小程序支付后端从零构建:wx.pay 全流程、幂等实践与客户端定位
支付后端从 0 到 1:流程、幂等和那位备胎 提起微信支付,不少后端新同学的第一反应是"这不就是调个 API 嘛"。真上手才发现,光一个异步回调就能把人折腾到怀疑人生:明明用户付了钱,订单状态却一直不更新;回调来了两次,积分发了双份;个人主体小程序连商户号都申请不下来,只能对着文档干瞪眼。 这篇文章把 wx.pay 的后端流程从头到尾拆开:登录拿 openid、统一下单换 prepay_id、二次签名、异步回调验签与解密,再到怎么用乐观锁把幂等做扎实。最后用一点篇幅聊聊"备胎信使"理论——搞明白客户端在支付里到底说了不算什么,很多困惑会迎刃而解。 📌 前置知识:会写 Spring Boot 接口,看得懂 SQL,理解基本的 HTTP 与 JSON。不需要任何支付经验,本文的代码保证从空项目能直接搭起来。 第 1 步 目标说明:这一篇到底讲什么 1.1 为什么写这篇文章 支付是少数几个"看起来简单、出错要命"的领域。某开发者的第一版支付代码只有一百多行,跑起来却发现三个大坑: 客户端调起支付后立刻回调了 success,后端却还没收到微信的异步通知,订单一直挂在"待支付"; 通知重试机制下同一个回调被处理了两次,用户积分翻倍; 本地调得好好的,上线后微信的回调根本进不来——因为内网地址微信访问不了。 这三件事分别对应流程、幂等、回调三个话题,也是本文的主线。提前把这些想明白,能省下大把试错时间。 1.2 小程序开发的"三驾马车" 一个完整的小程序业务,后端主要跟三样东西打交道: 能力 前端 API 后端职责 类比 身份识别 wx.login 用 code 换 openid,建立用户账号 进门刷脸 交易闭环 wx.requestPayment 统一下单、签名、回调处理 柜台结账 消息触达 wx.requestSubscribeMessage + 服务端发送 存 access_token,发订阅消息 售后电话 三者独立又协作:登录建立身份,支付产生交易,订阅消息把交易结果送达用户。 1.3 本文核心议题 围绕上面三驾马车,重点回答四个问题: wx.pay 的完整后端流程是什么?预支付、二次签名、异步回调各是干什么的。 如何保证支付幂等,防止重复扣款、重复加积分? 客户端在支付中到底扮演什么角色?哪些事它说了不算? 个人开发者没有商户资质,怎么照样把后端逻辑练熟? 1.4 阅读本文的收获 读完你会得到一份可以直接抄的 Java 实现:登录接口、统一下单、二次签名、回调处理器,以及一套幂等的三层防御。还会得到一个重要认知:支付后端的核心逻辑与商户号无关,没资质也能先把逻辑写对,拿到商户号只是替换一个 API 地址的事。 ...