微信小程序订单发货管理完整解决方案

本文将基于 ThinkPHP 框架,完整介绍订单发货信息录入、运单取消、运力列表查询,以及支付合规排查的完整解决方案,重点讲解"发货后如何取消"这一常见问题。

目录

一、前言

二、体验版支付提示"违规"问题排查

2.1 问题现象

2.2 原因分析

2.3 核心原因与解决方案

第一步:检查"订单发货管理"是否接入

第二步:查看站内信与通知

第三步:检查账号基础状态

2.4 订单详情路径配置注意事项

2.5 总结操作步骤

三、发货信息录入 API 实现

3.1 API 接口说明

3.2 请求参数说明

3.3 shipping_list 结构说明

3.4 PHP 代码实现

3.5 使用示例

四、获取运力列表(快递公司列表)API

4.1 API 接口说明

4.2 PHP 代码实现

4.3 返回数据示例

五、发货后如何取消(重点)

4.1 仅录入发货信息(uploadShippingInfo)

4.2 查询订单发货状态

4.3 返回的发货状态说明

六、常见问题总结

七、总结

参考文章


一、前言

在微信小程序商城系统开发中,实物电商类小程序必须接入"订单发货管理"系统,否则会触发微信风控策略,导致支付功能被封禁。本文将基于 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 查询当前订单发货状态
  • 运力列表查询:获取支持的快递公司编码列表
  • 支付合规:接入订单发货管理系统,配置订单详情路径,确保支付功能正常

参考文章

发货信息录入 | 微信开放文档

微信小程序在发起支付的时候提示“由于小程序违规,支付功能暂时无法使用”

通过本文的完整实现方案,可以快速接入微信小程序订单发货管理系统,正确处理发货取消场景,确保支付功能正常使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JSON_L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值