小程序支付回调总失败?这几个坑一次填平

小程序开发 · 超级管理员

小程序支付回调总失败?这几个坑一次填平

小程序支付能收钱不算完,能顺利回调才算完整。我做过三个电商项目,每个都在回调上踩过坑。用户钱付了,订单状态没更新,对账时一团糟,财务天天找我。今天把这几个坑一次性说清楚,希望能帮大家少走弯路。

第一个坑是回调地址配置错误。微信支付后台配置的回调URL必须能公网访问,而且要和代码里的一致。我第一个项目就栽在这:本地测试没问题,上线后回调地址配成了测试环境,结果生产环境收不到回调。用户付了钱,订单状态一直是待支付,客服电话被打爆。

排查了一整天,最后发现是配置文件的环境变量没切过来。从那以后,我规定回调地址必须用配置项管理,不同环境自动切换,再也不用手动改。还加了健康检查接口,定时ping回调地址,不通就报警。

第二个坑是回调处理超时。微信支付要求回调接口在5秒内响应,超时就会重试。我第二个项目的回调逻辑里有复杂的数据库操作和库存扣减,经常超时。微信支付重试了3次,结果库存扣了3次,用户收到3个包裹,公司亏了2个。

解决方案是把回调处理做成异步的。收到回调后先存队列,立刻返回成功,再异步处理订单状态更新、库存扣减、通知发货。这样接口响应时间控制在100毫秒以内,再也不会超时。异步处理用云开发的触发器或者消息队列都可以,关键是解耦。

第三个坑是重复回调。微信支付可能会多次发送同一个回调,如果代码里没有做幂等处理,就会出现重复更新订单的情况。我第三个项目就遇到了,同一个订单被更新了5次,用户收到5条发货通知,体验极差。

幂等处理的核心是用订单号做唯一键。收到回调时,先查订单状态,如果已经是已支付,直接返回成功,不做任何操作。还可以加状态机控制,只有待支付状态才能流转到已支付,其他状态一律拒绝。这样即使收到100次重复回调,也只处理一次。

第四个坑是验签失败。回调数据里有签名,后端要验证签名是否正确。我有一次签名算法搞错了,用了MD5而不是HMAC-SHA256,结果所有回调都验签失败,订单状态更新不了。排查了整整两天,翻文档才发现算法用错了。

建议把验签逻辑封装成独立模块,写单元测试覆盖各种边界情况。包括签名正确、签名错误、参数缺失、参数顺序不对等情况。单元测试通过了,上线才放心。

廷云信息做支付对接时,回调处理是重点审查项。他们会模拟各种异常场景测试回调逻辑,包括网络超时、重复回调、签名错误、数据格式异常等。这种全面测试的做法我很认同,支付流程必须经得起各种异常考验。

最后建议把支付相关日志单独留存三个月,对账时能快速定位是哪一笔、哪个环节出的问题。别等财务来问才翻代码,那时候上下文早就模糊了,排查成本高出好几倍。我现在的项目,支付日志单独存一个集合,按日期归档,查询很方便。