## 一、概述与目标 - 标准化账户域三科目:个人余额、劳动报酬、冻结余额;以银行余额为对照。 - 以“狱政交易对象”统一编排冻结/在途/银行交互/补偿,实现端到端一致性与可追溯。 - 覆盖成功、失败、超时、退回、外部入账等全链路场景,形成对账闭环与治理体系。 ## 二、账户模型与不变量 - 科目:个人(可用)、劳动(可用)、冻结(不可用)、银行余额(对照)。 - 不变量:每次动账后校验`个人 + 劳动 + 冻结 = 银行余额(账面)`。 ## 三、交易与状态机 - 对象分工: - 狱政交易:余额校验、冻结/解冻、在途划转、状态机与补偿。 - 银行交易:通道调用与回执。 - 幂等键:JZTxId / BankTxId / SourceKey。 - 状态机:`created → pending → bank_submitted → success | failed | timeout → reversed` ```mermaid stateDiagram-v2 [*] --> created created --> pending: 校验余额/建立在途 pending --> bank_submitted: 发起银行交易 bank_submitted --> success: 银行成功 bank_submitted --> failed: 银行失败 bank_submitted --> timeout: 超时无回执 success --> reversed: 银行退回/业务冲正 failed --> [*] timeout --> success: 对账识别成功 timeout --> failed: 对账识别失败 reversed --> [*] ``` ## 四、资金规则与在途 - 扣款优先级:先个人,后劳动;不足则失败或先冻结。 - 冻结/解冻:仅账户内流转,不触发银行。 - 在途:可用→在途原子划转;成功从在途结转对外,失败/取消在途回退。 ```mermaid flowchart TD A[创建狱政交易] --> B{余额充足?} B -- 否 --> X[拒绝] B -- 是 --> C[可用→在途 划转] C --> D[发起银行交易] D --> E{结果} E -- 成功 --> F[在途→对外 结转] E -- 失败 --> G[在途→可用 回退] E -- 超时 --> H[进入补偿/对账] ``` ## 五、外部入账与退回 - 外部入账:对账单生成SourceKey(流水号+记账日+金额+户名归一化),幂等入账。 - 退回/冲正:success则生成reversed对冲;在途则回退并关闭。 ```mermaid flowchart TD A[对账单项] --> B[生成SourceKey] B --> C{已处理?} C -- 是 --> D[幂等返回] C -- 否 --> E[入账 指定科目] E --> F[来源型交易 success] ``` ```mermaid flowchart TD A[收到银行退回] --> B{原交易状态} B -- success --> C[生成逆向交易reversed] C --> D[可用↑或恢复冻结] B -- 在途/未完成 --> E[在途回退] E --> F[关闭原交易] ``` ## 六、对账与补偿闭环 - 三账:银行账、在途账、总账;目标:`总账 = 银行账 + 在途净额`。 ```mermaid flowchart TD A[拉取银行对账单] --> B[汇总银行账] B --> C[汇总总账] C --> D[汇总在途净额] D --> E{等式是否成立?} E -- 是 --> F[对账通过] E -- 否 --> G[差异分类入队] G --> H[自动纠错] G --> I[人工复核] H --> J[更新账务/关闭差异] I --> J ``` ```mermaid sequenceDiagram participant TO as 狱政交易 participant Bank as 银行 participant RC as 对账服务 TO->>Bank: 发起交易 Bank-->>TO: 无回执(超时) TO->>TO: 标记timeout/入补偿 RC->>Bank: 拉取对账单 Bank-->>RC: 返回明细 RC->>TO: 匹配并更新 TO->>TO: success则在途结转,failed则在途回退 ``` ## 七、并发与幂等 - 同账户串行化/分片锁;状态机转移携带期望状态+version,首次落地为准。 - 全链路重试幂等(JZTxId/BankTxId/SourceKey),队列去重。 ```mermaid flowchart TD A[写入请求] --> B{账户是否持锁?} B -- 否 --> C[获取分片锁] B -- 是 --> D[排队/快速失败] C --> E[读取version] E --> F{期望状态匹配?} F -- 否 --> R[幂等返回] F -- 是 --> G[更新状态 version+1] G --> H[释放锁] ``` ## 八、银行余额同步减少分配 - 以Δ<0为驱动,顺序:个人→劳动→冻结;逐步非负校验,不足则回滚/人工。 ```mermaid flowchart TD A[银行差额Δ<0] --> B["扣个人 min(abs(Δ), 个人可用)"] B --> C{Δ已抵消?} C -- 是 --> Z[结束 校验不变量] C -- 否 --> D["扣劳动 min(剩余Δ, 劳动可用)"] D --> E{Δ已抵消?} E -- 是 --> Z E -- 否 --> F["扣冻结 min(剩余Δ, 冻结余额)"] F --> G{Δ已抵消?} G -- 否 --> X[失败 回滚/人工] G -- 是 --> Z ``` ## 九、治理与运行 - 参数化:通道级超时/重试/退避、扣减优先级、退回归属、冻结期限;配置审计。 - 监控SLA:在途老化、超时率、退回率、差异关闭时延、补偿成功率;限流/熔断/降级。 - 审计与合规:输入/幂等键/状态转移/操作者/签名;关键记录WORM。 - RBAC:角色矩阵与双人复核;敏感操作留痕。 ## 十、日切与迁移 - 账务日与自然日边界;跨日入账与T+1补账归属;错账回滚口径统一。 - 演进:灰度、双写/对比、回滚预案、存量修复脚本与验收标准。 ## 附:在途的状态管理 ### 状态定义 - pending:可用→在途划转已完成,待发起银行或已排队。 - bank_submitted:银行调用已发出,等待回执或对账裁决。 - timeout:超过通道超时阈值未获回执,进入补偿与对账判定。 - success:银行成功,已从在途结转对外(在途余额归零)。 - failed:银行失败,已将在途回退至可用(在途余额归零)。 - reversed:已对成功交易完成逆向冲正(银行退回或业务冲正)。 ### 状态机 ```mermaid stateDiagram-v2 [*] --> pending: 可用→在途 pending --> bank_submitted: 发起银行 bank_submitted --> success: 银行成功 bank_submitted --> failed: 银行失败 bank_submitted --> timeout: 超时无回执 timeout --> success: 对账识别成功 timeout --> failed: 对账识别失败 success --> reversed: 退回/业务冲正 failed --> [*] reversed --> [*] ``` ### 触发事件与转移规则 - submit_bank:从pending到bank_submitted。 - bank_ack_success / bank_ack_fail:从bank_submitted到success/failed。 - timer_expired:从bank_submitted到timeout(由定时器驱动)。 - reconcile_match_success / reconcile_match_fail:从timeout到success/failed(由对账作业驱动)。 - reverse_requested:从success到reversed(银行退回或业务冲正)。**** ### 并发与幂等裁决 - 每次转移携带期望状态与version,服务端校验后version自增;首个成功落地为准,其余并发幂等返回。 - 同账户加分片锁或串行化,避免同一账户在途与可用并发修改冲突。 ### 超时与补偿 - 定时器:通道级超时阈值(可配置),到时触发timer_expired进入timeout。 - 补偿:对账作业周期拉取银行明细,匹配后触发reconcile_match_*事件推进结论。 - 死信:超过最大补偿次数进入死信队列并告警,需人工复核。 ### 回收与审计 - 在途余额只能存在于pending、bank_submitted、timeout三态;进入success/failed/reversed即归零。 - 全链路审计:记录输入参数、幂等键、状态变更、操作者/系统ID、签名与时间戳。 ### 指标与告警 - 在途老化分布、各状态停留时长、timeout占比、补偿成功率、reversed占比。 - 告警阈值:单笔在途超时、批量超时率、补偿失败率、对账差异未关闭时延。