All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m40s
44 lines
2.6 KiB
Markdown
44 lines
2.6 KiB
Markdown
## Context
|
|
|
|
见 proposal.md。退款申请创建已允许 0 元金额,但退款通过路径的公共金额校验拒绝 `<= 0`。企微终态消费者和受控人工审批均复用该校验。退款通过事务还会无条件调用钱包回款;代理主钱包回款命令不接受 0 元。
|
|
|
|
## Goals / Non-Goals
|
|
|
|
**Goals:**
|
|
- 让零金额退款在两条通过路径中保持一致的状态推进语义。
|
|
- 避免零金额钱包流水、余额变更或调用资金回款用例。
|
|
- 保持退款、订单、通知及既有后处理的事务与幂等边界。
|
|
|
|
**Non-Goals:**
|
|
- 不允许负数退款金额。
|
|
- 不修改退款申请、企微审批或订单的数据库结构。
|
|
- 不改变非零退款的校验、资金回款和后处理语义。
|
|
|
|
## Decisions
|
|
|
|
### 公共金额校验接受零、拒绝负数
|
|
将公共审批退款金额的下限从“必须大于零”调整为“不得小于零”,继续校验不超过申请金额和订单实收金额。这样企微终态与人工路径不会出现规则漂移。
|
|
|
|
备选方案是在企微消费者单独放行零金额;不采用,因为人工审批仍会拒绝,且重复了金额规则。
|
|
|
|
### 零金额在退款事务内跳过资金回款
|
|
当审批通过金额为零时,退款事务仍更新退款和订单状态、写入审计/通知/既有后处理事件,但跳过 `refundWalletPayment`。非零金额保留原调用。
|
|
|
|
备选方案是让钱包模块接受 0 元退款命令;不采用,因为会创建无资金含义的流水并放宽资金模块的金额不变量。
|
|
|
|
### 已失败的生产决策等待安全重试
|
|
现有 `approval:26:approved` 决策投递已经处于失败待重试,部署后由既有重试机制重新执行;若重试已耗尽,维护者按既有受控运维流程重放同一稳定事件,而不直接修改退款、订单或钱包数据。
|
|
|
|
## Risks / Trade-offs
|
|
|
|
- [0 元退款仍将订单标记为已退款] → 这是业务已确认语义;审计中保留审批退款金额为 0。
|
|
- [遗漏某条通过路径] → 两条路径复用公共校验,并在退款服务公共回款接缝处按金额分支。
|
|
- [旧失败任务已耗尽重试] → 发布后先核验决策投递状态;必要时以稳定事件 ID 受控重放。
|
|
|
|
## Migration Plan
|
|
|
|
1. 发布 API 与 Worker 二进制,不执行数据库迁移。
|
|
2. 维护者核验 `approval:26:approved` 的决策投递是否被重试并成功,以及退款单 `RF20260820170954264700` 是否更新。
|
|
3. 若未自动重试,由维护者受控重放同一审批终态事件并核验未产生 0 元钱包流水。
|
|
4. 回滚仅恢复旧二进制;已完成的零金额退款不回退业务事实。
|