Arch Day 47: 清结算系统设计 — 支付链路中"看不见但最关键"的引擎
清算(Clearing)是算账——确定"谁欠谁多少钱";结算(Settlement)是付账——实际完成资金的划转。清结算引擎是支付系统的"后台心脏",对用户不可见,但决定了商户什么时候拿到钱、拿到多少钱。
日期: 2026-05-16 (Day 47) 阶段: 第二阶段 - 金融域深度 标签: #清算 #结算 #轧差 #分账系统 #DDD #资金池管理
核心概念
一句话定义
清算(Clearing)是算账——确定"谁欠谁多少钱";结算(Settlement)是付账——实际完成资金的划转。清结算引擎是支付系统的"后台心脏",对用户不可见,但决定了商户什么时候拿到钱、拿到多少钱。
为什么资深架构师仍需关注
| 维度 | 关注理由 |
|---|---|
| 资金安全 | 清结算直接涉及真金白银的划转,算错一分钱就是事故 |
| 业务复杂性 | 多方分账、退款冲抵、手续费计算、结算周期——业务规则极其复杂 |
| DDD典型域 | 清结算是DDD领域建模的绝佳练习场:有清晰的领域语言和业务规则 |
| 性能挑战 | 日百万笔交易的批量清算,对计算效率和数据库操作有极高要求 |
| 合规约束 | 备付金管理、结算资金隔离、反洗钱检查——每个环节都有监管要求 |
常见误区与反模式
| 误区 | 真相 |
|---|---|
| "清算和结算是同一回事" | 清算是计算(信息流),结算是划款(资金流),两者时间、系统、责任都不同 |
| "T+0结算技术上很简单" | T+0意味着实时结算,需要垫资能力、实时风控、实时记账——远比T+1复杂 |
| "分账就是按比例拆分" | 分账要处理退款回滚、手续费分摊、结算周期不同步等大量边界场景 |
| "清算只是简单的加减法" | 清算涉及轧差、手续费分层计算、跨币种换算、退款冲抵——逻辑极其复杂 |
| "用一张大表就能搞定" | 清结算需要严格的领域模型:清算批次、结算单、资金流水、分账明细各有职责 |
知识点详解
知识点1:清算(Clearing) vs 结算(Settlement) 本质区别
清算 (Clearing) — "算账"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
定义: 对一定周期内的交易进行汇总、轧差、计算各方应收应付
输入: 已完成的交易记录
输出: 清算结果(各方应收/应付金额)
时间: 通常为T+1凌晨批处理
特点: 纯计算,不涉及实际资金移动
结算 (Settlement) — "付账"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
定义: 根据清算结果,实际完成资金从付款方到收款方的划转
输入: 清算结果
输出: 资金到账确认
时间: 清算完成后(可能同日或隔日)
特点: 涉及真实资金移动,需要银行通道
完整流程:
交易完成 → [等待] → 清算(算账) → 结算(付账) → 到账通知
类比理解:
清算 = 月底算工资条(算出每人应发多少)
结算 = 实际发工资到银行卡(真金白银到账)
| 维度 | 清算(Clearing) | 结算(Settlement) |
|---|---|---|
| 本质 | 信息处理(计算) | 资金移动(划款) |
| 时间 | 先执行 | 后执行 |
| 频率 | 每日批处理 | 按周期(T+0/T+1/T+N) |
| 系统 | 清算引擎(内部系统) | 结算系统(需对接银行) |
| 错误影响 | 金额计算错误 | 资金划转错误 |
| 可逆性 | 可重新计算 | 已划款不可逆(需反向操作) |
| 并发要求 | 中(批处理) | 低(顺序执行) |
| 幂等要求 | 高(重跑不重算) | 极高(不能重复打款) |
知识点2:轧差(Netting)机制详解
轧差是清算的核心算法——通过抵消互相抵消的债务来减少实际资金移动量。
场景:一天内的交易
商户A → 平台: 收款100元 (手续费2元)
商户A → 平台: 收款200元 (手续费4元)
商户A → 平台: 退款 50元
平台 → 商户A: 结算
不轧差(逐笔结算):
结算1: 98元 → 商户A
结算2: 196元 → 商户A
退款: 商户A → 50元
= 3笔资金操作
轧差后(净额结算):
净应结 = (100-2) + (200-4) - 50 = 244元
结算: 244元 → 商户A
= 1笔资金操作
效果: 3笔操作 → 1笔操作(减少67%的资金操作量)
轧差类型对比
双边轧差 (Bilateral Netting)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
两方之间互相轧差
A欠B: 100万 A欠B净额: 100-70 = 30万
B欠A: 70万 → B欠A净额: 0
实际只需A付B 30万
多边轧差 (Multilateral Netting)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
多方之间通过中央对手方(CCP)轧差
A欠B: 100 各方净头寸:
B欠C: 80 A: -100+50 = -50 (净付50)
C欠A: 50 B: -80+100 = +20 (净收20)
C: -50+80 = +30 (净收30)
不轧差: 3笔操作,总额230
轧差后: 3笔操作,总额100 (减少57%)
净额结算 (Net Settlement)
━━━━━━━━━━━━━━━━━━━━━━━━━
先轧差后结算(减少资金操作量)
适用: 大部分支付场景
全额结算 (Gross Settlement)
━━━━━━━━━━━━━━━━━━━━━━━━━
逐笔实时结算(不轧差)
适用: 大额支付、实时支付(RTGS)
知识点3:T+N结算周期设计
结算周期时间线
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
T日(交易日) T+1日 T+2日
│ │ │
├─ 交易发生 ├─ 凌晨: 清算跑批 ├─ 资金到账(T+2)
├─ 授权成功 ├─ 上午: 对账确认 │
├─ 状态更新 ├─ 下午: 结算打款 │
│ ├─ T+1到账(快) │
│ │ │
▼ ▼ ▼
不同结算周期的对比
| 维度 | T+0(实时) | T+1(次日) | T+2(隔日) |
|---|---|---|---|
| 到账时间 | 交易完成即到 | 次日到账 | 后天到账 |
| 商户体验 | 极好 | 好 | 一般 |
| 风险控制 | 低(无缓冲期) | 中(1天缓冲) | 高(2天缓冲) |
| 资金成本 | 高(需垫资) | 中 | 低 |
| 退款处理 | 复杂(已到账) | 可冲抵 | 可冲抵 |
| 适用场景 | 线下商户、外卖 | 电商、SaaS | 跨境、大额 |
| 架构复杂度 | 高 | 中 | 低 |
T+0的架构挑战
T+0实时结算的特殊要求
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 垫资能力
├── 问题: 通道资金T+1才到平台,但商户要求T+0
├── 方案: 平台用自有资金垫付
└── 风险: 资金链压力,商户跑路风险
2. 实时风控
├── 问题: 没有缓冲期无法事后拦截
├── 方案: 交易前实时风控评估
└── 规则: 大额延迟结算、新商户限制T+0
3. 退款处理
├── 问题: 钱已经结算给商户,用户要退款
├── 方案A: 从商户下一笔结算中扣除
├── 方案B: 从商户保证金中扣除
└── 方案C: 追回(最差情况)
4. 对账挑战
├── 问题: T+0结算后,T+1对账发现差异
├── 方案: 预留差异处理机制
└── 规则: 差异金额从后续结算中补扣
知识点4:资金池管理
支付平台资金池结构
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌─────────────────────────────────────────┐
│ 总资金池 │
│ │
│ ┌───────────┐ ┌───────────┐ │
│ │ 待结算资金 │ │ 已结算资金 │ │
│ │(通道→平台 │ │(已付给商户) │ │
│ │ 尚未付商户) │ │ │ │
│ └───────────┘ └───────────┘ │
│ │
│ ┌───────────┐ ┌───────────┐ │
│ │ 保证金 │ │ 手续费 │ │
│ │(商户缴纳 │ │(平台收入) │ │
│ │ 用于退款 │ │ │ │
│ │ 兜底) │ │ │ │
│ └───────────┘ └───────────┘ │
│ │
│ ┌───────────┐ ┌───────────┐ │
│ │ 备付金 │ │ 营销资金 │ │
│ │(央行监管 │ │(营销活动 │ │
│ │ 集中存管) │ │ 红包/补贴) │ │
│ └───────────┘ └───────────┘ │
└─────────────────────────────────────────┘
资金流转:
用户付款 → 通道 → 平台待结算池 → 清算计算 → 结算到商户
↓
扣除手续费 → 手续费池
扣除保证金 → 保证金池
关键原则:
├── 商户资金和平台自有资金必须严格隔离
├── 备付金100%集中存管于央行(中国大陆监管要求)
├── 资金池余额和账务系统余额必须实时一致
└── 每日对账确认资金池状态
知识点5:清结算引擎DDD领域模型
清结算引擎领域模型 (DDD)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Bounded Context: 清结算上下文 (Clearing & Settlement Context)
Aggregate 1: ClearingBatch (清算批次 - 核心聚合根)
├── batchId: string // 清算批次号
├── batchDate: Date // 清算日期
├── status: BatchStatus // CREATED→RUNNING→COMPLETED→CONFIRMED
├── merchantId: string // 商户号
├── channelCode: string // 通道编码
├── settleType: SettleType // T+0/T+1/T+2
│
├── 收入侧
│ ├── totalPayAmount: Money // 总收款金额
│ ├── totalPayCount: number // 总收款笔数
│ ├── totalRefundAmount: Money // 总退款金额
│ └── totalRefundCount: number // 总退款笔数
│
├── 费用侧
│ ├── channelFee: Money // 通道手续费
│ ├── platformFee: Money // 平台服务费
│ └── otherFee: Money // 其他费用
│
├── 结果
│ ├── netSettleAmount: Money // 净结算金额
│ │ = totalPayAmount - totalRefundAmount - channelFee - platformFee
│ └── clearingDetails: ClearingDetail[]
│
└── 领域事件
├── ClearingBatchCreated
├── ClearingBatchCompleted
└── ClearingBatchConfirmed
Aggregate 2: SettlementOrder (结算单)
├── settlementId: string // 结算单号
├── clearingBatchId: string // 关联清算批次
├── merchantId: string
├── settleAccount: BankAccount // 结算账户信息
├── settleAmount: Money // 结算金额
├── status: SettleStatus // PENDING→PROCESSING→SUCCESS→FAILED
├── bankChannelRef: string // 银行打款流水号
└── 领域事件
├── SettlementCreated
├── SettlementProcessing
├── SettlementSucceeded
└── SettlementFailed
Aggregate 3: FundMovement (资金流水)
├── movementId: string
├── fromAccount: string // 源账户
├── toAccount: string // 目标账户
├── amount: Money
├── movementType: MovementType // PAY_IN/SETTLE_OUT/FEE/REFUND
├── relatedOrderId: string // 关联业务单号
├── status: MovementStatus
└── createdAt: DateTime
Value Object: Money
├── amount: BigDecimal // 金额(用BigDecimal避免精度问题)
├── currency: Currency // 币种
└── 规则: 所有金额计算使用Money对象,禁止直接使用float/double
知识点6:分账系统设计
电商平台、O2O等场景需要将一笔收款分给多个参与方。
分账场景示例:外卖订单
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
用户支付: 50元
分账规则:
├── 商家: 50 × 70% = 35元
├── 骑手: 50 × 15% = 7.5元
├── 平台: 50 × 10% = 5元
├── 平台手续费: 50 × 3% = 1.5元
└── 营销基金: 50 × 2% = 1元
= 50元(必须精确等于原始金额)
分账模型设计:
┌───────────────────────────────────────┐
│ SplitRule (分账规则) │
│ │
│ ruleId: string │
│ merchantId: string │
│ ruleName: string │
│ splitItems: │
│ ├── {receiverId: "商家A", │
│ │ type: RATIO, │
│ │ ratio: 0.70} │
│ ├── {receiverId: "骑手池", │
│ │ type: RATIO, │
│ │ ratio: 0.15} │
│ ├── {receiverId: "平台收入", │
│ │ type: RATIO, │
│ │ ratio: 0.10} │
│ ├── {receiverId: "手续费", │
│ │ type: RATIO, │
│ │ ratio: 0.03} │
│ └── {receiverId: "营销基金", │
│ type: REMAINDER} ← 兜底接收方 │
│ │
│ 注意: 最后一个用REMAINDER,解决精度问题 │
│ 实际金额 = 总额 - 其他所有方之和 │
└───────────────────────────────────────┘
分账时序:
1. 交易完成 → 记录分账规则快照(交易时刻的规则)
2. 清算批次 → 按分账规则计算各方金额
3. 结算执行 → 分别打款到各接收方
退款场景的分账回滚:
原交易: 50元 → [商家35, 骑手7.5, 平台5, 手续费1.5, 营销1]
退款: 50元 → 从各方按原比例扣回
├── 商家扣回35元
├── 骑手扣回7.5元(从骑手待结算池中扣除)
├── 平台扣回5元
├── 手续费扣回1.5元
└── 营销扣回1元
部分退款: 20元 → 按原比例计算
├── 商家扣回14元 (20×70%)
├── 骑手扣回3元 (20×15%)
└── ...
知识点7:清算引擎核心流程
清算引擎每日批处理流程
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 1: 数据准备 (00:00 - 00:30)
├── 获取清算日期范围内的已完成交易
├── 获取退款交易
├── 获取手续费配置
└── 锁定清算批次(防止重复跑批)
Step 2: 分组汇总 (00:30 - 01:00)
├── 按 [商户+通道+结算周期] 分组
├── 汇总各组的收款总额、退款总额、笔数
└── 生成ClearingBatch记录
Step 3: 费用计算 (01:00 - 01:30)
├── 计算通道手续费 = 收款金额 × 通道费率
├── 计算平台服务费 = 收款金额 × 平台费率
├── 计算其他费用(如分账手续费)
└── 注意: 退款的手续费是否退回,取决于业务规则
Step 4: 轧差计算 (01:30 - 02:00)
├── 净结算金额 = 总收款 - 总退款 - 总手续费
├── 处理特殊情况:
│ ├── 净结算为负数 → 从保证金扣除或挂账
│ ├── 跨周期退款 → 从当期结算中冲抵
│ └── 最小结算金额 → 低于阈值不结算,累积到下期
└── 生成结算单(SettlementOrder)
Step 5: 结果校验 (02:00 - 02:30)
├── 总收款 = 各商户结算总和 + 总手续费 + 总退款
├── 借贷平衡检查
├── 与对账结果交叉验证
└── 异常标记和告警
Step 6: 生成结算指令 (02:30 - 03:00)
├── 将结算单转化为银行打款指令
├── 按银行通道分批
├── 加入打款队列
└── 等待结算执行
对比分析
清结算架构方案对比
| 维度 | 逐笔实时结算 | 日批量清结算 | 混合模式 |
|---|---|---|---|
| 适用场景 | T+0商户 | T+1/T+2商户 | 多种结算周期并存 |
| 实时性 | 秒级 | 日级 | 按商户配置 |
| 计算复杂度 | 低(单笔计算) | 中(批量汇总) | 高(两套逻辑) |
| 资金效率 | 低(逐笔划转) | 高(轧差后净额) | 中 |
| 垫资压力 | 高 | 无 | 中 |
| 退款处理 | 复杂 | 简单(冲抵) | 按场景处理 |
| 推荐 | 外卖/线下 | 电商/SaaS | 综合平台 |
分账系统方案对比
| 方案 | 实时分账 | 延迟分账 | 清算时分账 |
|---|---|---|---|
| 时机 | 交易成功即分 | 交易完成后定时 | 清算批次中计算 |
| 优势 | 各方实时可见 | 可处理退款冲抵 | 统一管理、效率高 |
| 劣势 | 退款回滚复杂 | 延迟高 | 实时性差 |
| 适用 | 简单二方分账 | 含退款的场景 | 多方复杂分账 |
架构设计实操
设计目标
设计清结算引擎的DDD领域模型和核心清算流程。
清结算引擎架构图
┌─────────────────────────────────────────────────────────┐
│ 清结算引擎架构 │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 调度层 (Scheduler) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │定时任务 │ │手动触发 │ │补跑触发 │ │ │
│ │ │(Cron) │ │(Admin) │ │(Rerun) │ │ │
│ │ └─────┬────┘ └─────┬────┘ └─────┬────┘ │ │
│ └────────┼──────────────┼──────────────┼──────────┘ │
│ └──────────────┼──────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 清算层 (Clearing Layer) │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │交易汇总 │→│费用计算 │→│轧差计算 │ │ │
│ │ │Aggregator│ │FeeCalc │ │Netting │ │ │
│ │ └──────────┘ └──────────┘ └─────┬────┘ │ │
│ │ ┌──────────┐ ┌──────────┐ │ │ │
│ │ │分账计算 │ │校验引擎 │←───────┘ │ │
│ │ │SplitCalc │ │Validator │ │ │
│ │ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 结算层 (Settlement Layer) │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │结算指令 │→│打款执行 │→│结果确认 │ │ │
│ │ │Generator │ │Executor │ │Confirmer │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 账务层 (Ledger Layer) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │记账引擎 │ │余额管理 │ │流水查询 │ │ │
│ │ │Posting │ │Balance │ │Statement │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
ADR-047:清算采用批处理+事件驱动混合模式
| 项目 | 内容 |
|---|---|
| 决策 | 日常清算采用批处理(T+1凌晨跑批),T+0实时结算采用事件驱动 |
| 状态 | 已采纳 |
| 上下文 | 平台同时支持T+0和T+1两种结算周期的商户 |
| 方案A | 全部批处理(T+0商户也攒到凌晨算) |
| 方案B | 全部事件驱动(每笔交易实时清算) |
| 方案C | 混合模式 ✓ |
| 决策理由 | T+1占80%交易量,批处理效率高且逻辑集中;T+0占20%,单笔金额可控,适合事件驱动实时处理 |
| 权衡 | 需要维护两套清算逻辑,但复杂度可控;统一的账务层保证数据一致 |
| 后果 | T+0清算路径需要额外的实时风控和垫资管理 |
AI增强实践
AI在清结算中的应用
AI增强的清结算系统
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 智能费率优化
├── 分析商户交易模式,推荐最优费率方案
├── 预测商户交易量增长,提前调整阶梯费率
└── 识别费率套利行为(如拆单降费率)
2. 异常清算检测
├── 识别异常清算结果(金额突增/突降)
├── 检测分账比例异常(与历史不符)
└── 预警潜在的资金风险
3. 智能对账差异分析
├── 自动分类差异原因(时间偏移/金额不符/笔数不符)
├── 推荐差异处理方案
└── 学习历史差异处理经验
4. 结算预测
├── 预测商户资金需求(辅助T+0垫资决策)
├── 预测结算高峰时间(优化银行通道调度)
└── 预测退款冲抵金额(辅助资金池管理)
Prompt示例
Prompt: 我正在设计一个电商平台的分账清结算系统,场景如下:
- 一笔100元订单,需要分给:商家70%、平台20%、物流10%
- 支持部分退款(如退30元,只退商品部分,物流费不退)
- 商家T+1结算,平台T+0入账,物流T+7结算
- 各方结算周期不同,如何设计清算批次?
请帮我设计:
1. 分账规则的领域模型
2. 部分退款时的分账回滚逻辑
3. 不同结算周期的清算批次管理方案
4. 关键的边界场景和处理规则
与Web3/DeFi的关联
传统清结算 vs DeFi清结算
| 维度 | 传统清结算 | DeFi清结算 |
|---|---|---|
| 清算 | 批量(T+1)、中心化清算所 | 实时、每笔交易链上结算 |
| 结算 | T+1~T+3、银行通道 | 区块确认即结算(秒~分钟) |
| 轧差 | 多边轧差减少资金操作 | 无需轧差(每笔原子结算) |
| 分账 | 清算时计算、结算时执行 | 智能合约自动分配(如NFT版税) |
| 对账 | 三方对账(平台/通道/银行) | 链上数据=唯一真相源 |
| 争议 | 拒付/仲裁机制 | 无法逆转(除非合约层设计) |
DeFi中的"清结算"
Uniswap中的"清结算":
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
传统模式: 下单→授权→清算→结算 (分步骤,异步)
Uniswap: swap()函数一次调用 = 授权+清算+结算 (原子操作)
这就是为什么DeFi不需要"对账"——
每笔交易的状态在链上是确定性的,不存在"中间状态"的一致性问题。
但DeFi的新挑战:
├── MEV导致的结算价格偏差(类似于传统的滑点)
├── 跨链交易的最终性问题(不同链的确认速度不同)
└── L2到L1的提现周期(Optimistic Rollup需要7天挑战期)
今日思考
深度问题1:为什么全球大部分支付仍然是T+1结算,而不是实时?
核心原因有三:(1)风控缓冲——T+1给了一个时间窗口来处理欺诈、退款、争议,实时结算意味着资金无法追回;(2)资金效率——批量轧差后净额结算,大幅减少了跨行资金划转的次数和成本;(3)运营成本——实时结算需要实时对账、实时风控、实时异常处理,运营复杂度指数级增长。
深度问题2:分账系统中精度问题如何处理?
经典问题:100元按33.33%分3份,33.33+33.33+33.33=99.99,差了0.01元。解决方案是指定一个"兜底方":前N-1方按比例精确到分,最后一方=总金额-前N-1方之和。这样保证分账总额精确等于原始金额。在代码中,所有金额使用BigDecimal(或整数-分为单位),绝对禁止float/double。
深度问题3:如果清算跑批失败了怎么办?
设计要求:(1)幂等——清算批次可重复执行,结果不变(通过batch_id去重);(2)断点续跑——记录处理进度,失败后从断点恢复而非从头开始;(3)手动补跑——提供管理后台支持手动触发指定日期的清算;(4)告警——跑批异常立即告警运维,且自动阻止结算执行(没算清楚不能打款)。
面试题准备
题目1:清算和结算有什么区别?
30秒回答
清算是"算账"——汇总交易、计算轧差、确定各方应收应付金额,是信息层面的处理。结算是"付账"——根据清算结果,实际完成资金从一方到另一方的划转。通常先清算后结算,清算在凌晨批处理完成,结算在工作日执行。
2分钟回答
(详细展开清算、结算的定义、关系、时序、系统差异,参见知识点1中的完整对比表和流程描述。)
追问准备
- 追问1:T+0和T+1对架构有什么不同要求?→ T+0需要实时清算路径、垫资能力、实时风控;T+1可以批处理、轧差净额结算、有缓冲期处理退款
- 追问2:轧差是什么?有什么好处?→ 抵消互为债务方的金额,减少实际资金操作量和成本
题目2:如何设计一个分账系统?
30秒回答
分账系统核心是三个模型:分账规则(定义各方比例)、分账明细(每笔交易的具体分配)、分账结算(各方的结算执行)。关键设计点:规则快照(交易时锁定规则避免后续变更影响)、精度处理(兜底方吃差额)、退款回滚(按原比例反向扣回)。
2分钟回答
分账系统我会分四层设计。
第一层,规则层。定义分账规则:按比例/按固定金额/混合模式。支持多级分账(平台→商家→供应商)。规则在交易时快照保存,防止规则变更导致历史分账异常。
第二层,计算层。在清算时根据分账规则计算每笔交易的分配结果。关键处理:精度问题用"兜底方"解决;手续费分摊(按比例还是固定方承担,可配置)。
第三层,结算层。各参与方可能有不同的结算周期。商家T+1,平台T+0,供应商T+7——需要独立管理各方的结算批次。
第四层,退款层。部分退款时,按原分账比例计算各方应退金额。全额退款时,完全回滚原分账结果。已经结算的金额,从下一笔结算中扣除或从保证金中扣除。
学习资源
| 资源 | 类型 | 推荐理由 |
|---|---|---|
| 《支付方法论》 | 书籍 | 国内支付清结算的经典著作 |
| Stripe的Balance Transaction文档 | 文档 | 清结算API设计的最佳实践 |
| DDD实战:支付领域建模 | 文章 | 清结算领域模型的DDD实践 |
| BIS CPMI报告 | 报告 | 全球支付基础设施的权威分析 |
明日预告
Day 48: 对账系统设计 — 清结算完成后,如何确认"算的对不对"?核心话题:三级对账体系(交易对账→资金对账→总分核对)、对账引擎的匹配算法、差错处理流程(长款/短款/金额不符)、大数据量对账的性能优化。对账是支付系统"最后的防线"。