这篇是我自己做小程序商城时踩坑总结出来的,从绑定商户、微信支付,到后面微信强制要求的发货信息管理,能避的坑我都尽量写清楚。官方文档能看,但很多地方不会告诉你「实际线上会怎么炸」。


小程序绑定微信商户

首先就是来这个界面去申请:

在这里插入图片描述

绑定完成后,需要去 https://pay.weixin.qq.com/。由于我用的是微信支付 V3,所以需要拿私钥、公钥、APIv3 密钥、证书序列号、商户号等信息。如果你都拿到了就可以下一步。

注意:小程序 AppID 和商户号要在两边都关联好,后面发货、对账、结算都会用到,别只配了支付没配订单管理。


接入微信支付

服务端调用凭证

首先是需要每过一段时间去获取微信小程序服务端调用凭证(access_token)的。

这里的话我建议是:如果一些接口请求报错了,或者返回 40001 / 42001 这类 token 失效的错误,再去尝试刷新调用凭证。我不建议定时无脑刷新,如果你在线下调试就有可能跟已经部署了的应用抢 token,两边互相把 token 顶失效,调试起来很烦。

调用接口文档在下图这里:

在这里插入图片描述

如果项目里有多个小程序 AppID,一定要按 appId 分开缓存 token,别全局共用一个,不然 A 小程序的接口拿 B 小程序的 token 去调,报错你半天找不到原因。

微信支付

这里的话是建议大家用两个表来管理订单比较合适。准确来说是一个系统订单表,另一个算是微信支付流水表(支付单)。

  • 系统订单表:管业务状态(待支付、待发货、待收货……)
  • 支付流水表:管 out_trade_notransaction_id、支付回调原始数据

然后微信支付的话,就按照微信文档来就行了,也可以去看看其他博主的微信支付详细教程。

注意:微信支付需要做一层保险。当用户支付了,然后服务端可能卡了或者重启等情况的时候,没有获取到微信支付的异步回调,我们自己的系统就会漏掉「待支付」状态的订单。因此我们需要定时去向微信方对一下账,看看一些待支付的系统订单到底支付了没。同时还建议系统订单有过期时间,如果不过期,待支付的系统订单会堆积越来越多,最后去调用微信对账接口查的东西也会越来越多。

对账接口:https://pay.weixin.qq.com/doc/v3/partner/4012760526

在这里插入图片描述

线上环境支付失败,显示小程序违规?

需要来这里配置一下,订单的详情地址,跳进去的时候需要可以查询到订单信息。这里配置完成一般就不会再显示违规了。

在这里插入图片描述


物流问题

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

在这里插入图片描述

那么接下来的内容应该可以帮你解决这样的问题。

既然我们这个商城是跟真实物流挂钩的,那么现在系统的发货写法也是不一样的。微信现在要求走「发货信息管理服务」,不是你在自己后台改个状态就叫发货了——微信那边也要录入一份,不然资金会一直冻着,结算也会出问题。

官方总览文档:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html

先搞清楚:你要接的是什么?

很多人一开始会搞混,这里分清楚:

能力干什么路径前缀要不要接
发货信息管理服务发货录入、确认收货、资金结算/wxa/sec/order/...必须接
物流助手 / 物流服务电子面单、快递下单、查轨迹/cgi-bin/express/...可选,跟结算无关

我这次只接了发货信息管理,没有接物流助手。商家自己有快递单号,手动填进去就行。

上线前公众平台要配什么?

  1. 交易结算管理确认:在公众平台「支付与交易 → 订单管理」里,把关联的商户号都授权确认一遍。没做这一步,upload_shipping_info 可能直接失败。

  2. 消息推送 URL(下面单独说,这个很重要):https://你的域名/api/wxmp/message,选明文 + XML(别选 JSON 加密模式,不然你服务端解析对不上)。Token 要和后端配置一致。
    在这里插入图片描述

  3. 消息跳转路径:调 set_msg_jump_path 设置成你的订单详情页,比如 pages/order/detail。用户点微信发货通知就能跳进小程序。

完整业务闭环(照着做就不会乱)

用户支付成功 → 订单「待发货」
    ↓
管理后台填快递单号 → 先调微信 upload_shipping_info → 成功后再改本地「待收货」
    ↓
用户点「确认收货」→ 必须调 wx.openBusinessView 拉起微信组件 → 微信侧确认
    ↓
后端 get_order 校验微信 order_state >= 3 → 本地改「待评价」
    ↓
微信结算 / 用户 10 天未点自动确认 → 消息推送或定时任务补偿同步本地

重点:微信没有「用户在你页面点确认 → 你后端通知微信已收货」的 API。你自己页面点个按钮改本地状态,微信那边不知道,钱还是要等约 10 天自动确认才结算。


物流有两种情况

商家已经有联系的固定物流公司

已经有了的话,那么只需要:

  1. 管理后台发货时,先调微信 upload_shipping_info,成功后再更新本地订单状态。
  2. 快递公司编码不能填中文名,要去调 get_delivery_list 拿微信运力 ID(比如顺丰是 SF)。
  3. 小程序确认收货走 wx.openBusinessViewbusinessType: 'weappOrderConfirm'
  4. 用户在微信订单中心确认、或者超时自动确认后,靠消息推送 + 定时补偿任务把本地状态同步过来。

核心接口就这几个:
接口地址: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_type1 = 商户单号,2 = 微信交易单号。有些旧教程写反了,按错必挂。
  • get_order 的参数是扁平transaction_idmerchant_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。

商家没有联系固有的物流公司

如果商家没有固定快递,有两种路:

  1. 继续手动发货:商家自己联系快递、拿到单号,在管理后台录入,走上面同一套 upload_shipping_info 流程。这是我现在用的方案,最简单。
  2. 接微信物流助手:电子面单、自动下单、查轨迹,路径是 /cgi-bin/express/...,跟结算无关,属于二期能力,有需求再搞。

不管哪种,本地改了状态不算发货,微信那边没录入就不算。


消息推送与状态同步

消息推送 URL 是干嘛用的?

简单说:这是微信服务器主动往你后端「打电话」的地址,跟微信支付回调不是一回事。

对比微信支付回调消息推送 URL
干什么告诉你要不要改「待支付 → 已支付」告诉你要不要改「待收货 → 待评价」等发货/结算相关状态
谁调微信支付系统微信小程序平台
典型场景用户付完钱用户确认收货、超时自动确认、提醒你去发货

配置路径:开发 → 开发管理 → 开发设置 → 消息推送(或「服务器配置」)。

配好之后有两步交互:

  1. GET 验证:微信第一次配置时会带 signaturetimestampnonceechostr 来访问你的 URL。你后端用 Token 验签,验过了就原样返回 echostr 纯文本(别包 JSON),微信平台才认为地址有效。
  2. POST 收事件:之后有订单相关事件,微信会 POST 一段 XML 到你这个地址。你解析 Event 字段,做对应业务处理,最后返回字符串 success 就行。

我们项目里主要关心的是 Event=trade_manage_order_settlement(订单结算事件)。微信会在 XML 里带上 transaction_idmerchant_trade_no 等字段,后端根据这些找到本地订单,如果还是「待收货」,就改成「待评价」。

为什么需要它? 因为用户不一定在你小程序里点确认收货。常见几种情况:

  • 用户在**微信「我 → 订单与卡包 → 小程序订单」**里点的确认收货,不会走你的 openBusinessView,你的后端根本不知道。
  • 用户一直不点,约 10 天微信自动确认,同样不会调你的接口。
  • 用户虽然在你小程序里确认了,但网络抖动、服务重启,本地状态可能没更新成功。

没有消息推送 URL,上面这些情况你的系统订单就会一直卡在「待收货」,跟微信实际状态对不上。所以它是补偿同步用的,跟定时任务(每隔几小时调 get_order 对账)是双保险,建议两个都配上。

注意:消息推送只管「微信 → 你后端」这一方向,不能用来代替 upload_shipping_info 发货录入,也不能代替 openBusinessView 让用户确认收货。该调的 API 还是要调。


推送时机与本地要不要改状态

微信会在两个时机推 trade_manage_order_settlement 事件:

时机特有字段你要不要改本地状态
发货完成时shipped_time不要,这时用户还没确认收货
订单结算时confirm_receive_timesettlement_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_idmerchant_idmerchant_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 400body 多包了一层 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 同步微信 + 小程序组件确认收货 + 消息推送/定时补偿」的组合,日常运营够用了。物流助手、电子面单那些以后有需求再加。

如果你也在接这块,欢迎评论区交流,踩过的坑我可以再补充。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐