我做小程序接入微信支付,才发现最难的不是代码
真正容易卡住人的,往往不是 wx.requestPayment,而是商户号、白名单、证书、回调、退款和资金状态这些细节。
我之前以为,接入微信支付最难的是写代码。
后来真的做了一遍,发现不是。
代码反而是比较清楚的部分:后端下单,小程序调起支付,微信回调通知,服务端更新订单状态。
真正耗时间的,是那些看起来不像代码的问题。
商户号有没有关联小程序?APIv3 密钥有没有设置?证书和公钥放在哪里?回调地址能不能访问?服务器 IP 有没有加白名单?退款和转账的钱到底在哪个账户?
这些东西任何一个没配对,页面上可能只给你一个很笼统的失败。
微信支付接入不是一段代码,而是一整条配置链路。
第一关:先把账号关系理顺
很多人一上来就想写支付接口。
但小程序支付不是孤立存在的。
你得先确认三件事:
这一步没理顺,后面代码写得再漂亮也没用。
我之前测试时就遇到过一种情况:后台看起来商户号已经存在,但小程序侧还要确认关联关系。没确认之前,支付链路就是半通不通。
所以我的建议是,接入前先画一张很简单的关系图:
小程序 AppID ↓ 关联商户号 ↓ JSAPI 支付产品 ↓ APIv3 密钥 / 证书 / 回调地址
这张图画清楚,后面排查会轻松很多。
第二关:不是有密钥就能调接口
微信支付 APIv3 会用到密钥、证书、公钥这些东西。
一开始很容易混:
APIv3 密钥是自己设置的 32 位字符串。
商户 API 证书是用来证明商户身份的。
微信支付公钥或平台证书是用来验签和解密回调的。
这些东西名字很像,但用途完全不同。
更麻烦的是,它们通常不会在同一个页面完成配置。你可能要在商户平台、产品中心、API 安全、开发配置之间来回切。
我后来给自己定了一个小规则:
凡是支付配置,都不要只看“已设置”,还要确认代码里用的是不是同一套。
有时候后台显示已经设置好了,但服务端环境变量里还是旧值;有时候证书下载了,但代码读的是另一个路径。
这种问题最烦,因为它看起来像接口问题,其实是配置不一致。
第三关:白名单和回调最容易被忽略
公众号和小程序的很多接口都要求 IP 白名单。
支付回调又要求你的服务端地址能被微信访问。
这两个问题经常让人误判。
你本地测试能通,不代表微信服务器能访问到你。
你服务器能访问微信,也不代表微信允许你这个服务器 IP 调接口。
我自己测试公众号草稿箱接口时,就遇到过白名单问题。明明 AppID 和密钥都对,接口还是返回 invalid ip。最后才发现,微信看到的出口 IP 和我以为的不是同一个。
这个经验放到支付上也一样。
如果你接入微信支付,一定要单独检查:
这里的“幂等”很重要。
微信支付回调可能重复通知。服务端不能因为重复回调,就重复记账、重复发货、重复更新状态。
第四关:钱不是只有“支付成功”
如果只是卖一个普通商品,支付成功可能就结束了。
但如果你的业务涉及保证金,事情会复杂很多。
因为钱有状态。
比如我做保证金约定时,就需要区分:
这时候后台如果只显示一个“成功”,其实是不够的。
用户真正关心的是:
钱现在在哪里?下一步谁处理?多久能到账?
所以支付系统不只是调起支付,还要把资金状态设计清楚。
我现在会怎么接入?
如果重新来一次,我会按这个顺序做:
千万不要一上来就把支付、保证金、退款、赔付、后台审核全部混在一起测。
那样一旦失败,你根本不知道是哪一层坏了。
支付接入最稳的方式,是一层一层打通。
写在最后
这次接入微信支付给我最大的感受是:
技术文档里写的是接口,真实开发里遇到的是系统。
代码只是其中一部分。
账号、权限、证书、密钥、白名单、回调、资金账户、用户提示、后台状态,每一块都要对齐,支付链路才算真的跑起来。
如果你也在做小程序支付,建议先别急着写复杂业务。
先用最小金额跑通完整链路。
能支付,能回调,能退款,能查状态,再往业务里接。
这样慢一点,但少掉很多夜里排查问题的时间。
后面我会继续记录 ChainPromise守约的开发过程,包括微信支付、保证金、退款、商家转账和小程序审核里踩过的坑。
ChainPromise守约