订单支付模块设计与实现详解(含微信支付V3与中台解耦方案)

一、引言

订单支付模块是任何交易系统中最核心、最敏感、最容易出问题的部分之一。它不仅涉及资金流转,还关系到系统一致性、安全性与用户体验。

本文将围绕一个典型流程展开深入讲解:

小程序 → 订单服务 → 调用微信支付 → 支付回调 → 更新订单

并进一步扩展到:

如何通过中台网关与支付服务解耦订单模块


二、整体支付流程解析

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
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容