微信小程序真实物流商城接入指南[避坑版]
这篇是我自己做小程序商城时踩坑总结出来的,从绑定商户、微信支付,到后面微信强制要求的发货信息管理,能避的坑我都尽量写清楚。官方文档能看,但很多地方不会告诉你「实际线上会怎么炸」。
小程序绑定微信商户
首先就是来这个界面去申请:

绑定完成后,需要去 https://pay.weixin.qq.com/。由于我用的是微信支付 V3,所以需要拿私钥、公钥、APIv3 密钥、证书序列号、商户号等信息。如果你都拿到了就可以下一步。
注意:小程序 AppID 和商户号要在两边都关联好,后面发货、对账、结算都会用到,别只配了支付没配订单管理。
接入微信支付
服务端调用凭证
首先是需要每过一段时间去获取微信小程序服务端调用凭证(access_token)的。
这里的话我建议是:如果一些接口请求报错了,或者返回 40001 / 42001 这类 token 失效的错误,再去尝试刷新调用凭证。我不建议定时无脑刷新,如果你在线下调试就有可能跟已经部署了的应用抢 token,两边互相把 token 顶失效,调试起来很烦。
调用接口文档在下图这里:

如果项目里有多个小程序 AppID,一定要按 appId 分开缓存 token,别全局共用一个,不然 A 小程序的接口拿 B 小程序的 token 去调,报错你半天找不到原因。
微信支付
这里的话是建议大家用两个表来管理订单比较合适。准确来说是一个系统订单表,另一个算是微信支付流水表(支付单)。
- 系统订单表:管业务状态(待支付、待发货、待收货……)
- 支付流水表:管
out_trade_no、transaction_id、支付回调原始数据
然后微信支付的话,就按照微信文档来就行了,也可以去看看其他博主的微信支付详细教程。
注意:微信支付需要做一层保险。当用户支付了,然后服务端可能卡了或者重启等情况的时候,没有获取到微信支付的异步回调,我们自己的系统就会漏掉「待支付」状态的订单。因此我们需要定时去向微信方对一下账,看看一些待支付的系统订单到底支付了没。同时还建议系统订单有过期时间,如果不过期,待支付的系统订单会堆积越来越多,最后去调用微信对账接口查的东西也会越来越多。
对账接口:https://pay.weixin.qq.com/doc/v3/partner/4012760526

线上环境支付失败,显示小程序违规?
需要来这里配置一下,订单的详情地址,跳进去的时候需要可以查询到订单信息。这里配置完成一般就不会再显示违规了。

物流问题
如果你的系统发货了之后,收到了这样的通知:

那么接下来的内容应该可以帮你解决这样的问题。
既然我们这个商城是跟真实物流挂钩的,那么现在系统的发货写法也是不一样的。微信现在要求走「发货信息管理服务」,不是你在自己后台改个状态就叫发货了——微信那边也要录入一份,不然资金会一直冻着,结算也会出问题。
先搞清楚:你要接的是什么?
很多人一开始会搞混,这里分清楚:
| 能力 | 干什么 | 路径前缀 | 要不要接 |
|---|---|---|---|
| 发货信息管理服务 | 发货录入、确认收货、资金结算 | /wxa/sec/order/... | 必须接 |
| 物流助手 / 物流服务 | 电子面单、快递下单、查轨迹 | /cgi-bin/express/... | 可选,跟结算无关 |
我这次只接了发货信息管理,没有接物流助手。商家自己有快递单号,手动填进去就行。
上线前公众平台要配什么?
-
交易结算管理确认:在公众平台「支付与交易 → 订单管理」里,把关联的商户号都授权确认一遍。没做这一步,
upload_shipping_info可能直接失败。 -
消息推送 URL(下面单独说,这个很重要):
https://你的域名/api/wxmp/message,选明文 + XML(别选 JSON 加密模式,不然你服务端解析对不上)。Token 要和后端配置一致。

-
消息跳转路径:调
set_msg_jump_path设置成你的订单详情页,比如pages/order/detail。用户点微信发货通知就能跳进小程序。
完整业务闭环(照着做就不会乱)
用户支付成功 → 订单「待发货」
↓
管理后台填快递单号 → 先调微信 upload_shipping_info → 成功后再改本地「待收货」
↓
用户点「确认收货」→ 必须调 wx.openBusinessView 拉起微信组件 → 微信侧确认
↓
后端 get_order 校验微信 order_state >= 3 → 本地改「待评价」
↓
微信结算 / 用户 10 天未点自动确认 → 消息推送或定时任务补偿同步本地
重点:微信没有「用户在你页面点确认 → 你后端通知微信已收货」的 API。你自己页面点个按钮改本地状态,微信那边不知道,钱还是要等约 10 天自动确认才结算。
物流有两种情况
商家已经有联系的固定物流公司
已经有了的话,那么只需要:
- 管理后台发货时,先调微信
upload_shipping_info,成功后再更新本地订单状态。 - 快递公司编码不能填中文名,要去调
get_delivery_list拿微信运力 ID(比如顺丰是SF)。 - 小程序确认收货走
wx.openBusinessView,businessType: 'weappOrderConfirm'。 - 用户在微信订单中心确认、或者超时自动确认后,靠消息推送 + 定时补偿任务把本地状态同步过来。
核心接口就这几个:
接口地址:https://developers.weixin.qq.com/miniprogram/dev/server/API/order_shipping/api_uploadshippinginfo.html
| 接口 | 路径 | 什么时候用 |
|---|---|---|
| 发货录入 | POST /wxa/sec/order/upload_shipping_info | 管理端点发货 |
| 查发货状态 | POST /wxa/sec/order/get_order | 确认收货前校验 |
| 运力列表 | POST /cgi-bin/express/delivery/open_msg/get_delivery_list | 管理端快递公司下拉 |
| 消息跳转 | POST /wxa/sec/order/set_msg_jump_path | 启动时设一次 |
发货请求体大概长这样(有 transaction_id 优先用它):
{
"order_key": {
"order_number_type": 2,
"transaction_id": "4200003173202607025628410162"
},
"logistics_type": 1,
"delivery_mode": 1,
"shipping_list": [{
"tracking_no": "SF1234567890",
"express_company": "SF",
"item_desc": "商品描述限120字"
}],
"upload_time": "2026-07-08T17:30:00.120+08:00",
"payer": { "openid": "用户openid" }
}
注意几个我踩过的坑:
order_number_type:1 = 商户单号,2 = 微信交易单号。有些旧教程写反了,按错必挂。get_order的参数是扁平的transaction_id或merchant_id + merchant_trade_no,不是包一层order_key。get_delivery_list路径是/cgi-bin/express/delivery/open_msg/get_delivery_list,不是/wxa/sec/order/...,填错就invalid url。- 顺丰发货时
shipping_list[].contact必填,手机号要掩码,末 4 位不能打星号。 is_trade_managed这类自检接口,body 要传{ "appid": "wx..." },传空对象报 40097。
商家没有联系固有的物流公司
如果商家没有固定快递,有两种路:
- 继续手动发货:商家自己联系快递、拿到单号,在管理后台录入,走上面同一套
upload_shipping_info流程。这是我现在用的方案,最简单。 - 接微信物流助手:电子面单、自动下单、查轨迹,路径是
/cgi-bin/express/...,跟结算无关,属于二期能力,有需求再搞。
不管哪种,本地改了状态不算发货,微信那边没录入就不算。
消息推送与状态同步
消息推送 URL 是干嘛用的?
简单说:这是微信服务器主动往你后端「打电话」的地址,跟微信支付回调不是一回事。
| 对比 | 微信支付回调 | 消息推送 URL |
|---|---|---|
| 干什么 | 告诉你要不要改「待支付 → 已支付」 | 告诉你要不要改「待收货 → 待评价」等发货/结算相关状态 |
| 谁调 | 微信支付系统 | 微信小程序平台 |
| 典型场景 | 用户付完钱 | 用户确认收货、超时自动确认、提醒你去发货 |
配置路径:开发 → 开发管理 → 开发设置 → 消息推送(或「服务器配置」)。
配好之后有两步交互:
- GET 验证:微信第一次配置时会带
signature、timestamp、nonce、echostr来访问你的 URL。你后端用 Token 验签,验过了就原样返回echostr纯文本(别包 JSON),微信平台才认为地址有效。 - POST 收事件:之后有订单相关事件,微信会 POST 一段 XML 到你这个地址。你解析
Event字段,做对应业务处理,最后返回字符串success就行。
我们项目里主要关心的是 Event=trade_manage_order_settlement(订单结算事件)。微信会在 XML 里带上 transaction_id、merchant_trade_no 等字段,后端根据这些找到本地订单,如果还是「待收货」,就改成「待评价」。
为什么需要它? 因为用户不一定在你小程序里点确认收货。常见几种情况:
- 用户在**微信「我 → 订单与卡包 → 小程序订单」**里点的确认收货,不会走你的
openBusinessView,你的后端根本不知道。 - 用户一直不点,约 10 天微信自动确认,同样不会调你的接口。
- 用户虽然在你小程序里确认了,但网络抖动、服务重启,本地状态可能没更新成功。
没有消息推送 URL,上面这些情况你的系统订单就会一直卡在「待收货」,跟微信实际状态对不上。所以它是补偿同步用的,跟定时任务(每隔几小时调 get_order 对账)是双保险,建议两个都配上。
注意:消息推送只管「微信 → 你后端」这一方向,不能用来代替 upload_shipping_info 发货录入,也不能代替 openBusinessView 让用户确认收货。该调的 API 还是要调。
推送时机与本地要不要改状态
微信会在两个时机推 trade_manage_order_settlement 事件:
| 时机 | 特有字段 | 你要不要改本地状态 |
|---|---|---|
| 发货完成时 | shipped_time | 不要,这时用户还没确认收货 |
| 订单结算时 | confirm_receive_time、settlement_time | 要,这时才改本地「待评价」 |
我一开始没区分这两个时机,发货后微信一推送,本地订单就直接变成「待评价」了,用户明明还没点确认收货。一定要按字段区分。
另外建议加一个定时补偿任务(比如每 6 小时),扫描「待收货 + 已同步微信发货」的订单,调 get_order 看微信那边是不是已经确认了,是的话补偿更新本地。防止消息推送丢了或者用户在微信订单中心确认、没走你小程序页面。
小程序侧要注意的
确认收货组件
wx.openBusinessView({
businessType: 'weappOrderConfirm',
extraData: {
transaction_id: '420000...' // 或者用 merchant_id + merchant_trade_no
},
success(res) {
// 看 res.extraData.status === 'success' 才算真成功
// 不是 success 回调进了就代表收货成功!
}
})
success 进了不代表收货成功,必须看 extraData.status,是 success / fail / cancel 三种。
微信发货通知跳详情页
设置了 set_msg_jump_path 之后,用户点微信发货通知,URL 会带 transaction_id、merchant_id、merchant_trade_no,不会带你的业务 orderNo。
所以订单详情页的 onLoad 必须能解析这些参数,后端 findOne 也要支持用微信单号查订单。不然用户一点通知进去就是「订单不存在」——这个坑我踩实了。
Token 过期
从微信通知冷启动进详情页,如果 access token 过期但 refresh token 还在,一般会自动刷新。如果 refresh 也过期了,会弹登录框。但详情页请求失败时现在可能显示「订单不存在」,其实是没登录,这个提示有点误导,后面可以优化一下。
我踩过的坑汇总
| 现象 | 原因 | 怎么修 |
|---|---|---|
获取运力列表 invalid url | 路径写错 | 用 /cgi-bin/express/delivery/open_msg/get_delivery_list |
| 发货 / 查单参数错误 | order_number_type 枚举反了 | 1=商户单号,2=微信交易单号 |
get_order 400 | body 多包了一层 order_key | 改成扁平参数 |
| 启动自检报 40097 | 自检接口 body 缺 appid | 传 { appid: "wx..." } |
| 发货后本地立刻变「待评价」 | 没区分发货推送和结算推送 | 只有结算字段存在才同步 |
| 点微信通知进详情「订单不存在」 | 详情页不识别 transaction_id | 前后端都支持微信 query 参数 |
| 顺丰发货失败 | 缺 contact 掩码手机号 | 传 receiver_contact |
Set is not a function 之类 | Redis Set 和原生 Set 重名 | import 时 alias 成 RedisSet |
官方文档索引
| 文档 | 链接 |
|---|---|
| 发货信息管理服务(总览) | https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html |
| 发货信息录入 | https://developers.weixin.qq.com/miniprogram/dev/server/API/order_shipping/api_uploadshippinginfo.html |
| 查询订单发货状态 | https://developers.weixin.qq.com/miniprogram/dev/server/API/order_shipping/api_getorder.html |
| 确认收货组件 | https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping-half.html |
| 公众平台订单管理 | https://mp.weixin.qq.com/wxamp/order |
写在最后
真实物流商城跟普通小程序下单最大的区别就两点:支付要对账兜底,发货要走微信发货信息管理。本地状态和微信状态必须两边对齐,不然要么钱结不了,要么用户投诉「我明明收货了系统还显示待收货」。
我这套是「管理后台发货 + API 同步微信 + 小程序组件确认收货 + 消息推送/定时补偿」的组合,日常运营够用了。物流助手、电子面单那些以后有需求再加。
如果你也在接这块,欢迎评论区交流,踩过的坑我可以再补充。
更多推荐
所有评论(0)