Appearance
信贷业务全景与领域模型
系列首篇。以头部互联网消费信贷(类信用卡分期与消费贷形态)产品的架构视角。先把"一条贷款从生到死"的全程走通。再切限界上下文。最后落两个最容易被做错的模型:额度账户与借据状态机。 姊妹篇:账务系统设计-复式记账与日切、幂等与对账-资金安全底座、风控决策架构、清结算与资方对接。
业务主流程:一条贷款的一生
信贷系统的一切设计都围绕"资金的所有权和时间"展开:钱进来、钱出去、钱占用多久、收不收得回。主流程按贷前/贷中/贷后三段:
贷前(找对人) 贷中(把钱放出去) 贷后(把钱收回来)
┌──────────────┐ ┌────────────────────────┐ ┌────────────────────────┐
│ 获客 → 进件 │ │ 支用申请 → 额度校验 │ │ 还款计划 → 正常还款 │
│ ↓ │ │ ↓ │ │ ↓ (扣款/主动还/提前还) │
│ 反欺诈/风控 │ │ 风控交易决策 → 立借据 │ │ 逾期 → 催收(提醒/外呼) │
│ ↓ │ │ ↓ │ │ ↓ M3+ │
│ 授信审批 │ │ 放款出账(渠道代付) │ │ 代偿/转让 → 核销 │
│ ↓ │ │ ↓ │ │ │
│ 额度生效 │ │ 生成还款计划+首次计息 │ │ 全程伴随: 账务/对账/报表 │
└──────────────┘ └────────────────────────┘ └────────────────────────┘
获客→进件→授信 支用 还款→催收→核销各环节的一句话职责,也是各环节最容易被低估的复杂度:
- 获客:渠道投放、落地页、转化归因——技术上是高并发营销问题,不是资金问题;
- 进件:收集身份/职业/联系人/设备信息,实名 KYC,把"一个自然人"变成系统里的客户号;
- 授信:风控决策(见风控决策架构)给出通过/拒绝/人工 + 额度/定价/期限,产出一份有有效期的授信合同;
- 支用:用户在额度内借钱。一次支用立一张借据(IOU),借据是信贷域最核心的聚合根;
- 还款:按还款计划扣款或主动还款,按冲抵顺序(费用→罚息→利息→本金)分配;
- 催收:逾期后按 D+1/D+7/M1/M2/M3 分案,提醒、外呼、委外;
- 核销:M3+(或按会计政策)仍无法回收,走核销审批把债权从表内转表外。转表外不等于放弃债权,回款了还要回拨。
核心限界上下文划分
按 DDD 切上下文,判断标准是"谁的不变量谁守护":
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ 客户/进件 │ │ 额度 │ │ 支用/借据 │ │ 账务 │ │ 还款 │
│ KYC/实名 │ │ 授信池 │ │ 借据/还款 │ │ 复式记账 │ │ 计划/冲抵 │
│ 聚合:客户 │ │ 聚合:额度 │ │ 计划/放款 │ │ 分录/科目 │ │ 聚合:还款 │
└────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘
│ │ │ │ │
└────────────┴──────┬──────┴─────────────┴─────────────┘
▼
┌────────────────────┐ ┌─────────┐
│ 催收(案件/分案/委外) │ │ 清结算 │──▶ 资方/渠道(外部)
└────────────────────┘ └─────────┘- 额度上下文:守护"可用额度不能为负"的不变量,管授信池的生效/失效/调额;
- 支用上下文:守护借据状态机的合法迁移,拥有借据与还款计划(计划属于借据,不独立成上下文);
- 账务上下文:守护"借贷必相等",只认分录不认业务语义。它甚至不知道"借据"是什么,这是它能对一切业务中立的根源(见账务系统设计-复式记账与日切);
- 还款上下文:守护"冲抵顺序"和"还款金额 ≤ 应还";
- 上下文之间只走事件与防腐层:放款成功后账务记分录、还款成功后额度释放。都是事件驱动 + 对账兜底,不做跨上下文的强一致大事务。取舍逻辑见分布式事务解决方案(总纲)——资金链路选最终一致 + 对账,而不是 TCC 硬锁。
把上下文之间的协作画成事件流,主链路是四个领域事件驱动的接力:
授信生效事件 ──▶ 额度域: 创建额度账户(total>0)
支用成功事件 ──▶ 账务域: 记放款分录 ──▶ 借据域: 立借据 ACTIVE
还款成功事件 ──▶ 账务域: 记还款分录 ──▶ 借据域: 冲抵应还 ──▶ 额度域: 释放已用
逾期切换事件 ──▶ 催收域: 立案件分案 ──▶ 账务域: 罚息起算| 事件 | 发布方 | 订阅方 | 语义 |
|---|---|---|---|
| 授信生效 | 授信流程 | 额度 | 额度池可占用 |
| 支用成功 | 支用域 | 账务/借据/额度 | 钱出去了、债权成立 |
| 还款成功 | 还款域 | 账务/借据/额度 | 冲抵 + 释放占用 |
| 逾期切换 | 计息日终批 | 催收/账务 | 罚息起算 + 分案 |
事件的消费全部幂等(事件带业务单号,消费侧唯一约束/CAS 兜底)。消费失败重投,长期失败进对账差异。这套兜底体系展开见幂等与对账-资金安全底座。
额度与余额的账户模型
额度是"可以被占用的承诺",模型必须把"占用的中间态"表达出来,这就是三分模型:
| 字段 | 含义 | 谁有权改 | 变更时机 |
|---|---|---|---|
| total | 授信总额度 | 授信审批/调额流程 | 授信生效、提额/降额、额度到期 |
| frozen | 冻结额度 | 支用/营销预占 | 支用申请冻结 → 放款确认转已用 / 失败解冻 |
| used | 已用额度 | 放款确认/还款回退 | 放款成功 +支用额,还款结清本金 −归还额 |
| available | 可用 = total − used − frozen | (推导值) | 不允许任何单方直改 |
核心不变量:used + frozen ≤ total,且三者 ≥ 0。这四行表就是额度域的全部宪法,任何绕过它直接 UPDATE 余额的代码都是违宪。
用三分而不用"一个余额"直接扣,原因:支用是两阶段的:
申请: frozen += X (预占,可能出现失败,要能退回)
放款: frozen -= X (确认)
used += X (落借据、出账)
失败/超时: frozen -= X (解冻,available 恢复)如果只有"余额"一个数,申请时直接扣,放款失败要"加回去"。加回时额度可能已被调额/到期,就出现凭空造额度或凭空气额度。冻结段让"未决"显式存在,对账时 frozen > 0 超过 N 分钟 的单子就是悬挂单,有明确的巡检语义。
并发控制:额度行的扣减是热点(一个用户的多次支用、放款与还款并发)。用 UPDATE ... SET frozen = frozen + X WHERE id = ? AND total - used - frozen >= X 的条件更新,影响行数为 0 即额度不足。这与支付回调里 CAS 状态机是同一思想:把业务判断压进 WHERE 子句,靠数据库行锁串行化热点。同款实战拆解见支付回调的HMAC验签与幂等设计。
借据生命周期状态机
借据是"用户欠我方(及资方)一笔钱"的法律与技术双重载体,状态机必须单向、可追溯:
┌──────────── 结清(全部应还清零) ────────────┐
▼ │
ACTIVE(正常/放款成功) ──逾期(D+1 未还当期)──▶ OVERDUE(逾期) ──结清──▶ SETTLED(已结清)
│ │
│提前还款(结清)──────────────────────────▶ SETTLED
│ │ M3+/会计政策审批
│ ▼
└── 放款失败/当日撤单 ──▶ CANCELED(已撤销) CHARGED_OFF(已核销,表外)
│
│ 债权转让
▼
TRANSFERRED(已转让)- 每条边唯一触发者:逾期由日终批切(计息批跑完仍未还当期)。结清由还款冲抵完成触发,核销由核销审批流触发。状态迁移永远由领域事件驱动,不允许接口直接"改状态";
- SETTLED 是唯一正常终态,CHARGED_OFF/TRANSFERRED 是资产处置态:核销后回款走表外回拨,转让后借据只读、清分对象换人;
- 所有迁移走 CAS:
UPDATE iou SET status = 'OVERDUE' WHERE id = ? AND status = 'ACTIVE'。日终批与用户并发还款赛态:用户先还清,批的 CAS 影响行数为 0,直接跳过。不靠锁、不靠队列顺序,靠状态谓词本身拒绝非法迁移; - 状态伴生证据:迁移时一并回填结清时间/核销审批号这类伴生字段。"状态"和"状态的证据"原子落地——和支付单
paid_at随 CAS 回填是同一个手法。
业界实践参照(样本银行A vs 样本银行B)
样本银行A的数字信贷"310"全链路是本文主流程的公开极限样本。全链路:进件 3 分钟 → 授信 1 秒放款 → 0 人工干预。大数据风控 + 决策引擎 + 实时信贷决策。单笔贷款成本约 2.3 元 [媒体]。逐段对回本文的三段论:
| 样本银行A实践 | 本文对应环节 | 事实要点 | 可信度 |
|---|---|---|---|
| 310 全链路 | 贷前+贷中主流程 | "进件→授信→放款"压成一条实时链路,全程 0 人工干预 | [媒体] |
| 大山雀(卫星遥感信贷) | 贷前·授信的数据源创新 | 遥感影像+深度学习识别种植面积/种类/长势,融合气候/地理/行业景气建模,准确率 93%+;农户手机圈地→遥感验证→纯信用授信,累计服务约 180 万农户 | [媒体] |
| 百灵(交互式风控→2.0 Agent) | 贷中·交互与提额自证 | CV 解析合同/发票/门头照等 26 种凭证;统一智能体服务 4200 万小微 | [媒体] |
| 样本银行A贴(票据)/ 大雁(供应链) | 贷后与生态延伸 | 电票收票/付票/贴现/承兑一站式;图计算+知识图谱覆盖供货/回款/订货/发薪等全环节,1000+ 品牌、千万级小微 | [官方]/[媒体] |
两个映射观察:
- "0 人工"不是取消人工缓冲区,而是把人工能力工作台化。其"定海针"人审工作台使复杂件处理效率提升 20 倍 [媒体]。对应本文灰名单"进人工"环节的 AI 增强形态;
- 2025 年"新 310"(360° 感知 / 1 对 1 专家 / 0 延时)把"3 分钟进件"改写为"360° 感知" [媒体]。主流程骨架未变,但"进件"正被数据前置感知替代。本文"获客/进件"的环节边界会随数据能力移动。
样本银行B: 微粒贷是同一主流程的镜像样本。同为分钟级体验,但对三段论的回答几乎处处相反 [媒体]:
| 对照维度 | 样本银行B(微粒贷) | 样本银行A(310) | 可信度 |
|---|---|---|---|
| 获客入口 | 白名单邀请制:微信/QQ 流量入口、无主动申请入口——获客是"推给谁",不是"谁来申请" | 场景主动进件(码商/农户自己上门) | [媒体] |
| 出资结构 | 联合贷:样本银行B出风控与部分出资,数百家合作银行出资;早期市场惯例约 2:8,2021 年互联网贷款新规要求合作方出资 ≥30% 重塑结构 | 银行自营出资 | [媒体] |
| 产品形态 | 小额分散 + 循环授信(额度内随借随还,单笔敞口有限) | 按经营流水核定的经营性贷款 | [媒体] |
两点映射观察:
- 白名单邀请把本文"贷前找人"改写为"系统找人":进件的前置是模型圈选(谁能看到入口)。授信的第一问从"这笔申请批不批"前移为"这个人要不要邀请"。名单本身成了产品,风险在进件之前就被定价;
- 联合贷让"一张借据背后 N 个资方"成为出厂设置而非架构选型。出资结构写进产品基因。额度占用、借据、账务从第一天就要按资方份额拆分设计(展开见清结算与资方对接)。
追问链
Q1:额度和借据为什么是两个上下文?合不行吗?
不行,因为它们的生命周期和不变量完全不同。额度是"池",多张借据共享,不变量是三分守恒。借据是"笔",不变量是状态机与还款计划的自洽。合并后一次支用要锁整个聚合,放款与还款互相阻塞。拆开后额度域只看到 frozen/used 的增减,根本不知道借据长什么样。
Q2:还款是先动借据还是先动账务? 账务先行原则:资金到账(渠道成功)→ 账务记还款分录 → 事件驱动借据冲抵、额度释放。反过来先改借据后记账,账务失败就会出现"账上说欠、账上没收钱"的账实不符。而对账体系(见幂等与对账-资金安全底座)恰恰要求账务是唯一的资金事实源。
Q3:核销之后用户又还钱了,钱算谁的? 表外回拨:核销只把债权移出表内(会计处理),催收权利保留。回款先进表外回拨科目,再按会计政策确认。所以核销态的借据必须仍能受理还款。状态机里 CHARGED_OFF 不拒绝还款事件,这是新手画状态机最容易漏的一条边。
Q4:这套模型和支付域的支付单是不是一回事? 同构但不同生命周期:支付单是"一笔钱的瞬时事件"(分钟级到终态)。借据是"一段债权的长期状态"(月/年级,每天计息推进)。同构的部分是状态机 + CAS + 幂等三键(详见幂等与对账-资金安全底座里 star-site 支付单与借据的逐条对照)。不同的部分是借据多出"计息推进""还款计划分期""逾期/核销"这些时间维度的状态演化。把支付单模型直接拷过来做借据,会漏掉所有和时间相关的规则。
小结
- 主流程三段论:贷前找人、贷中放钱、贷后收钱,每个环节一个独立的复杂度中心;
- 限界上下文按"不变量归属"切:额度守三分守恒、借据守状态机、账务守借贷相等、还款守冲抵顺序;
- 额度三分(total/used/frozen)把两阶段支用的中间态显式化,条件更新做并发控制;
- 借据状态机单向迁移 + CAS + 伴生证据,和支付单是同构的。信贷域的很多答案可以直接从支付域平移过来。
2026-10 新增(金融信贷域系列)。