本文将基于 ThinkPHP 框架,完整介绍订单发货信息录入、运单取消、运力列表查询,以及支付合规排查的完整解决方案,重点讲解"发货后如何取消"这一常见问题。
目录
4.1 仅录入发货信息(uploadShippingInfo)
一、前言
在微信小程序商城系统开发中,实物电商类小程序必须接入"订单发货管理"系统,否则会触发微信风控策略,导致支付功能被封禁。本文将基于 ThinkPHP 框架,完整介绍订单发货信息录入、运单取消、运力列表查询,以及支付合规排查的完整解决方案,重点讲解"发货后如何取消"这一常见问题。
二、体验版支付提示"违规"问题排查
2.1 问题现象
开发小程序商城系统时,对接微信支付是必须的。在开发阶段,微信开发者工具里能正确调起支付操作,但提交体验版后,直接在小程序发起支付时提示:
由于小程序违规,支付功能暂时无法使用
这个提示让人一脸懵逼——小程序都没上线,哪来的违规?实际上,微信的提示不太准确,很容易误导人。
2.2 原因分析
通过打开调试,可以看到错误码 errno: 102,这是微信官方针对小程序的支付限制。虽然预下单(统一下单)接口能成功,但"调起支付"这一步被微信的风控系统拦截了。这通常是小程序账号资质或订单合规性触发了平台规则,而不是代码或商户号的问题。
2.3 核心原因与解决方案
第一步:检查"订单发货管理"是否接入
这是最常见的原因。根据微信新规,实物电商类小程序必须接入"订单发货管理"系统,否则会直接封禁支付功能。
- 操作路径:登录微信公众平台 (mp.weixin.qq.com) → 功能 → 微信支付 → 订单管理
- 需要做:确认是否已点击"同意并接入"
- 必须正确配置订单详情页路径(如 pages/order/detail/index)
第二步:查看站内信与通知
微信的处罚通常会发送站内信,但容易被忽略。
- 操作路径:登录微信公众平台 → 首页左侧"通知中心"
- 需要做:寻找标题包含"违规"、"支付功能受限"、"订单管理"的站内信
- 如果存在,直接点击信中链接进行申诉或按指引整改
第三步:检查账号基础状态
- 认证与备案:确认小程序已完成微信认证(年审未过期)和 ICP 备案
- 商户号授权:在"微信支付" → "商户号管理"中,确认商户号状态正常且已与该小程序绑定确认
2.4 订单详情路径配置注意事项
第一次提交订单详情路径可能会提示失败,原因是要先提交小程序审核。只要提交小程序审核后即可录入成功。录入成功后,不管审核是否通过,即可发起支付测试。
2.5 总结操作步骤
1. 登录后台:访问 mp.weixin.qq.com
2. 查通知:点开"通知中心",确认是否有未处理的违规单
3. 改订单:去"微信支付" -> "订单管理",接入发货系统并填好路径
4. 等生效:整改完成后,系统通常会在 24-48 小时内自动恢复。如果超时未恢复,需通过站内信的"申诉"按钮提交人工审核
三、发货信息录入 API 实现
3.1 API 接口说明
文档地址:
该接口用于商户小程序发货信息录入,发货后需同步发货信息到微信,用户可以在微信服务通知收到发货通知。
3.2 请求参数说明
| 参数名 | 类型 | 说明 |
| transaction_id | string | 微信支付单号(与 out_trade_no 二选一) |
| out_trade_no | string | 商户订单号(与 transaction_id 二选一) |
| openid | string | 用户 openid(必填) |
| logistics_type | int | 物流模式:1=实体物流 2=同城配送 3=虚拟商品 4=用户自提 |
| delivery_mode | int | 发货模式:1=统一发货 2=分拆发货 |
| shipping_list | array | 物流信息列表(1-15条) |
| is_all_delivered | bool | 分拆发货时是否全部发货完成 |
3.3 shipping_list 结构说明
| 参数名 | 类型 | 说明 |
| tracking_no | string | 物流单号(快递发货必填) |
| express_company | string | 物流公司编码(快递发货必填) |
| item_desc | string | 商品描述(必填) |
| contact | object | 联系方式(顺丰快递必填) |
3.4 PHP 代码实现
/**
* 小程序订单发货信息录入
* @param array $params 发货参数
* @return array
*/
public function uploadShippingInfo($params)
{
// 必填参数校验
if (empty($params['openid'])) {
throw new Exception('用户 openid 不能为空');
}
if (empty($params['shipping_list']) || !is_array($params['shipping_list'])) {
throw new Exception('物流信息列表不能为空');
}
if (count($params['shipping_list']) > 15) {
throw new Exception('物流信息列表最多 15 条');
}
// 校验 shipping_list 中的必填字段
foreach ($params['shipping_list'] as $index => $item) {
if (empty($item['item_desc'])) {
throw new Exception("商品描述不能为空");
}
// 实体物流时,物流单号和物流公司编码必填
if (($params['logistics_type'] ?? 1) == 1) {
if (empty($item['tracking_no']) || empty($item['express_company'])) {
throw new Exception("物流单号和物流公司编码不能为空");
}
}
}
$accessToken = $this->getMiniappAccessToken();
$url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token={$accessToken}";
$postData = [
'order_key' => [
'order_number_type' => 1,
'out_trade_no' => $params['out_trade_no'],
'mchid' => $this->mchid,
],
'logistics_type' => (int)($params['logistics_type'] ?? 1),
'delivery_mode' => (int)($params['delivery_mode'] ?? 1),
'shipping_list' => $params['shipping_list'],
'upload_time' => date('Y-m-d\TH:i:s.vP'),
'payer' => ['openid' => $params['openid']],
];
$response = Http::post($url, json_encode($postData));
$result = (array)json_decode($response, true);
if (isset($result['errcode']) && $result['errcode'] != 0) {
throw new Exception('小程序发货信息录入失败:' . ($result['errmsg'] ?? 'unknown'));
}
return $result;
}
3.5 使用示例
// 发货信息录入
$this->uploadShippingInfo([
'out_trade_no' => $order['order_no'],
'openid' => $order['user']['openid'],
'logistics_type' => 1, // 实体物流
'delivery_mode' => 1, // 统一发货
'shipping_list' => [[
'tracking_no' => 'SF1234567890',
'express_company' => 'SF',
'item_desc' => '商品名称*1',
]],
]);
四、获取运力列表(快递公司列表)API
4.1 API 接口说明
文档地址:获取运力id列表 | 微信开放文档
该接口用于获取微信小程序支持的运力 ID 列表(快递公司编码),用于发货信息录入时选择正确的快递公司。
4.2 PHP 代码实现
/**
* 获取微信小程序运力id列表(快递公司列表)
* @param array $config 小程序配置
* @return array 运力列表
*/
public function getDeliveryList($config = [])
{
$accessToken = $this->getMiniappAccessToken($config);
$url = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/get_delivery_list?access_token={$accessToken}";
// POST 请求,空请求体(微信接口要求)
$response = Http::post($url, json_encode(new \stdClass()));
$result = (array)json_decode($response, true);
if (isset($result['errcode']) && $result['errcode'] != 0) {
throw new hink\Exception('获取运力列表失败:' . ($result['errmsg'] ?? 'unknown'));
}
return $result;
}
注意:请求体必须是空对象 {},使用 json_encode(new stdClass()) 生成,而不是 null 或空数组。
4.3 返回数据示例
{
"errcode": 0,
"errmsg": "ok",
"delivery_list": [
{"delivery_id": "SF", "delivery_name": "顺丰速运"},
{"delivery_id": "YTO", "delivery_name": "圆通速递"},
{"delivery_id": "ZTO", "delivery_name": "中通快递"},
{"delivery_id": "EMS", "delivery_name": "EMS"},
{"delivery_id": "HTKY", "delivery_name": "百世快递"},
{"delivery_id": "JD", "delivery_name": "京东快递"}
]
}
五、发货后如何取消(重点)
这是开发者最关心的问题:已经调用了发货信息录入 API 后,如果要取消发货,应该怎么处理?
4.1 仅录入发货信息(uploadShippingInfo)
如果只是调用了发货信息录入 API,微信没有提供专门的"取消发货"接口。处理流程如下:
1. 第一步:联系快递公司拦截/召回快递(如果已经发出)
2. 第二步:调用微信退款 API 发起退款
3. 第三步:退款成功后,微信系统会自动更新订单发货状态
4. 第四步:用户会在微信服务通知中收到退款通知
注意:发货信息录入只是告知微信"已发货"的状态,并没有创建真正的快递运单。如果要取消,只能通过退款方式让微信系统自动更新状态。
4.2 查询订单发货状态
在取消发货前,可以先查询订单的当前发货状态:
/**
* 查询订单发货状态
* @param array $params 查询参数
* @return array
*/
public function getShippingOrder($params)
{
$accessToken = $this->getMiniappAccessToken();
$url = "https://api.weixin.qq.com/wxa/sec/order/get_order?access_token={$accessToken}";
$orderKey = [];
if (!empty($params['transaction_id'])) {
$orderKey['order_number_type'] = 2;
$orderKey['transaction_id'] = $params['transaction_id'];
} elseif (!empty($params['out_trade_no'])) {
$orderKey['order_number_type'] = 1;
$orderKey['out_trade_no'] = $params['out_trade_no'];
$orderKey['mchid'] = $this->mchid;
}
$postData = ['order_key' => $orderKey];
$response = Http::post($url, json_encode($postData));
$result = (array)json_decode($response, true);
if (isset($result['errcode']) && $result['errcode'] != 0) {
throw new Exception('查询订单发货状态失败');
}
return $result;
}
4.3 返回的发货状态说明
| 状态值 | 说明 |
| 1 | 待发货 |
| 2 | 已发货 |
| 3 | 已收货 |
| 4 | 已退款/已取消 |
六、常见问题总结
| 问题 | 原因 | 解决方案 |
| 体验版支付提示违规 | 未接入订单发货管理系统 | 登录 mp.weixin.qq.com → 微信支付 → 订单管理 → 同意并接入 |
| 发货信息录入失败 | shipping_list 缺少必填字段 | 检查 tracking_no、express_company、item_desc 是否完整 |
| 无法取消发货信息 | 发货信息录入无取消 API | 只能通过微信退款 API 退款,系统自动更新状态 |
| 取消运单失败 | 运单不是通过微信物流助手创建 | 此接口仅限微信物流助手创建的电子面单运单 |
| 获取运力列表失败 | 请求体格式错误 | 使用 json_encode(new stdClass()) 生成空对象 {} |
| 订单详情路径配置失败 | 小程序未提交审核 | 先提交小程序审核,审核后即可录入路径 |
| 支付功能未恢复 | 整改后等待时间不足 | 整改完成后需等待 24-48 小时自动恢复 |
| 退款后发货状态未更新 | 退款回调未正确处理 | 确认退款成功后微信系统会自动更新发货状态 |
七、总结
微信小程序订单发货管理核心要点:
- 发货信息录入 API:发货后同步到微信,用户可收到服务通知
- 取消发货:发货信息录入无专门取消 API,只能通过退款处理;电子面单运单可调用取消运单 API
- 查询发货状态:通过 get_order API 查询当前订单发货状态
- 运力列表查询:获取支持的快递公司编码列表
- 支付合规:接入订单发货管理系统,配置订单详情路径,确保支付功能正常
参考文章
微信小程序在发起支付的时候提示“由于小程序违规,支付功能暂时无法使用”
通过本文的完整实现方案,可以快速接入微信小程序订单发货管理系统,正确处理发货取消场景,确保支付功能正常使用。

289

被折叠的 条评论
为什么被折叠?



