用户点“立即支付”,弹出微信收银台,输密码,完成。前端看着就这么一下,可我们做小程序支付项目时,真正花时间的从来不是这个弹窗,而是弹窗前后那些用户看不见的环节:商户号怎么开、订单怎么下、钱到账后系统怎么知道、退款怎么退、月底账怎么对。

哪一环没想清楚,上线后就会出现“用户付了钱,订单还显示待支付”这种最让客服头疼的投诉。

开发前的准备:商户号和小程序关联

小程序本身不能直接收钱,收款要靠微信支付商户号。准备工作大致有三件:

  • 小程序完成认证,主体是企业或个体工商户;
  • 用同一主体申请微信支付商户号,提交营业执照、结算账户等资料,等审核;
  • 在商户平台把商户号和小程序的 AppID 关联起来,并在小程序后台确认授权。

主体不一致是最常见的卡点,比如小程序挂在 A 公司,商户号却是 B 公司的,关联时就会受限。费率按行业类目和平台规定执行,这里不展开数字,以商户平台显示为准。

商户号开通后,要在商户平台设置 API 密钥、申请 API 证书。这些密钥和证书只能放在服务器端,绝不能写进小程序前端代码,也不要发到聊天群里给开发看。

小程序支付的完整调用流程

把整条链串起来看,小程序支付开发大概是这几步:

  1. 用户在小程序里提交订单,前端把商品、数量等信息发给你自己的后端;
  2. 后端生成自己的订单号,计算金额,调用微信支付的下单接口,拿到预支付交易标识;
  3. 后端用这个标识和密钥生成签名参数,返回给前端;
  4. 前端调用小程序的支付接口,拉起收银台;
  5. 用户支付后,微信支付服务器向你配置的回调地址发送支付结果通知;
  6. 后端验签、解密通知内容,核对金额和订单号后更新订单状态。

有个原则要记住:金额一定由后端计算。前端传来的价格只能参考,否则改个请求参数就能低价下单。

回调和订单状态:最容易出事的地方

小程序支付接口在前端返回“成功”,并不代表钱真的到了。用户可能支付完立刻关掉小程序,网络也可能中断。所以订单状态应该以后端收到并验证过的回调通知为准,而不是以前端回调为准。

处理回调时有几个细节,我们几乎每个项目都会反复检查。回调地址必须是公网能访问的 HTTPS 地址;收到通知先验签,验签不过直接丢弃;同一笔订单的通知可能会重复发好几次,代码要做幂等处理,已经是“已支付”的订单不能再加一次库存扣减或积分;处理完要按文档要求返回成功应答,不然微信支付会继续重试。

还要准备一个兜底:定时任务去主动查询那些长时间“支付中”的订单。回调偶尔会因为服务器重启、证书过期没收到,有查询补偿,就不会出现钱到了订单没变的情况。

小程序支付的退款怎么做

退款同样走后端接口,需要用到商户证书。业务上要先想清楚:谁有权限发起退款,是否支持部分退款,一笔订单能退几次。退款也是异步的,提交成功只代表申请受理,最终结果要看退款通知或者主动查询。

我们见过一个坑:运营在后台连点了两次退款按钮,系统没做防重,结果发起了两笔退款请求。好在第二笔因为超出可退金额被拒了,但这类按钮一定要加锁或者状态校验。

对账:上线后别忘了这一步

很多团队上线后只看自己系统里的订单,从不和商户平台对账。时间一长,总会有几笔对不上:回调丢失、测试订单没清、退款状态不同步。

建议每天或者每周下载一次小程序支付的交易账单,和自己系统的订单逐笔比对,差异单单独列出来排查。量不大的时候人工看看就行,订单多了再做成自动对账脚本。

上线前必测的几种情况

正式开放小程序支付之前,我们一般会让测试同学走一遍:正常支付、支付中途取消、支付后马上杀掉小程序、重复点击支付按钮、全额退款、部分退款、回调地址临时不可用再恢复。这几种场景都跑通,上线后基本不会出大问题。

结论

微信小程序支付功能的开发,核心不在前端那一个接口,而在后端的下单、回调验签、幂等处理、退款和对账。主体一致、密钥只放服务器、金额后端算、状态以回调为准,这几条守住了,小程序支付就稳了一大半。接口细节和规则以微信支付官方文档的最新版本为准。蔚岚科技承接小程序开发项目,支付、订单和后台管理可以一起做,需要评估方案可以打 18720919319。

常见问题

个人开发者的小程序能接入支付吗?

一般不行。微信支付商户号需要企业或个体工商户主体,个人主体的小程序通常开不了支付能力。

小程序支付开发需要多长时间?

如果商户号已经开好,单纯接入下单和回调,熟练的团队用不了太久;加上退款、对账和后台管理,工期会明显变长。最耗时的往往是商户号审核。

测试支付会真的扣钱吗?

会。微信支付的正式环境是真实扣款,测试时可以用小金额商品,测完再走退款,把退款流程也顺便验证了。

一个商户号能给多个小程序用吗?

可以在商户平台关联多个同主体的 AppID,具体关联规则和数量限制以商户平台为准。

回调收不到通知一般是什么原因?

常见的是回调地址不是 HTTPS、服务器防火墙拦了请求、证书或密钥配置错误导致验签失败。先看服务器日志里有没有请求进来,再逐项排查。