## 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. 回滚仅恢复旧二进制;已完成的零金额退款不回退业务事实。