WechatNewDelivery.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. <?php
  2. namespace app\utils\Delivery;
  3. use app\models\DeliveryInfo;
  4. use app\models\intracityService\IndexController;
  5. use app\models\Order;
  6. use app\models\WechatIntracityService;
  7. use app\modules\admin\models\OrderRevokeForm;
  8. use app\modules\admin\models\WechatDeliveryForm;
  9. class WechatNewDelivery
  10. {
  11. public $md_id = 171;
  12. public $store_id;
  13. //预下单 https://api.weixin.qq.com/cgi-bin/express/intracity/preaddorder
  14. //预览订单时查询运费-下单时查询运费-支付成功后查询运费是否一直,不一致提示配送费错误,请重新下单。- 下单后提交配送订单
  15. public function preAddOrder($params) {
  16. try {
  17. $md_id = $params['md_id'];
  18. if ($md_id <= 0) {
  19. $md_id = 0;
  20. }
  21. $store_id = $params['store_id'];
  22. $service = WechatIntracityService::findOne(['md_id' => $md_id, 'is_delete' => 0, 'store_id' => $store_id]);
  23. if (!$service) {
  24. throw new \Exception('暂未申请同城配送权限');
  25. }
  26. if (empty($service->wx_store_id)) {
  27. $form = new WechatDeliveryForm();
  28. $form->store_id = $store_id;
  29. $form->md_id = $md_id;
  30. $service_result = $form->getStoreInfo();
  31. if ($service_result['code'] === 0) {
  32. $service = $service_result['service'];
  33. } else {
  34. throw new \Exception('运费查询失败' . $service_result['msg']);
  35. }
  36. }
  37. $goods_list = $params['goods_list'];
  38. $weight = 0;
  39. $cargo_num = 0;
  40. $price = 0;
  41. $cargo_name = "";
  42. foreach ($goods_list as $goods_item) {
  43. $weight += $goods_item['weight'];
  44. $cargo_num += $goods_item['num'];
  45. $price += $goods_item['price'];
  46. $cargo_name .= $goods_item['name'] . ';';
  47. }
  48. if ($weight <= 0) {
  49. throw new \Exception('商品重量需要设置');
  50. }
  51. $price = sprintf('%.2f', $price);
  52. $cargo_name = mb_substr($cargo_name, 0, 32, 'utf-8');
  53. $data = [
  54. 'wx_store_id' => $service->wx_store_id,
  55. 'user_lng' => $params['address']['longitude'],
  56. 'user_lat' => $params['address']['latitude'],
  57. 'user_name' => $params['address']['name'],
  58. 'user_phone' => $params['address']['mobile'],
  59. 'user_address' => $params['address']['province'] . $params['address']['city'] . $params['address']['district'] . $params['address']['detail'],
  60. // 'cargo_name' => $goods_list['name'],
  61. 'cargo' => [
  62. 'cargo_name' => $cargo_name,
  63. 'cargo_weight' => $weight ?: 0,
  64. 'cargo_price' => $price * 100,
  65. 'cargo_type' => 3,
  66. 'cargo_num' => $cargo_num,
  67. ],
  68. //cargo_type这里选择商品类型,填入的是百货,实际应用可能会涉及药品之类,可能会有问题
  69. //'use_sandbox' => 1,
  70. ];
  71. $form = new IndexController();
  72. $form->store_id = $store_id;
  73. $result = $form->getUrlData($store_id, 'cgi-bin/express/intracity/preaddorder', $data);
  74. if (isset($result['errcode']) && $result['errcode'] === 0) {
  75. return [
  76. 'code' => 0,
  77. 'msg' => '计算成功',
  78. 'data' => [
  79. 'resultcode' => 0,
  80. 'service_trans_id' => $result['service_trans_id'],
  81. 'distance' => $result['distance'],
  82. 'fee' => floatval(sprintf('%.2f',$result['est_fee'] / 100)),
  83. 'expected_finished_time' => $result['expected_finished_time'],
  84. 'promise_delivery_time' => $result['promise_delivery_time'],
  85. 'is_wechat_new_delivery' => 1
  86. ]
  87. ];
  88. // 'resultcode' => 0,
  89. // 'address' => $address,
  90. // 'store' => $store,
  91. // 'distance' => $distance,
  92. // 'delivery_time' => $delivery_time,
  93. // 'delivery_time_stamp' => $delivery_time_stamp,
  94. // 'LocalDeliveryFreight' => $result,
  95. // 'freight_detail' => $freight_detail,
  96. // 'fee' => (float)$freight,
  97. // 'endTime' => $endTime
  98. }
  99. throw new \Exception($result['errmsg'], $result['errcode']);
  100. } catch (\Exception $e) {
  101. return [
  102. 'code' => 1,
  103. 'msg' => $e->getMessage()
  104. ];
  105. }
  106. }
  107. //下单 https://api.weixin.qq.com/cgi-bin/express/intracity/addorder
  108. public function addOrder($params) {
  109. try {
  110. $md_id = $params['md_id'];
  111. if ($md_id <= 0) {
  112. $md_id = 0;
  113. }
  114. $store_id = $params['store_id'];
  115. $service = WechatIntracityService::findOne(['md_id' => $md_id, 'is_delete' => 0, 'store_id' => $store_id]);
  116. if (!$service) {
  117. throw new \Exception('暂未申请同城配送权限');
  118. }
  119. if (empty($service->wx_store_id)) {
  120. $form = new WechatDeliveryForm();
  121. $form->store_id = $store_id;
  122. $form->md_id = $md_id;
  123. $service_result = $form->getStoreInfo();
  124. if ($service_result['code'] === 0) {
  125. $service = $service_result['service'];
  126. } else {
  127. throw new \Exception('运费查询失败' . $service_result['msg']);
  128. }
  129. }
  130. $goods_list = $params['goods_list'];
  131. $weight = 0;
  132. $cargo_num = 0;
  133. $cargo_price = 0;
  134. $cargo_name = "";
  135. $goods_item_list = [];
  136. foreach ($goods_list as $goods_index => $goods_item) {
  137. $weight += $goods_item['weight'];
  138. $cargo_num += $goods_item['num'];
  139. $cargo_price += $goods_item['price'];
  140. $cargo_name .= $goods_item['name'] . ';';
  141. $goods_item_list[$goods_index]['item_name'] = $goods_item['name'];
  142. $goods_item_list[$goods_index]['item_pic_url'] = $goods_item['pic'];
  143. $goods_item_list[$goods_index]['count'] = $goods_item['num'];
  144. }
  145. if ($weight <= 0) {
  146. throw new \Exception('商品重量需要设置');
  147. }
  148. $cargo_price = sprintf('%.2f', $cargo_price);
  149. $cargo_name = mb_substr($cargo_name, 0, 32, 'utf-8');
  150. $data = [
  151. 'wx_store_id' => $service->wx_store_id,
  152. 'store_order_id' => $params['order_no'],
  153. 'user_openid' => $params['store_user']['wechat_open_id'],
  154. 'user_lng' => $params['address']['longitude'],
  155. 'user_lat' => $params['address']['latitude'],
  156. 'user_name' => $params['address']['name'],
  157. 'user_phone' => $params['address']['mobile'],
  158. 'user_address' => $params['address']['province'] . $params['address']['city'] . $params['address']['district'] . $params['address']['detail'],
  159. 'order_seq' => $params['order_seq'],
  160. 'verify_code_type' => 3,
  161. 'order_detail_path' => $params['order_detail_path'],
  162. 'callback_url' => 'https://' . \Yii::$app->request->hostName . '/index.php/wechat/delivery-callback',
  163. //'use_sandbox' => 1,
  164. 'cargo' => [
  165. 'cargo_name' => $cargo_name,
  166. 'cargo_weight' => $weight ?: 0,
  167. 'cargo_price' => $cargo_price * 100,
  168. 'cargo_type' => 3,
  169. 'cargo_num' => $cargo_num,
  170. 'item_list' => $goods_item_list
  171. ],
  172. ];
  173. $form = new IndexController();
  174. $result = $form->getUrlData($store_id, 'cgi-bin/express/intracity/addorder', $data);
  175. if (isset($result['errcode']) && $result['errcode'] === 0) {
  176. $delivery_type = 0;
  177. if ($result['service_trans_id']) {
  178. switch ($result['service_trans_id']) {
  179. case 'DADA':
  180. $delivery_type = 2;
  181. break;
  182. case 'SFTC':
  183. $delivery_type = 1;
  184. break;
  185. }
  186. }
  187. $deliveryInfo = DeliveryInfo::findOne(['order_no' => $params['order_no']]);
  188. $deliveryInfo->fee = bcdiv($result['fee'], 100, 2);
  189. $deliveryInfo->delivery_type = $delivery_type;
  190. $deliveryInfo->wx_order_id = $result['wx_order_id'];
  191. $deliveryInfo->success_params = json_encode($result, JSON_UNESCAPED_UNICODE);
  192. if (!$deliveryInfo->save()) {
  193. throw new \Exception(json_encode($deliveryInfo->errors, JSON_UNESCAPED_UNICODE));
  194. }
  195. return [
  196. 'code' => 0,
  197. 'msg' => '计算成功',
  198. 'data' => [
  199. 'wx_store_id' => $result['wx_store_id'],
  200. 'wx_order_id' => $result['wx_order_id'],
  201. 'store_order_id' => $result['store_order_id'],
  202. 'service_trans_id' => $result['service_trans_id'],
  203. 'distance' => $result['distance'],
  204. 'trans_order_id' => $result['trans_order_id'],
  205. 'waybill_id' => $result['waybill_id'],
  206. 'fee' => $result['fee'],
  207. 'fetch_code' => $result['fetch_code'],
  208. 'order_seq' => $result['order_seq']
  209. ]
  210. ];
  211. }
  212. throw new \Exception($result['errmsg'], $result['errcode']);
  213. } catch (\Exception $e) {
  214. return [
  215. 'code' => 1,
  216. 'msg' => $e->getMessage()
  217. ];
  218. }
  219. }
  220. //取消订单 https://api.weixin.qq.com/cgi-bin/express/intracity/cancelorder
  221. public function cancelOrder($params) {
  222. try {
  223. // $md_id = $params['md_id'];
  224. // if ($md_id <= 0) {
  225. // $md_id = 0;
  226. // }
  227. $store_id = $params['store_id'];
  228. $order_no = $params['order_no'];
  229. $deliveryInfo = DeliveryInfo::findOne(['order_no' => $order_no]);
  230. if (!$deliveryInfo) {
  231. throw new \Exception('未找到订单');
  232. }
  233. $data = [
  234. 'wx_order_id' => $deliveryInfo->wx_order_id,
  235. 'cancel_reason_id' => 1,//此处为 1.不需要了 1:不需要了 2:信息填错 3:无人接单 99:其他
  236. ];
  237. $form = new IndexController();
  238. $result = $form->getUrlData($store_id, 'cgi-bin/express/intracity/cancelorder', $data);
  239. if (isset($result['errcode']) && $result['errcode'] === 0) {
  240. $deliveryInfo->deduct_fee = $result['deductfee'];
  241. if (!$deliveryInfo->save()) {
  242. throw new \Exception(json_encode($deliveryInfo->errors, JSON_UNESCAPED_UNICODE));
  243. }
  244. return [
  245. 'code' => 0,
  246. 'msg' => '取消成功'
  247. ];
  248. }
  249. throw new \Exception($result['errmsg'], $result['errcode']);
  250. } catch (\Exception $e) {
  251. return [
  252. 'code' => 1,
  253. 'msg' => $e->getMessage()
  254. ];
  255. }
  256. }
  257. //查询订单状态 https://api.weixin.qq.com/cgi-bin/express/intracity/queryorder
  258. public function getOrderStatus($params) {
  259. try {
  260. $store_id = $params['store_id'];
  261. $order_no = $params['order_no'];
  262. $deliveryInfo = DeliveryInfo::findOne(['order_no' => $order_no]);
  263. $data = [
  264. 'wx_order_id' => $deliveryInfo->wx_order_id
  265. ];
  266. $form = new IndexController();
  267. $result = $form->getUrlData($store_id, 'cgi-bin/express/intracity/queryorder', $data);
  268. if (isset($result['errcode']) && $result['errcode'] === 0) {
  269. $deliveryInfo->wx_order_status = $result['order_status'];
  270. if (!$deliveryInfo->save()) {
  271. throw new \Exception(json_encode($deliveryInfo->errors, JSON_UNESCAPED_UNICODE));
  272. }
  273. $order_ = Order::findOne(['order_no' => $order_no, 'is_delete' => 0]);
  274. if (in_array($result['order_status'], [30000, 40000, 50000])) {
  275. $order_->trade_status = Order::ORDER_FLOW_SEND;
  276. }
  277. if (intval($result['order_status']) === 70000) {
  278. $order_->trade_status = Order::ORDER_FLOW_CONFIRM;
  279. }
  280. if (!$order_->save()) {
  281. throw new \Exception(json_encode($order_->errors, JSON_UNESCAPED_UNICODE));
  282. }
  283. //如果取消订单 配送状态:取消 --- 调用取消接口
  284. // 用户主动取消 --调用取消接口
  285. if (in_array($result['order_status'], [20000, 20001, 60000])) {
  286. $result = $this->handleCancel(['order_no' => $order_no]);
  287. debug_log($result, 'delivery_.log');
  288. }
  289. return [
  290. 'code' => 0,
  291. 'msg' => '获取成功',
  292. 'data' => [
  293. 'order_status' => $result['order_status']
  294. ]
  295. ];
  296. }
  297. throw new \Exception($result['errmsg'], $result['errcode']);
  298. } catch (\Exception $e) {
  299. return [
  300. 'code' => 1,
  301. 'msg' => $e->getMessage()
  302. ];
  303. }
  304. }
  305. //模拟订单回调 https://api.weixin.qq.com/cgi-bin/express/intracity/mocknotify
  306. public function mockNotify($params) {
  307. $store_id = $params['store_id'];
  308. $order_no = $params['order_no'];
  309. $deliveryInfo = DeliveryInfo::findOne(['order_no' => $order_no]);
  310. $data = [
  311. 'wx_order_id' => $deliveryInfo->wx_order_id,
  312. 'order_status' => 20000
  313. ];
  314. $form = new IndexController();
  315. return $form->getUrlData($store_id, 'cgi-bin/express/intracity/queryorder', $data);
  316. }
  317. public function handleCancel($params) {
  318. try {
  319. $order_no = $params['order_no'];
  320. $order_ = Order::findOne(['order_no' => $order_no]);
  321. //取消订单
  322. $order_revoke = new OrderRevokeForm();
  323. $order_revoke->store_id = $order_->store_id;
  324. $order_revoke->order_id = $order_->id;
  325. $order_revoke->delete_pass = true;
  326. return $order_revoke->save();
  327. } catch (\Exception $e) {
  328. return [
  329. 'code' => 1,
  330. 'msg' => $e->getMessage()
  331. ];
  332. }
  333. }
  334. }