架构设计第二篇:支付模块架构设计

支付模块要解决的问题

用户发起支付

系统创建支付单

调用第三方支付渠道

接收支付结果通知

同步支付状态给订单模块

退款、对账、补单、风控

可分为如下子模块:

1、支付网关层。给上游的订单系统提供统一接口,如创建支付单接口、查询支付状态接口、申请退款接口、查询退款状态接口。

2、支付核心服务。负责支付业务主流程,如生成支付单、维护支付状态机、幂等控制、调用渠道路由。

3、渠道适配层。针对微信支付、支付宝支付、苹果内购等做适配,统一封装请求参数、统一返回码转换等,这样后续再新增支付渠道,不用修改主流程。

4、回调处理模块。第三方支付一般都是异步通知最终结果,所以必须要有回调模块。先验签,然后验证商户号、app_id、金额,更新支付单状态,发消息给订单系统。

5、退款模块。退款不是简单调渠道接口,而是一个独立子流程:创建退款单、调渠道退款接口、接收退款回调、更新退款状态、同步退款状态给订单系统。

6、对账补偿模块。支付系统一定要有主动查单、对账文件下载/解析、漏单补单等。

表结构有:

支付单表pay_order:id(支付单号)、request_id(请求id)、order_id(订单号)、out_trade_no(传给渠道的商户订单号,要保证全局唯一)、channel_transaction_id(渠道流水号)、user_id(用户)、pay_amout(支付金额)、pay_channel(支付渠道,微信支付、支付宝支付、苹果内购等)、pay_method(支付场景,app、h5、小程序、pc等)、status(状态)、expire_time(支付单过期时间)、create_time、update_time

退款单表refund_order:id(退款单号)、pay_order_id(支付单号)、order_id(订单号)、channel_transaction_id(渠道流水号)、refund_amount(退款金额)、status(状态)、create_time、update_time

还可以记录与渠道交互的请求响应数据以及渠道回调通知的请求响应数据,用于审计和问题排查,可选。

支付状态机

支付单表状态可选项有INIT、PAYING、SUCCESS、FAIL、CLOSED、REFUNDING、REFUNDED。状态流转要单向、有限,如INIT->PAYING,PAYING->SUCCESS,PAYING->FAIL,PAYING->CLOSED,SUCCESS->REFUNDING,REFUNDING->REFUND。我们在更新状态时,要加where条件,如更新为SUCCESS时,要加where status=INIT。

幂等设计

1、创建支付单时幂等

一次业务操作,只能创建一条支付单。后端根据request_id+order_id建立唯一索引,同时需要订单系统保证超时重试时request_id不变。

2、回调通知幂等

回调通知可能有多次,但只能更新一次。对状态进行条件更新,即update时加上where status='PAYING'条件。

支付一致性的保证

有两个典型问题

1、支付成功了,但是没有回调。

处理方案是在调用渠道接口时,创建一个延迟任务,在30s后去查单,如果渠道返回没有支付成功,则2分钟后再去查,如果还没成功,则10分钟后再查。。。如果一直没成功,临近过期前查最后一次。

2、回调后,支付单更新成功了,但是通知订单系统失败。

处理方案是采用本地消息表+定时任务重试补偿,实现最终一致性。具体做法是在一个本地事务中,执行两个操作,第一是更新支付单表,第二是在本地消息表写一条记录。提交事务后,再通过消息队列投递消息。投递成功的话,修改本地消息表对应记录的状态为成功,否则为失败。同时利用定时任务扫描本地消息表状态为失败的记录,再次投递,投递成功的话,就修改状态为成功,否则一直重试。同时,在订单系统要求实现幂等,根据订单号判断是否已处理,未处理的话,就处理,否则忽略。

对账流程

定期下载渠道账单,与本地支付单核对,找出差异单,自动补单,必要时人工介入。

高并发下的注意事项

1、为减轻数据库压力,要走索引,必要时要读写分离、历史流水归档以及用redis缓存支付单状态。这样,写入qps在5000~10000之间,查询qps能到几十万。

2、回调通知支付成功后,不要同步调用太多下游,如订单、积分、发票、通知,要走消息队列解耦。

 

亿级支付系统的核心优化方向
1. 分库分表
支付单表按业务维度/用户 ID/hash 分表,避免单表热点
读写分离
对退款、流水表也分表
2. 缓存加速热点读
Redis 缓存支付单状态、订单支付状态
3. 分布式事务 / 最终一致性
核心链路(支付成功 → 扣减库存 → 更新账户余额)可设计为 可补偿事务
方案:
本地消息表 + MQ 异步通知
事务消息(RocketMQ / Kafka + Outbox Pattern)
状态机驱动,幂等重试
4. 高可用架构
服务多副本部署,做负载均衡 + 心跳健康检查
MQ 消息集群多副本,保证消息不丢
Redis 采用集群模式
数据库主从多活或跨机房双写(如果要求秒级容灾)
5. 并发控制与限流
订单维度防重:避免重复支付单生成
接口限流:防止洪峰瞬间打垮 DB
队列削峰:前端请求先落队列,逐批写 DB 或调用渠道
6. 异步解耦
支付成功 → MQ → 订单系统、库存系统、风控系统、营销系统
减少同步调用链,降低延迟,提升可用性
7. 日志、监控、补偿
支付单流水 + 渠道流水 + 回调通知 + 消息发送日志全量保存
实时监控支付延迟、回调延迟、失败率
异常补偿机制必须可自动补单

 

posted on 2026-03-21 15:05  koushr  阅读(53)  评论(0)    收藏  举报

导航