一、引言
订单支付模块是任何交易系统中最核心、最敏感、最容易出问题的部分之一。它不仅涉及资金流转,还关系到系统一致性、安全性与用户体验。
本文将围绕一个典型流程展开深入讲解:
小程序 → 订单服务 → 调用微信支付 → 支付回调 → 更新订单
并进一步扩展到:
如何通过中台网关与支付服务解耦订单模块
二、整体支付流程解析
2.1 标准流程
1. 小程序发起下单
2. 后端创建订单
3. 调用微信支付统一下单接口
4. 小程序调起支付
5. 用户完成支付
6. 微信回调后端(notify)
7. 后端更新订单状态
2.2 架构图
小程序
↓
订单服务
↓
微信支付
↓
支付回调(notify)
↓
订单更新
三、核心模块设计
3.1 订单服务(Order Service)
职责:
- 创建订单
- 校验订单合法性
- 管理订单状态
- 提供查询接口
订单状态建议设计:
| 状态值 | 含义 |
|---|---|
| 0 | 待支付 |
| 1 | 支付中 |
| 2 | 已支付 |
| 3 | 已关闭 |
3.2 支付流程核心逻辑
Step 1:创建订单(事务控制)
BEGIN;
INSERT INTO orders (...)
COMMIT;
关键点:
- 订单号唯一
- 金额由后端计算(严禁前端传)
Step 2:调用微信支付接口
后端调用统一下单接口,返回 prepay_id
Step 3:返回支付参数给小程序
{
"timeStamp": "...",
"nonceStr": "...",
"package": "prepay_id=xxx",
"signType": "RSA",
"paySign": "xxx"
}
Step 4:小程序发起支付
wx.requestPayment({...})
四、支付回调处理(最关键)
4.1 为什么回调是核心?
因为:
支付结果必须以后端回调为准,而不是前端结果
4.2 回调处理流程
微信 → POST notify → 你的服务器
4.3 标准处理逻辑
begin transaction;
// 1. 验签 + 解密
verifySignature();
// 2. 查询订单(加锁)
order = select * from orders where id=? for update;
// 3. 幂等判断
if (order.status == 已支付) {
return SUCCESS;
}
// 4. 校验金额
if (order.amount != notify.amount) {
return FAIL;
}
// 5. 更新订单状态
update orders set status = 已支付;
// 6. 记录支付流水
insert payment_record;
// 7. 提交事务
commit;
五、关键技术点详解
5.1 事务控制
用于保证:
- 更新订单
- 写支付记录
必须同时成功或失败
5.2 行级锁(防并发)
SELECT * FROM orders WHERE id=? FOR UPDATE;
作用:
- 防止重复更新订单
- 保证并发安全
5.3 幂等设计(必须)
原因:
- 微信可能多次回调
解决方案:
如果订单已支付 → 直接返回成功
5.4 金额校验
必须校验:
数据库金额 == 微信返回金额
否则可能被攻击
5.5 签名验证(安全核心)
必须做:
- 验证微信签名
- 解密回调数据
否则:
可以伪造支付成功
5.6 回调接口设计
注意:
- 不要加登录校验
- 必须公网可访问
- 返回固定格式:
{"code":"SUCCESS","message":"成功"}
六、常见问题与解决方案
6.1 重复支付
解决:
- 唯一订单号
- 状态控制
6.2 回调多次
解决:
- 幂等处理
6.3 前端篡改金额
解决:
- 金额只信任后端
6.4 用户支付中断
解决:
- 定时任务关闭超时订单
七、数据库设计建议
7.1 订单表(orders)
order_id
user_id
amount
status
create_time
pay_time
7.2 支付表(payment)
payment_id
order_id
prepay_id
transaction_id
status
callback_time
八、进阶设计:中台网关解耦支付模块
8.1 为什么要解耦?
传统方式:
订单服务 → 直接调用微信支付
问题:
- 强耦合
- 难扩展(接入支付宝困难)
- 支付逻辑混乱
8.2 解耦后架构
小程序
↓
API网关
↓
订单服务 支付服务
↓
微信支付
8.3 模块职责划分
订单服务
- 只管业务
- 不接触支付细节
支付服务
- 调用微信支付
- 处理回调
- 管理支付流水
API网关
- 统一入口
- 鉴权
- 限流
8.4 解耦后的流程
1. 创建订单(订单服务)
2. 发起支付(支付服务)
3. 微信回调(支付服务)
4. 更新订单(订单服务)
8.5 服务间通信方式
方式一:HTTP调用
简单直接,但耦合较高
方式二:消息队列(推荐)
支付成功 → MQ → 订单服务消费
优点:
- 解耦
- 可重试
- 高并发稳定
九、安全设计总结
必须做到:
- ✔ 后端控制金额
- ✔ 验签 + 解密
- ✔ 幂等处理
- ✔ 行级锁
- ✔ 唯一订单号
- ✔ 回调校验
十、总结
订单支付模块的本质是:
在不可信环境中保证资金与订单状态的一致性
基础版:
事务 + 行锁 + 幂等 + 回调验证
进阶版:
订单服务(业务) + 支付服务(资金) + 网关(入口)
最终目标:
高内聚、低耦合、安全可靠、可扩展
如果系统设计得当,即使未来扩展:
- 多支付渠道
- 高并发场景
- 分布式架构
也可以轻松应对。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END






暂无评论内容