2026 2026年1月26日 7 min · 2.2k chars by yxc023
架构小故事-001:保证金模型设计
通过保证金模型设计的实际案例,探索如何在金融系统中平衡风险控制和业务灵活性
一、业务背景
在平台业务中,保证金是平台对商家风险兜底的核心工具。
当同一个商家有多家店铺时,保证金的收取逻辑如下:
阶梯化差额
平台政策规定保证金应根据店铺数量缴纳。
通常第一家店金额较高,后续每家店金额较低。
比如:首家店收 2 万元,后续每家店收 1 万元。
约定灵活性
在线下实际执行时,会出现对特定店铺进行优惠。
例如:第 3 家店减免。
风险追加
当平台认定某些店铺违反规则时,会对保证金进行追加。
最开始模型设计得比较简单。
只记录了每个商家、每个店铺的保证金应收和实收。
但随着业务的发展,以上业务特征逐渐暴露出模型的局限性。 最终引发了严重的清算问题。
二、核心问题
案例引子:同一个退出场景,引发三种答案
典型场景
某商家下有三家店:
- 第 1 店:缴纳 2 万元
- 第 2 店:缴纳 1 万元
- 第 3 店:因特殊政策优惠,仅缴纳 5000 元
冲突点
当第 1 家店(2 万)退出时,应退金额是多少?
这个看似简单的问题,在实际业务中却引发了巨大争议。
不同业务人员给出了三种截然不同的答案:
按店铺维度理解
第 1 店对应 2 万,退出就退 2 万。
按阶梯规则理解
首店退出后,第 2 店变成首店。
按新阶梯,第 2 店应收 2 万。
实际只缴 1 万,需补缴 1 万。
所以只能退 1 万。
按实际缴纳理解
3 店共缴 3.5 万。
退出 1 店后,剩余 2 店按阶梯应收 3 万(2 万+1 万)。
所以应退 5000 元。
三种答案都有道理,却无法达成共识。
这个案例暴露出旧模型存在的两个核心问题:
问题 1:保证金计算规则的逻辑缺失
📋 规则定义 vs 实际记录
| 维度 | 业务规则 | 系统实际记录 |
|---|---|---|
| 定义 | 保证金按店铺数量计算 | 每家店应收多少钱 |
| 范围 | 该商家当前应缴保证金额度 | 每个店的保证金是多少 |
❌ 导致的问题
1. 逻辑偏离
这种记录方式将后续逻辑带偏到”每个店的保证金是多少”。
导致退出场景下出现严重歧义。
2. 规则缺失
更关键的是:旧模型未约定店铺退出时阶梯标准如何重新计算。
这使得”以当前在网店铺数为准”这一原则,在退出场景下无法落地执行。
问题 2:优惠与追加的信息缺失与权属不明
📌 案例延续
第 3 店因特殊政策优惠,仅缴纳 5000 元(假设标准应为 1 万元)。
❌ 系统记录情况
系统只记录了 “第 3 店应收 5000” 这个结果。
❌ 缺失的关键信息
| 缺失项 | 说明 |
|---|---|
| 优惠金额 | 5000 元(标准 1 万 - 实收 5000) |
| 优惠原因 | 为什么优惠? |
| 优惠权属 | 针对第 3 店?还是整个商家? |
⚠️ 造成的后果
这种 信息隐含化 导致退出场景下产生更大的争议。
由于缺乏优惠/追加的明细记录和绑定关系的明确约定:
- ❌ 系统无法追溯原始决策依据
- ❌ 清退时,该”保留”还是”取消”这些额度
- ❌ 全凭人工经验判断
三、设计方案
核心思路:保证金额度与商家余额分离
新模型将**“保证金额度”与”账户余额”**分离管理。
保证金额度
系统根据规则计算的保证金额度。
始终基于**“当前在网店铺数量”与”阶梯标准”**。
并叠加任何优惠或追加额度。
保证金余额
商家实际缴纳的保证金。
设计一:保证金额度的动态计算
保证金额度 = 在网店铺数 × 保证金标准 + 优惠记录 - 追加记录
核心原则
1. 以商家为单位计算
保证金额度是商家整体的概念。
而非每个店铺的简单累加。
2. 实时动态计算
当店铺数量变化时,系统自动重新计算保证金额度。
3. 退出时重算规则
店铺退出后,系统自动按剩余店铺数重新计算阶梯水位。
设计二:优惠与追加的明确记录与绑定
1. 显式记录优惠与追加明细
店铺入驻时,不再只记录”应收金额”。
而是完整记录:
- 优惠金额(优惠了多少,优惠原因)
- 追加金额(追加了多少,追加原因)
- 记录时间、操作人、审批流程
2. 明确绑定属性
每笔优惠或追加必须明确绑定类型:
店铺绑定
针对特定店铺的激励优惠或风险追加。
随店铺生效/失效。
商家绑定
针对商家整体实力的减免或加收。
跟随商家,不随店铺。
推演验证:退出场景的逻辑
步骤一:计算基础保证金额度
根据剩余店铺数量,按阶梯标准计算基础保证金额度。
系统直接按阶梯规则计算,无需识别具体哪家是首店/续店。
步骤二:处理优惠/追加记录
根据绑定属性,叠加或取消优惠/追加记录:
- 绑定在该退出店铺:该优惠/追加同步取消
- 绑定在商家或绑定在其他店铺:继续保留叠加
步骤三:计算退款
最终应退/应补 = 账户余额 - 重算后的保证金额度
四、总结
价值 1:实现与领域模型保持高度一致
旧模型的核心问题是实现与模型脱节:
- 业务模型中有”保证金额度”的概念
- 但实现只记录了”店铺应收金额”
- 丢失了核心概念
业务规则没有明确描述。
只是在制定业务规则的人员心中,导致实现没有依据。
DDD 原则:领域模型是系统的核心,实现必须忠实地反映领域模型。
价值 2:隐式概念显性化
“优惠”在旧模型中是隐含的,只记录结果”应收 5000”。
显式化过程:
| 隐式概念 | 显式建模 |
|---|---|
| 店铺应收金额 | 店铺应收实体(标准金额、优惠金额、实收金额) |
| 优惠归属 | 绑定属性值对象(店铺绑定/商家绑定) |
| 优惠原因 | 优惠记录实体(金额、原因、时间、操作人) |
价值 3:概念澄清、精确化
| 模糊表达 | 精确化表达 |
|---|---|
| “保证金按店铺数量计算” | 保证金额度 = 在网店铺数 × 阶梯标准 + 优惠记录 - 追加记录 |
| “多退少补” | 最终应退/应补 = 账户余额 - 保证金额度 |
领域模型应该使用通用语言(Ubiquitous Language)。
精确的概念定义是消除歧义的基石。
评论