微信小程序支付,从关联商户号到收到第一笔钱
谁会卡在这
小程序能下单了,点付款却弹一句 appid 和 mch_id 不匹配。你打开商户平台看了三遍,AppID 明明填了。
或者更气人的:钱付出去了,微信扣了,订单还挂在「待支付」。
踩错的代价
小程序支付这条链路,真正卡人的地方不在代码,在两个后台之间。
三种死法,一种比一种晚发现:
第一种,当场调不起。 用户点付款直接弹错。这种最好——它当场告诉你坏了,你还有机会在上线前修。
第二种,能付但订单不变。 用户钱付了,你服务器没收到通知。用户以为没付成功,要么再付一次,要么来找你退款。这种要等到有人投诉才发现,而在那之前你一直觉得自己配得挺好。
第三种,审核被卡。 提审时带着充值入口,被要求补资质,一轮一周。等你补完,这个月过去一半了。
至于四样凭据(APIv3 密钥、API 证书、证书序列号、微信支付公钥)怎么配、别配混,那是另一篇的事,这里不重复。这篇只讲小程序特有的那几步。
正确步骤
一、关联商户号和小程序:这事得两边都点
这是最高频的坑,因为它是双向的,而一半人只做了前一半。
小程序和商户号是两个独立账号,默认互不认识。你得给它们互相介绍一下:
- 微信支付商户平台 →「产品中心」→「AppID 账号管理」→ 关联 AppID,填小程序 AppID
- 然后回到小程序后台(mp.weixin.qq.com)→「微信支付」→ 找到这个商户号 → 确认关联
第 2 步不做,商户平台那边就一直挂着「待确认」。而报错是 appid 和 mch_id 不匹配——它不会说"你还差一步确认",它就说不匹配。于是你回商户平台反复检查那个 AppID 有没有填错,检查到怀疑人生。
AppID 没错。是另一边没点。
主体不一致的情况另说,那个要多走一道确认流程,坑更深,单独一篇讲。
二、支付授权目录:小程序不用配,而我配了一下午
商户平台的「开发配置」里躺着「支付授权目录」「JSAPI 支付授权目录」。
我第一次接的时候看见就顺手配了。填域名、填路径、改了四五版、清缓存、重新提交,就是不生效。当时的想法是"肯定是我路径写错了",于是又改了三版。
后来才搞明白:小程序下单根本不看这个目录。
支付授权目录是给公众号 H5 支付用的。小程序只要 AppID 关联对了就能调起,跟这个目录一毛钱关系没有。
我在一个不需要配的地方,认认真真配了一下午。
做小程序支付,这一步直接跳过。
三、回调地址:三个硬要求,缺一个就是第二种死法
回调地址(notify_url)不通,就是前面说的"付了钱订单不变"。
- 必须 https,http 不收
- 域名必须已备案、公网能访问
- 不能带参数,问号后面那串去掉
判断方法很简单:下单能成功,说明凭据全对;订单不变,九成就是这里。 别再去翻密钥了。
四、前端调起支付
后端拿到 prepay_id 之后,组装五个字段给前端,前端直接透传:
wx.requestPayment({
// 秒级时间戳,必须是字符串
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
// 必须带前缀:prepay_id=wx2026...
package: res.package,
// v3 固定 RSA,不是 MD5
signType: 'RSA',
paySign: res.paySign,
success() {
// 别在这里把订单改成已支付
},
fail(e) {
console.error(e.errMsg)
}
})三个高频翻车点:
signType 从 v2 代码里抄过来忘了改。 v2 是 MD5 或 HMAC-SHA256,v3 固定 RSA。网上能搜到的老代码大半是 v2 的,照抄必挂。
package 要带 prepay_id= 前缀,只传那串 id 调不起来。
timeStamp 传字符串,传数字有些机型会失败——而且是"有些",所以你自己那台大概率测不出来。
paySign 的签名串是固定四行,顺序不能换,每行末尾都要有换行符:
小程序AppID\n
时间戳\n
随机字符串\n
package\n用商户 API 私钥做 SHA256-RSA 签名再 Base64。这里用的是小程序 AppID,不是商户号——两个都是一串字符,填反了报的还是"签名失败",你能查上半天。
最后那句注释单独展开说:success 里不要改订单状态。
它只代表用户在收银台点了确认,不代表钱到账。真正的状态以服务端收到异步回调为准。前端改状态,遇上用户支付到一半断网、或者付完立刻杀进程,你的订单数据就跟微信对不上了——而对账是月底才做的事,到时候你已经忘了这段代码。
五、验一笔真钱
配完别急着说完事。用真机走一笔小额支付,确认三件:
- 收银台调得起、能付成功
- 回调收到了,订单从待支付变成已支付 ← 最关键
- 商户平台后台查得到这笔,金额对得上
只在前端看到「支付成功」不算数。那可能只是微信那边成功了,你的订单还在原地。
六、提审前先把充值入口关掉
小程序审核期间,如果带着充值功能,可能被要求补充资质。一轮一周。
建议提审前先关掉入口,过审再开。
这条不在任何官方文档里,是被拒过才知道的。
常见报错对照表
| 报错 | 真正的原因 | 解法 |
|---|---|---|
appid 和 mch_id 不匹配 | 关联只做了商户平台那一半,没回小程序后台确认 | 两个后台各点一次,确认状态不是「待确认」 |
| 调起支付时「支付验证签名失败」 | signType 还写着 MD5,或签名串顺序/换行错了 | v3 固定 RSA;签名串按 AppID/时间戳/随机串/package 四行,每行都要换行符 |
requestPayment:fail 参数错误 | package 少了 prepay_id= 前缀,或 timeStamp 传了数字 | 补前缀;时间戳转成字符串 |
| 下单成功,订单一直待支付 | 回调地址非 https/未备案/带参数/端口被拦 | 换成 https 备案域名的干净地址,服务器放行 |
| 签名失败,但密钥证书都对 | paySign 里填的是商户号,不是小程序 AppID | 换成小程序 AppID |
| 金额差 100 倍 | 金额单位是分不是元 | 传整数分 |
| 提审被驳回,要求补充资质 | 提审时带着充值功能 | 先关掉充值入口,过审再开 |
这条链路上的其他几篇
- 《微信支付 v3 的证书和密钥,四类东西别再配混了》
