小程序如何对接微信支付:从商户号到第一笔回调

举报
yd_288814258 发表于 2026/10/20 02:41:48 2026/10/20
【摘要】 小程序如何对接微信支付:从商户号到第一笔回调小程序接入微信支付,本质不是「前端调一个 API」这么简单,而是后端下单 + 前端调起 + 异步回调验签三段式闭环。任何一段没接稳,都会出现「钱扣了订单没更新」「回调收不到」「签名错误」等经典问题。下面按实际落地顺序讲一遍。一、前置条件:先把账号关系理清在小程序里用微信支付,前提不是会写代码,而是账号资质要对:小程序主体完成微信认证(个人主体开不了...

小程序如何对接微信支付:从商户号到第一笔回调

小程序接入微信支付,本质不是「前端调一个 API」这么简单,而是后端下单 + 前端调起 + 异步回调验签三段式闭环。任何一段没接稳,都会出现「钱扣了订单没更新」「回调收不到」「签名错误」等经典问题。
下面按实际落地顺序讲一遍。

一、前置条件:先把账号关系理清

在小程序里用微信支付,前提不是会写代码,而是账号资质要对:
  • 小程序主体完成微信认证(个人主体开不了微信支付)
  • 申请微信支付商户号,支持企业、个体工商户、事业单位等
  • 小程序 AppID 与商户号互相绑定
  • 商户平台配置 APIv3 密钥、下载商户 API 证书
💡 小程序支付和公众号 JSAPI 支付共用一套下单接口,但小程序不需要配置 JSAPI 支付授权目录。

二、整体流程全景

标准链路只有 5 步:
  1. 用户点「立即支付」,小程序把订单信息发给自家后端
  2. 后端调用微信支付 JSAPI / 小程序下单接口,拿到 prepay_id
  3. 后端按规则签名,把 timeStamp / nonceStr / package / signType / paySign 返给前端
  4. 前端调 wx.requestPayment 拉起收银台
  5. 用户支付完成后,微信回调后端 notify_url,后端验签、解密、更新订单
前端回调只负责「页面跳转体验」,订单状态一律以后端回调 + 查单接口为准。

三、后端:调用 JSAPI 下单

接口地址

POST https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
请求头要带 Authorization(V3 签名)、Accept 和 Content-Type 都是 application/json。

核心参数


参数
说明
appid
小程序 AppID
mchid
商户号
description
商品描述,用户账单可见
out_trade_no
商户订单号,同商户号下唯一
notify_url
公网 HTTPS,不能带端口、不能重定向
amount.total
金额,单位分​
payer.openid
支付用户的 openid
示例 body:
{
  "appid": "wx1234567890",
  "mchid": "1900000109",
  "description": "商城-订单支付",
  "out_trade_no": "ORDER20261020001",
  "notify_url": "https://api.example.com/wxpay/notify",
  "amount": {
    "total": 1990,
    "currency": "CNY"
  },
  "payer": {
    "openid": "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"
  }
}
微信返回里取 prepay_id 即可。
⚠️ out_trade_no 必须唯一,重复会报订单号冲突;超时未付的订单应先关单再用新订单号重下。

四、前端:wx.requestPayment 调起支付

后端拿到 prepay_id 后,还要按 V3 规则生成前端签名(参与签名字段:appId、timeStamp、nonceStr、package),签名算法用 RSA。
前端拿到的参数结构:
wx.requestPayment({
  timeStamp: '1697780000',
  nonceStr: '5K8264ILTKCH16CQ2502SI8ZNMTM67VS',
  package: 'prepay_id=wx2026102000001234567890',
  signType: 'RSA',
  paySign: 'oR9d8PuhnIc+YZ8cB...',
  success(res) {
    // 仅做页面跳转,不代表支付成功
  },
  fail(res) {
    if (res.errMsg.includes('cancel')) {
      // 用户取消
    }
  }
})
几个容易踩的点:
  • package 值必须是 prepay_id=xxx 完整串,不是只传 id
  • signType 与后端签名方式保持一致,V3 用 RSA,别套旧教程的 MD5
  • success 回调只能说明「拉起支付没报错」,不能证明到账

五、后端:接收支付回调(最关键)

用户付完钱,微信会 POST 到 notify_url,报文是加密的。

1. 验签

回调 HTTP 头里带四个字段:
  • Wechatpay-Serial
  • Wechatpay-Signature
  • Wechatpay-Timestamp
  • Wechatpay-Nonce
用平台证书公钥对「时间戳 + 随机串 + body 原文」验签,确认确实是微信发的。

2. 解密

body 里的 resource.ciphertext 是 AES-256-GCM 加密,用 APIv3 密钥解密,拿到:
{
  "out_trade_no": "ORDER20261020001",
  "transaction_id": "4200001234567890",
  "trade_state": "SUCCESS",
  "amount": { "total": 1990 }
}

3. 业务处理 + 应答

正确处理顺序:
  1. 验签
  2. 解密
  3. 查本地订单,做幂等判断(已处理直接返回成功)
  4. 校验金额、订单号是否对得上
  5. 更新订单状态、发货、记日志
  6. 5 秒内返回 HTTP 200/204
// 成功不应答包体,状态码 200 即可
如果业务处理重(发券、推消息、扣库存),先落库标记「已收到通知」,再丢队列异步跑,别在回调里同步干重活,否则微信会超时重发。
⚠️ 微信回调会重复推,必须幂等;超时未应答会按 15s/30s/3m… 重发最多 15 次。

六、兜底:别只信回调

生产环境正确做法是「回调 + 主动查单」双保险:
  • 前端 requestPayment 返回后,调后端查单接口确认状态
  • 后端对「已创建但未支付」的订单,定时跑批查 查询订单 接口
  • 超时未付调用关单接口,释放库存

七、常见坑速查

  • 签名错误​ → 检查 appid 是不是小程序 appid、参数大小写、key/v3密钥用错、MD5/RSA 混用
  • 回调收不到​ → notify_url 非公网、带端口、HTTP、服务器防火墙拦了
  • 前端 paySign 报错​ → package 没带 prepay_id= 前缀
  • 交易类小程序调不起支付​ → 未接入订单发货管理,被公众平台限权
  • 金额对不上​ → 前端展示用元,后端传分,别直接透传

八、最小落地清单

接入前对着勾一遍:
  • [ ] 小程序已认证、商户号已绑定 AppID
  • [ ] APIv3 密钥和商户证书已配
  • [ ] 后端能调通 JSAPI 下单拿到 prepay_id
  • [ ] 前端 wx.requestPayment 参数由后端签名
  • [ ] notify_url 公网 HTTPS、幂等处理
  • [ ] 回调验签 + 解密 + 5 秒内应答
  • [ ] 订单状态以后端查单/回调为准
跑通这一条链路,小程序支付就算真正落地了。后面要加分账、退款、对账账单,都是在「下单 → 回调」这个骨架上挂模块,不会动摇主流程。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。