EleDistribution.class.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. <?php
  2. /**
  3. * lionfish 商城系统
  4. *
  5. * ==========================================================================
  6. * @link http://www.liofis.com/
  7. * @copyright Copyright (c) 2015 liofis.com.
  8. * @license http://www.liofis.com/license.html License
  9. * ==========================================================================
  10. *
  11. * @author cy 2021-02-02
  12. *
  13. */
  14. /*
  15. * 饿了么配送接口
  16. */
  17. namespace Lib\Localtown;
  18. class EleDistribution
  19. {
  20. private $reqUrl = "";
  21. //正式地址
  22. private $ele_url = "https://open-anubis.ele.me/anubis-webapi";
  23. //联调地址
  24. private $test_ele_url = "https://exam-anubis.ele.me/anubis-webapi";
  25. //饿了么app_id
  26. private $app_id = "";
  27. //饿了么secret_key
  28. private $secret_key = "";
  29. //门店编号
  30. private $chain_store_code = "";
  31. //门店名称
  32. private $transport_name = "";
  33. //取货点地址
  34. private $transport_address = "";
  35. //取货点经度
  36. private $transport_longitude = "";
  37. //取货点纬度
  38. private $transport_latitude = "";
  39. //取货点经纬度来源
  40. private $position_source = "";
  41. //取货点联系方式
  42. private $transport_tel = "";
  43. //取货点备注
  44. private $transport_remark = "";
  45. //创建蜂鸟订单地址
  46. private $add_order_url = "/v2/order";
  47. //重发蜂鸟订单地址
  48. private $re_add_order_url = "/v2/order";
  49. //取消蜂鸟订单地址
  50. private $cancel_order_url = "/v2/order/cancel";
  51. //查询蜂鸟订单地址
  52. private $query_delivery_url = "/v2/order/query";
  53. private $token;
  54. private $notify_url = "";
  55. /**
  56. * 构造函数
  57. */
  58. public function __construct(){
  59. $this->app_id = D('Home/Front')->get_config_by_name('localtown_ele_app_id');
  60. $this->secret_key = D('Home/Front')->get_config_by_name('localtown_ele_secret_key');
  61. $this->chain_store_code = D('Home/Front')->get_config_by_name('localtown_ele_store_code');
  62. $this->transport_name = D('Home/Front')->get_config_by_name('localtown_ele_transport_name');
  63. $this->transport_address = D('Home/Front')->get_config_by_name('localtown_ele_transport_address');
  64. $this->transport_longitude = D('Home/Front')->get_config_by_name('localtown_ele_transport_longitude');
  65. $this->transport_latitude = D('Home/Front')->get_config_by_name('localtown_ele_transport_latitude');
  66. $this->position_source = D('Home/Front')->get_config_by_name('localtown_ele_position_source');
  67. $this->transport_tel = D('Home/Front')->get_config_by_name('localtown_ele_transport_tel');
  68. $this->transport_remark = D('Home/Front')->get_config_by_name('localtown_ele_transport_remark');
  69. if (strpos($this->transport_name,'测试') !== false || strpos($this->transport_name,'test') !== false) {//测试账号
  70. $this->reqUrl = $this->test_ele_url;
  71. } else {
  72. $this->reqUrl = $this->ele_url;
  73. }
  74. $shop_domain = D('Home/Front')->get_config_by_name('shop_domain');
  75. $this->notify_url = $shop_domain.'delivery_notify.php';
  76. }
  77. public function requestToken() {
  78. $salt = mt_rand(1000, 9999);
  79. // 获取签名
  80. $sig = $this->generateSign($this->app_id, $salt, $this->secret_key);
  81. $url = $this->reqUrl . '/get_access_token';
  82. $tokenStr = $this->doGet($url, array('app_id' => $this->app_id, 'salt' => $salt, 'signature' => $sig));
  83. // echo $tokenStr;
  84. // 获取token
  85. $this->token = json_decode($tokenStr, true)['data']['access_token'];
  86. }
  87. /**
  88. * 创建蜂鸟配送订单接口
  89. */
  90. public function addOrder($order_info){
  91. //门店信息
  92. $transport_info = array(
  93. 'transport_name' => $this->transport_name,
  94. 'transport_address' => $this->transport_address,
  95. 'transport_longitude' => $this->transport_longitude,
  96. 'transport_latitude' => $this->transport_latitude,
  97. 'position_source' => $this->position_source,
  98. 'transport_tel' => $this->transport_tel,
  99. 'transport_remark' => $this->transport_remark
  100. );
  101. //收货人信息
  102. $receiver_info = array(
  103. 'receiver_name' => $order_info['shipping_name'],
  104. 'receiver_primary_phone' => $order_info['shipping_tel'],
  105. 'receiver_address' => $order_info['shipping_address'],
  106. 'receiver_longitude' => $order_info['shipping_lng'],
  107. 'position_source' => $this->position_source,
  108. 'receiver_latitude' => $order_info['shipping_lat']
  109. );
  110. //订单商品明细
  111. $product_list = [];
  112. foreach($order_info['goods_list'] as $k=>$v){
  113. $goods_array = [];
  114. $goods_array['item_id'] = $v['goods_id'];//商品编号
  115. $goods_array['item_name'] = $v['goods_name'];//商品名称
  116. $goods_array['item_quantity'] = $v['quantity'];//商品数量
  117. $goods_array['item_price'] = $v['price'];//商品原价
  118. $goods_array['item_actual_price'] = $v['total'];//商品实际支付金额,必须是乘以数量后的金额,否则影响售后环节的赔付标准
  119. $goods_array['is_need_package'] = 0;//是否需要ele打包 0:否 1:是
  120. $goods_array['is_agent_purchase'] = 0;//是否代购 0:否
  121. $product_list[] = $goods_array;
  122. }
  123. //拼装data数据
  124. $dataArray = array(
  125. 'transport_info' => $transport_info,
  126. 'receiver_info' => $receiver_info,
  127. 'items_json' => $product_list,
  128. 'partner_remark' => '',//商户备注信息
  129. 'partner_order_code' => $order_info['order_num_alias'], // 第三方订单号, 需唯一
  130. 'notify_url' => $this->notify_url, //第三方回调 url地址
  131. 'order_type' => 1,//订单类型(1:即时单,3:预约单)
  132. 'order_total_amount' => $order_info['order_total'],//订单总金额(不包含商家的任何活动以及折扣的金额)
  133. 'order_actual_amount' => $order_info['order_total'],//客户需要支付的金额
  134. 'order_weight'=> round($order_info['goods_weight']/1000,2),
  135. 'is_invoiced' => 0,//是否需要发票, 0:不需要, 1:需要
  136. 'invoice' => '',//发票抬头, 如果需要发票, 此项必填
  137. 'order_payment_status' => 1,//订单支付状态 0:未支付 1:已支付
  138. 'order_payment_method' => 1,//订单支付方式 1:在线支付
  139. 'require_payment_pay' => 0,//需要代收时客户应付金额, 如果需要ele代收 此项必填
  140. 'goods_count' => $order_info['goods_count'],//订单货物件数
  141. 'is_agent_payment' => 0,
  142. 'require_receive_time' => 0 //需要送达时间(毫秒);
  143. );
  144. $this->requestToken();
  145. $salt = mt_rand(1000, 9999);
  146. $dataJson = json_encode($dataArray, JSON_UNESCAPED_UNICODE) . PHP_EOL;
  147. // $urlencodeData = urlencode($dataJson);
  148. $urlencodeData = urlencode($dataJson);
  149. $sig = $this->generateBusinessSign($this->app_id, $this->token, $urlencodeData, $salt); //生成签名
  150. $requestJson = json_encode(array(
  151. 'app_id' => $this->app_id,
  152. 'salt' => $salt,
  153. 'data' => $urlencodeData,
  154. 'signature' => $sig
  155. ));
  156. $resp = $this->doPost($this->reqUrl.$this->add_order_url, $requestJson);
  157. $result = $this->parseResponseData($resp);
  158. return $result;
  159. }
  160. /**
  161. * 取消蜂鸟配送订单接口
  162. */
  163. public function cancelOrder($orderdistribution_info,$cancel_reason_id,$cancel_reason){
  164. $data = array(
  165. "partner_order_code" => $orderdistribution_info['third_order_id'],
  166. "order_cancel_code" => $cancel_reason_id, //订单取消编码
  167. "order_cancel_reason_code" => 2, //订单取消原因代码(1:用户取消,2:商家取消)
  168. "order_cancel_description" => $cancel_reason,
  169. "order_cancel_time" => time() * 1000
  170. );
  171. $this->requestToken();
  172. $dataJson = json_encode($data);
  173. $salt = mt_rand(1000, 9999);
  174. $urlencodeData = urlencode($dataJson);
  175. $sig = $this->generateBusinessSign($this->app_id, $this->token, $urlencodeData, $salt); //生成签名
  176. $requestJson = json_encode(array(
  177. 'app_id' => $this->app_id,
  178. 'salt' => $salt,
  179. 'data' => $urlencodeData,
  180. 'signature' => $sig
  181. ));
  182. $resp = $this->doPost($this->reqUrl.$this->cancel_order_url, $requestJson);
  183. $result = $this->parseResponseData($resp);
  184. return $result;
  185. }
  186. public function generateSign($appId, $salt, $secretKey) {
  187. $seed = 'app_id=' . $appId . '&salt=' . $salt . '&secret_key=' . $secretKey;
  188. return md5(urlencode($seed));
  189. }
  190. public function generateBusinessSign($appId, $token, $urlencodeData, $salt) {
  191. $seed = 'app_id=' . $appId . '&access_token=' . $token
  192. . '&data=' . $urlencodeData . '&salt=' . $salt;
  193. return md5($seed);
  194. }
  195. /**
  196. * 发送GET请求
  197. * @param string $url
  198. * @param array $param
  199. * @return bool|mixed
  200. */
  201. public static function doGet($url, $param = null)
  202. {
  203. if (empty($url) or (!empty($param) and !is_array($param))) {
  204. throw new InvalidArgumentException('Params is not of the expected type');
  205. }
  206. // 验证url合法性
  207. // if (!filter_var($url, FILTER_VALIDATE_URL)) {
  208. // throw new InvalidArgumentException('Url is not valid');
  209. // }
  210. if (!empty($param)) {
  211. $url = trim($url, '?') . '?' . http_build_query($param);
  212. }
  213. $ch = curl_init();
  214. curl_setopt($ch, CURLOPT_URL, $url);
  215. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  216. curl_setopt($ch, CURLOPT_HEADER, false);
  217. curl_setopt($ch, CURLOPT_AUTOREFERER, true);
  218. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 不进行ssl 认证
  219. // curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
  220. curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  221. $result = curl_exec($ch);
  222. $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  223. curl_close($ch);
  224. if (!empty($result) and $code == 200) {
  225. return $result;
  226. }
  227. return false;
  228. }
  229. /**
  230. * POST请求
  231. * @param $url
  232. * @param $param
  233. * @return boolean|mixed
  234. */
  235. public static function doPost($url, $param, $method = "POST")
  236. {
  237. // echo 'Request url is ' . $url . PHP_EOL;
  238. if (empty($url) or empty($param)) {
  239. throw new InvalidArgumentException('Params is not of the expected type');
  240. }
  241. // 验证url合法性
  242. // if (!filter_var($url, FILTER_VALIDATE_URL)) {
  243. // throw new InvalidArgumentException('Url is not valid');
  244. // }
  245. if (!empty($param) and is_array($param)) {
  246. $param = urldecode(json_encode($param));
  247. } else {
  248. // $param = urldecode(strval($param));
  249. $param = strval($param);
  250. }
  251. $ch = curl_init();
  252. curl_setopt($ch, CURLOPT_URL, $url);
  253. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  254. curl_setopt($ch, CURLOPT_HEADER, false);
  255. // curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
  256. curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  257. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 不进行ssl 认证
  258. if (strcmp($method, "POST") == 0) { // POST 操作
  259. curl_setopt($ch, CURLOPT_POST, true);
  260. } else if (strcmp($method, "DELETE") == 0) { // DELETE操作
  261. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
  262. } else {
  263. throw new InvalidArgumentException('Please input correct http method, such as POST or DELETE');
  264. }
  265. curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
  266. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: Application/json'));
  267. $result = curl_exec($ch);
  268. $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  269. curl_close($ch);
  270. if (!empty($result) and $code == '200') {
  271. return $result;
  272. }
  273. return false;
  274. }
  275. /**
  276. * 解析响应数据
  277. * @param $arr返回的数据
  278. * 响应数据格式:{"status":"success","result":{},"code":0,"msg":"成功"}
  279. */
  280. public function parseResponseData($arr){
  281. $result = array();
  282. if (empty($arr)) {
  283. $result['status'] = 0;
  284. $result['message'] = "接口请求超时或失败";
  285. $result['code'] = "-2";
  286. }else{
  287. $data = json_decode($arr, true);
  288. if($data['code'] == 200){//成功
  289. $result['status'] = 1;
  290. $result['message'] = $data['msg'];
  291. $result['code'] = $data['code'];
  292. $result['result'] = $data['data'];
  293. }else{//失败
  294. $result['status'] = 0;
  295. $result['message'] = $data['msg'];
  296. $result['code'] = $data['code'];
  297. $result['result'] = $data['data'];
  298. }
  299. }
  300. return $result;
  301. }
  302. }
  303. ?>