FengNiao.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace app\expand\controller;
  3. use app\common\service\HelperService;
  4. use think\Cache;
  5. use think\Log;
  6. use think\Validate;
  7. /**
  8. * 蜂鸟相关接口
  9. * Class Baidu
  10. * @package app\expand\controller
  11. */
  12. class FengNiao extends BaseAuth
  13. {
  14. private $_baseUrl = "https://exam-anubis.ele.me/anubis-webapi";//联调接口基础地址
  15. //"https://open-anubis.ele.me/anubis-webapi";//正式接口基础地址
  16. private $_fengNiaoAccount = null;
  17. private $_appId = null;
  18. private $_secretKey=null;
  19. public function __construct(){
  20. // echo sha1(md5(base64_encode("KEQIN1554885752"))."439F269CE14DBF34257C08612CE51EC8");exit;
  21. parent::__construct();
  22. $this->_fengNiaoAccount = $this->getKey($this->_apiCode);
  23. //验证是否具有访问这个接口的权限
  24. if(!isset($this->_fengNiaoAccount['fengNiaoAppId']) || !isset($this->_fengNiaoAccount['fengNiaoSecretKey'])){
  25. HelperService::returnJson(['code'=>400,'msg'=>'feng niao interface unauthorized access','data'=>[]]);
  26. }
  27. $this->_appId = $this->_fengNiaoAccount['fengNiaoAppId'];
  28. $this->_secretKey = $this->_fengNiaoAccount['fengNiaoSecretKey'];
  29. }
  30. public function order(){
  31. $params = $this->_params;
  32. $rule = [
  33. 'orderInfo|订单信息'=>'require',
  34. 'addressInfo|收货人信息'=>'require',
  35. 'productDetail|订单详情信息'=>'require',
  36. 'storeInfo|门店信息'=>'require',
  37. ];
  38. $validate = new Validate($rule);
  39. if(!$validate->check($params)){
  40. HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>[]]);
  41. }
  42. $times = time();
  43. $company_code = 'KEQIN';
  44. $sign = sha1(md5(base64_encode($company_code.$times))."439F269CE14DBF34257C08612CE51EC8");
  45. $url = "https://csapi.ahamu.cn/v1/FnNotifyUrl?api_code=".$company_code."&request_ts=".$times."&signKey=".$sign;
  46. file_put_contents('check_url',$url);
  47. $salt = mt_rand(1000,9999);
  48. $data = [
  49. 'partner_order_code'=>isset($params['orderInfo']['order_no'])?$params['orderInfo']['order_no']:'',//商户订单号
  50. 'partner_remark'=>isset($params['table_name'])?$params['table_name']:'',
  51. 'notify_url'=>$url,//回调地址
  52. 'order_type'=>1,//订单类型 1: 蜂鸟配送,支持90分钟内送达
  53. 'chain_store_code'=>isset($params['storeInfo']['store_no'])?$params['storeInfo']['store_no']:'',//门店编号
  54. 'transport_info'=>[
  55. 'transport_name'=>isset($params['storeInfo']['store_name'])?$params['storeInfo']['store_name']:'',//门店名称(支持汉字、符号、字母的组合),后期此参数将预留另用
  56. 'transport_address'=>isset($params['storeInfo']['address'])?$params['storeInfo']['address']:'',//取货点地址,后期此参数将预留另用
  57. 'transport_longitude'=>isset($params['storeInfo']['lng'])?$params['storeInfo']['lng']:'',//取货点经度,取值范围0~180,后期此参数将预留另用
  58. 'transport_latitude'=>isset($params['storeInfo']['lat'])?$params['storeInfo']['lat']:'',//取货点纬度,取值范围0~90,后期此参数将预留另用
  59. 'position_source'=>3,//取货点经纬度来源(1:腾讯地图, 2:百度地图, 3:高德地图),蜂鸟建议使用高德地图
  60. 'transport_tel'=>isset($params['storeInfo']['mobile'])?$params['storeInfo']['mobile']:'',//取货点联系方式, 只支持手机号,400开头电话以及座机号码
  61. ],
  62. 'order_total_amount'=>isset($params['orderInfo']['price'])?$params['orderInfo']['price'] + $params['orderInfo']['dis_count']:'',//订单总金额(不包含商家的任何活动以及折扣的金额)
  63. 'order_actual_amount'=>isset($params['orderInfo']['price'])?$params['orderInfo']['price']:'',//客户需要支付的金额
  64. 'is_invoiced'=>0,//是否需要发票, 0:不需要, 1:需要
  65. 'order_payment_status'=>1,//订单支付状态 0:未支付 1:已支付
  66. 'order_payment_method'=>1,//订单支付方式 1:在线支付
  67. 'is_agent_payment'=>0,//是否需要ele代收 0:否
  68. 'goods_count'=>1,//订单货物件数
  69. 'receiver_info'=>[
  70. 'receiver_name'=>isset($params['addressInfo']['receipt_name'])?$params['addressInfo']['receipt_name']:'',//收货人姓名
  71. 'receiver_primary_phone'=>isset($params['addressInfo']['receipt_mobile'])?$params['addressInfo']['receipt_mobile']:'',//收货人联系方式,只支持手机号,400开头电话,座机号码以及95013开头、长度13位的虚拟电话
  72. 'receiver_address'=>isset($params['addressInfo']['address'])?$params['addressInfo']['address'].$params['addressInfo']['house']:'',//收货人地址
  73. 'position_source'=>3,//收货人经纬度来源(1:腾讯地图, 2:百度地图, 3:高德地图),蜂鸟建议使用高德地图
  74. 'receiver_longitude'=>isset($params['addressInfo']['lng'])?$params['addressInfo']['lng']:'',//收货人经度,取值范围0~180
  75. 'receiver_latitude'=>isset($params['addressInfo']['lat'])?$params['addressInfo']['lat']:'',//收货人纬度,取值范围0~90
  76. ],
  77. 'items_json'=>
  78. isset($params['productDetail'])?$params['productDetail']:[]
  79. ,
  80. ];
  81. // Log::record('蜂鸟传输数组',$data);
  82. // file_put_contents('fengniao',$data);
  83. $udata = urlencode(json_encode($data,JSON_UNESCAPED_UNICODE).PHP_EOL);
  84. $orderInfo = [
  85. 'app_id'=>$this->_appId,
  86. 'salt'=>$salt,
  87. 'data'=> $udata,
  88. ];
  89. $signature = $this->_createRequestSign($this->_appId,$this->_getToken(),$udata,$salt);
  90. $orderInfo['signature'] = $signature;
  91. $url = $this->_baseUrl."/v2/order";
  92. $res = HelperService::doPost($url, json_encode($orderInfo));
  93. HelperService::addLog(['request'=>$orderInfo,'return'=>$res], $url, 'FN');
  94. HelperService::returnJson(['code'=>200,'msg'=>[],'data'=>@json_decode($res,true)]);
  95. }
  96. //查询订单
  97. public function searchOrder(){
  98. $params = $this->_params;
  99. $rule = [
  100. 'order_no|订单信息'=>'require',
  101. ];
  102. $validate = new Validate($rule);
  103. if(!$validate->check($params)){
  104. HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>[]]);
  105. }
  106. $salt = rand(1000,9999);
  107. $data = [
  108. 'partner_order_code'=>$params['order_no'],//商户订单号
  109. ];
  110. $udata = urlencode(json_encode($data,JSON_UNESCAPED_UNICODE).PHP_EOL);
  111. $orderInfo = [
  112. 'app_id'=>$this->_appId,
  113. 'data'=> $udata,
  114. 'salt'=>$salt,
  115. ];
  116. $signature = $this->_createRequestSign($this->_appId,$this->_getToken(),$udata,$salt);
  117. $orderInfo['signature'] = $signature;
  118. $url = $this->_baseUrl."/v2/order/query";
  119. $res = HelperService::doPost($url, json_encode($orderInfo));
  120. HelperService::addLog(['request'=>$orderInfo,'return'=>$res], $url, 'FN');
  121. HelperService::returnJson(['code'=>200,'msg'=>[],'data'=>@json_decode($res,true)]);
  122. }
  123. public function notifyUrl(){
  124. $params = $this->_params;
  125. Log::record('回调'.$params);
  126. file_put_contents('test',$params);
  127. }
  128. /**
  129. * 创建token签名算法
  130. * @param type $requestArr 请求数组
  131. * @return string
  132. */
  133. private function _createTokenSign($requestArr = []){
  134. if(empty($requestArr) || !is_array($requestArr)){
  135. return '';
  136. }
  137. ksort($requestArr);
  138. return md5(urlencode(http_build_query($requestArr)));
  139. }
  140. /**
  141. * 创建商户请求时签名
  142. * @param type $appId
  143. * @param type $accessToken
  144. * @param type $ueRequestDataArr urlencode,json_encode请求数据部分
  145. * @param type $salt
  146. */
  147. private function _createRequestSign($appId,$accessToken,$ueRequestDataArr,$salt){
  148. $signStr = 'app_id=' . $appId . '&access_token=' . $accessToken
  149. . '&data=' . $ueRequestDataArr . '&salt=' . $salt;
  150. return md5($signStr);
  151. }
  152. /**
  153. * 获取蜂鸟的token数据
  154. * @param type $isForce 是否强制获取token
  155. * @return type
  156. */
  157. private function _getToken($isForce=false){
  158. if(Cache::has('fengNiaoToken') && $isForce === false){
  159. return Cache::get('fengNiaoToken');
  160. }
  161. $salt = rand(1000,9999);
  162. $appId = $this->_appId;
  163. $getTokenArr = [
  164. 'app_id'=>$appId,
  165. 'salt'=>$salt,
  166. 'secret_key'=>$this->_secretKey
  167. ];
  168. $signature = $this->_createTokenSign($getTokenArr);
  169. $url = $this->_baseUrl."/get_access_token?app_id=$appId&salt=$salt&signature=$signature";
  170. $tokenInfoJson = file_get_contents($url);
  171. $tokenInfo = json_decode($tokenInfoJson,true);
  172. if(!isset($tokenInfo['code']) || $tokenInfo['code']!=200 || !isset($tokenInfo['data']['access_token'])){
  173. HelperService::returnJson([
  174. 'code'=>200,
  175. 'msg'=>'签名错误',
  176. 'data'=>$tokenInfoJson
  177. ]);
  178. }
  179. $token = $tokenInfo['data']['access_token'];
  180. Cache::set('fengNiaoToken', $token,intval($tokenInfo['data']['expire_time']/1000)-time());
  181. return $token;
  182. }
  183. /**
  184. * 查询门店是否有配送能力
  185. */
  186. public function distanceStore(){
  187. $params = $this->_params;
  188. $rule = [
  189. 'store_no|门店编号'=>'require',
  190. 'lng|经度'=>'require',
  191. 'lat|纬度'=>'require',
  192. ];
  193. $validate = new Validate($rule);
  194. if(!$validate->check($params)){
  195. HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>[]]);
  196. }
  197. $salt = rand(1000,9999);
  198. $data = [
  199. 'chain_store_code'=>$params['store_no'],//门店编号【大华店】
  200. 'position_source'=>3,//门店编号
  201. 'receiver_longitude'=>$params['lng'],//收货点经度(数字格式, 包括小数点, 取值范围0~180)
  202. 'receiver_latitude'=>$params['lat'],//收货点纬度(数字格式, 包括小数点, 取值范围0~90)
  203. ];
  204. $udata = urlencode(json_encode($data,JSON_UNESCAPED_UNICODE).PHP_EOL);
  205. $orderInfo = [
  206. 'app_id'=>$this->_appId,
  207. 'data'=> $udata,
  208. 'salt'=>$salt,
  209. ];
  210. $signature = $this->_createRequestSign($this->_appId,$this->_getToken(),$udata,$salt);
  211. $orderInfo['signature'] = $signature;
  212. $url = $this->_baseUrl."/v2/chain_store/delivery/query";
  213. $res = HelperService::doPost($url, json_encode($orderInfo));
  214. HelperService::addLog(['request'=>$orderInfo,'return'=>$res], $url, 'FN');
  215. HelperService::returnJson(['code'=>200,'msg'=>[],'data'=>@json_decode($res,true)]);
  216. }
  217. /**
  218. * 取消订单
  219. */
  220. public function cancelOrder(){
  221. // $params = $this->_params;
  222. // $rule = [
  223. // 'store_no|门店编号'=>'require',
  224. // 'lng|经度'=>'require',
  225. // 'lat|纬度'=>'require',
  226. // ];
  227. //
  228. // $validate = new Validate($rule);
  229. // if(!$validate->check($params)){
  230. // HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>[]]);
  231. // }
  232. $salt = rand(1000,9999);
  233. $data = [
  234. 'partner_order_code'=>"1904101806201487",//商户订单号
  235. 'order_cancel_reason_code'=>1,//订单取消原因代码(2:商家取消)
  236. 'order_cancel_code'=>1,//订单取消编码(1:物流原因:订单长时间未分配骑手, 2:物流原因:分配骑手后,骑手长时间未取件 , 3:物流原因:骑手告知不配送,让取消订单, 4:商品缺货/无法出货/已售完, 5:商户联系不上门店/门店关门了, 6:商户发错单, 7:商户/顾客自身定位错误, 8:商户改其他第三方配送, 9:顾客下错单/临时不想要了, 10:顾客自取/不在家/要求另改时间配送)(0类型已下线)
  237. 'order_cancel_time'=>microtime(),//订单取消时间(毫秒)
  238. ];
  239. $udata = urlencode(json_encode($data,JSON_UNESCAPED_UNICODE).PHP_EOL);
  240. $orderInfo = [
  241. 'app_id'=>$this->_appId,
  242. 'data'=> $udata,
  243. 'salt'=>$salt,
  244. ];
  245. $signature = $this->_createRequestSign($this->_appId,$this->_getToken(),$udata,$salt);
  246. $orderInfo['signature'] = $signature;
  247. $url = $this->_baseUrl."/v2/order/cancel";
  248. $res = HelperService::doPost($url, json_encode($orderInfo));
  249. HelperService::addLog(['request'=>$orderInfo,'return'=>$res], $url, 'FN');
  250. HelperService::returnJson(['code'=>200,'msg'=>[],'data'=>@json_decode($res,true)]);
  251. }
  252. }