订单发货管理接入指引:https://mp.weixin.qq.com/cgi-bin/announce?token=1148555877&action=getannouncement&key=11671435333v04b2&version=1&lang=zh_CN&platform=2https://mp.weixin.qq.com/cgi-bin/announce?token=1148555877&action=getannouncement&key=11671435333v04b2&version=1&lang=zh_CN&platform=2
发货信息录入接口文档:小程序发货信息管理服务 | 微信开放文档
注意事项
-
根据指定的订单单号类型,采用不同参数给指定订单上传物流信息:
(1). 商户侧单号形式(枚举值1),通过下单商户号和商户侧单号确定一笔订单
(2). 微信支付单号形式(枚举值2),通过微信支付单号确定一笔订单
-
发货模式根据具体发货情况选择:
(1). 统一发货(枚举值1),一笔订单统一发货,只有一个物流单号。
(2). 分拆发货(枚举值2),一笔订单分拆发货,包括多个物流单号。
-
物流公司编码,参见获取运力 id 列表get_delivery_list。
-
上传时间,用于标识请求的先后顺序,如果要更新物流信息,上传时间必须比之前的请求更新,请按照 RFC 3339 格式填写。
-
分拆发货仅支持使用物流快递发货,一笔支付单最多分拆成 10 个包裹。
-
以下情况将视为重新发货,每笔支付单仅有一次重新发货机会。
(1). 对已完成发货的支付单再次调用该 API。
(2). 使用该 API 修改发货模式或物流模式。
<?phpnamespace app\v1\controller;use app\common\controller\Checking;
use think\Cache;
use think\Controller;
use think\Db;/*** 微信发货管理*/
class WechatShip extends Controller
{protected $appid;protected $appSecret;public function __construct(){$this->appid ='';$this->appSecret ='';}/*** 发货* @return void*/public function deliver_addr(){$order_lists=$this->get_order_list(['order_state'=>1]);$transaction_ids=array_column($order_lists['order_list'],'transaction_id');$order_shipping_info=Db::name('szy_lionfish_comshop_order')->alias('o')->join('szy_lionfish_comshop_order_goods g','o.order_id=g.order_id','LEFT')->whereIn('o.transaction_id',$transaction_ids)->column('o.shipping_no,o.shipping_method,g.name','o.transaction_id');foreach ($order_lists['order_list'] as $k=>$v){$wxorder = $this->getWxSendOrderStatus($v['transaction_id']);if($wxorder['errcode'] != 0){Checking::writeLog('获取微信订单失败-'.$v['transaction_id'],'error','wxfh.log');continue;}if (empty($order_shipping_info[$v['transaction_id']]['shipping_no'])){continue;}$order_state = $wxorder['order']['order_state']; //订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款。if($order_state == 1){$data = ['transaction_id'=>$wxorder['order']['transaction_id'],//微信交易单号'openid'=>$wxorder['order']['openid'],//支付用户openid'item_desc'=>$order_shipping_info[$v['transaction_id']]['name'],//商品名'express_name'=>$order_shipping_info[$v['transaction_id']]['shipping_method'],//快递名'express_no'=>$order_shipping_info[$v['transaction_id']]['shipping_no'],//快递单号];$results = $this->sendDelivery($data,1);if ($results['errcode'] == 0) {Checking::writeLog('发货成功-'.$v['transaction_id'],'success','wxfh.log');} else {Checking::writeLog('发货失败-'.$v['transaction_id'],$results['errmsg'],'wxfh.log');}}}}/*** 获取token* @return mixed*/public function getAccessToken(){$appId = $this->appid;$appSecret = $this->appSecret;$cacheKey = $appId . '@access_token';if (!Cache::get($cacheKey)) {// 请求API获取 access_token$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";$result = Checking::GetHttp($url);$data = json_decode($result, true);// return $data['access_token'];// 写入缓存Cache::set($cacheKey, $data['access_token'], 7200); // 7000}return Cache::get($cacheKey);}/*** 快递公司*/public function get_delivery_list(){$token = $this->getAccessToken();$url = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/get_delivery_list?access_token=" . $token;
// $data = json_encode([], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);$result = Checking::request_post_json($url, '{}');$result = json_decode($result[1], true);return $result;}/*** 获取订单列表*/public function get_order_list($data){
// $data = [
// 'pay_time_range' => [
// 'begin_time'=>1719714996,//起始时间,时间戳形式,不填则视为从0开始
// 'end_time'=>time()//结束时间(含),时间戳形式,不填则视为32位无符号整型的最大值
// ],
// 'order_state'=>1,//订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款'openid'=>'',//支付者openid'last_index'=>'',//翻页时使用,获取第一页时不用传入,如果查询结果中 has_more 字段为 true,则传入该次查询结果中返回的 last_index 字段可获取下一页'page_size'=>''//翻页时使用,返回列表的长度,默认为100
//
// ];$token = $this->getAccessToken();$url = "https://api.weixin.qq.com/wxa/sec/order/get_order_list?access_token=" . $token;$data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);$result = Checking::request_post_json($url, $data);$result = json_decode($result[1], true);return $result;}/*** 获取发货订单信息* @param $transaction_id* @return mixed*/public function getWxSendOrderStatus($transaction_id){$token = $this->getAccessToken();$url = "https://api.weixin.qq.com/wxa/sec/order/get_order?access_token=" . $token;$data = ['transaction_id' => $transaction_id];$data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);$result = Checking::request_post_json($url, $data);$result = json_decode($result[1], true);return $result;}/*** 设置微信发货后,消息跳转地址,不设置为默认* @return void*/public function set_jump_path(){$token = $this->getAccessToken();$url = "https://api.weixin.qq.com/wxa/sec/order/set_msg_jump_path?access_token=" . $token;$data = ['path' => 'comshop/pages/order/index?conmen=3', //待收货订单列表页面];$data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);Checking::request_post_json($url, $data);}//发货 物流15天自动确认,虚拟商品隔天自动确认public function sendDelivery($order, $logistics_type=3){$this->set_jump_path();$token = $this->getAccessToken();$express_name = "";$express_no = "";if ($logistics_type == 1) {$express_name = $order['express_name'];$express_no = $order['express_no'];}$data = ['order_key' => ['order_number_type' => 2, //订单单号类型,用于确认需要上传详情的订单。枚举值1,使用下单商户号和商户侧单号;枚举值2,使用微信支付单号。'transaction_id' => $order['transaction_id']],'logistics_type' => $logistics_type,//物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提'delivery_mode' => 1, //发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货) 示例值: UNIFIED_DELIVERY'shipping_list' => [['tracking_no' => $express_no,'express_company' => $express_name,'item_desc' => $order['item_desc'] ?? "订单发货信息"]],'upload_time' => date('Y-m-d\TH:i:sP', time()),'payer' => ['openid' => $order['openid']]];$urlss = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" . $token;$data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);$results = Checking::request_post_json($urlss, $data);$results = json_decode($results[1], true);return $results;}}
/*** get* @param string $url 请求地址*/public static function GetHttp($url){// 关闭句柄$curl = curl_init(); // 启动一个CURL会话curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_HEADER, 0);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在// 设置Accept头部字段curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json'));// 设置User-Agent头部字段curl_setopt($curl, CURLOPT_USERAGENT, 'My User Agent String');$tmpInfo = curl_exec($curl); //返回api的json对象if(curl_exec($curl) === false){return 'Curl error: ' . curl_error($curl);}//关闭URL请求curl_close($curl);return $tmpInfo; //返回json对象}/*** 模拟post进行url请求* @param string $url* @param string $data_string*/public static function request_post_json($url, $data_string) {$ch = curl_init();curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json; charset=utf-8","Content-Length: " . strlen($data_string)));ob_start();curl_exec($ch);$return_content = ob_get_contents();ob_end_clean();$return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);return array($return_code, $return_content);}//请确保项目文件有可写权限,不然打印不了日志。public static function writeLog( $text, $message = '', $name = "log.txt" ){file_put_contents( $name, date( "Y-m-d H:i:s" ) . " " . $text . '-----' . $message . "\r\n", FILE_APPEND );}
小程序端
wx.openBusinessView({businessType: 'weappOrderConfirm',extraData: {merchant_id: '',//商户id// merchant_trade_no: '1234323JKHDFE1243252',// transaction_id: '4200002336202407032185573612'transaction_id:that.data.order.order_info.transaction_id//微信交易单号},success(res) {console.log('调起确认收货');console.log(res)if(res.extraData.status=="success"){app.util.request({'url': 'entry/wxapp/index','data': {controller: 'order.receive_order',token: token,order_id: id},dataType: 'json',success: function(res) {if (res.data.code == 0) {wx.showToast({title: '收货成功',icon: 'success',duration: 1000})that.reload_data();} else {app.util.message(res.data.msg||'收货失败', '', 'error');}}});}//dosomething},fail(res) {//dosomethingconsole.log(that.data.order.order_info.transaction_id)console.log(res)},complete() {//dosomething}});