7.2 KiB
Phase 4: 退款 + 支付 + 运营修复 - Discussion Log
Audit trail only. Do not use as input to planning, research, or execution agents. Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
Date: 2026-03-28 Phase: 04-退款-支付-运营修复 Areas discussed: Plan 分组策略, 退款状态机细节, OPS-01 卡/设备 status=4 触发路径, PAY-04 平台代购的具体场景
Plan 分组策略
| Option | Description | Selected |
|---|---|---|
| REFUND 一个 Plan | DB迁移+Model+Store+Service+Handler+路由全部一次完成 | ✓ |
| REFUND 拆两个 Plan | Plan A: DB迁移+基础层;Plan B: 功能层 |
User's choice: 一个 Plan(推荐)
| Option | Description | Selected |
|---|---|---|
| PAY + OPS 合并一个 Plan | PAY 和 OPS 彼此独立,合并一个 Plan 减少上下文切换 | ✓ |
| PAY 和 OPS 各自独立 | 两个 Plan,粒度更细 |
User's choice: PAY + OPS 合并一个 Plan(推荐)
| Option | Description | Selected |
|---|---|---|
| 内嵌同步(Approve 事务内) | 退款审批和佣金扣减原子,失败可回滚 | ✓ |
| 异步 Asynq 任务 | 入队 TaskTypeRefundCommissionDeduct,审批响应快 |
User's choice: 内嵌同步(推荐)
| Option | Description | Selected |
|---|---|---|
| REFUND-01 先行,再做 REFUND-02+03 | 与 Phase 3 DEVICE 基础层先行规范一致 | ✓ |
| 一次性全部完成 | DB迁移先执行,所有上层代码同时完成 |
User's choice: REFUND-01 先行,再做 REFUND-02+03(推荐)
| Option | Description | Selected |
|---|---|---|
| 不需要,OPS-01 独立实现 | OPS-01 是套餐激活/到期直接更新 status,不经过 StopResumeCallback | ✓ |
| 需要,提前将 CLEAN-06 并入本阶段 | 一并修复 bootstrap 注入 |
Notes: 用户对 CLEAN-06 和 OPS-01 的关系有疑问,确认两者独立后选择不提前。CLEAN-06 保留在 Phase 5。
退款状态机细节
| Option | Description | Selected |
|---|---|---|
| 审批人退回 | 审批人退回申请人(信息不全/待补充等),返回 returned 状态,申请人可重提 | ✓ |
| 申请人自撤回 | 申请人主动撤销,运营后可重提 |
User's choice: 审批人退回(推荐)
| Option | Description | Selected |
|---|---|---|
| RF + 时间戳 + 随机数 | 独立生成,不关联订单号 | |
| 基于订单号迭代 | {order_no}-RF{seq},关联清晰,seq 解决冲突 | ✓ |
User's choice: 基于订单号迭代,冲突解法用 {order_no}-RF{seq}
| Option | Description | Selected |
|---|---|---|
| 允许多次退款 | 同一订单可有多条退款记录,审批退款总额不超过实收金额 | |
| 同时只有一个待处理申请 | 上一次退款完成前不允许新申请 | ✓ |
User's choice: 同一订单同时只能有一个待处理的退款申请(推荐)
| Option | Description | Selected |
|---|---|---|
| 可修改金额 | 审批人可调整 approved_refund_amount,以此为佣金扣减基准 | ✓ |
| 只能审批全额 | 简化 Approve 逻辑 |
User's choice: 可修改金额(推荐)
| Option | Description | Selected |
|---|---|---|
| amount * approvedRefund / actualReceived(int64) | 先乘后除,禁用 float64 | ✓ |
| 先确认字段含义再决定 | — |
Notes: 用户初始想先确认字段含义。解释了 actual_received_amount(实收)/ approved_refund_amount(审批退款额)以及"先乘后除"的整数精度含义后确认使用 int64 算法。
| Option | Description | Selected |
|---|---|---|
| 是,更新 payment_status=4 | 审批通过同时更新订单状态 | ✓ |
| 不更新订单状态 | 退款表独立记录 |
User's choice: 是,更新 payment_status=4
OPS-01 卡/设备 status=4 触发路径
| Option | Description | Selected |
|---|---|---|
| 事务内同步更新 | 套餐激活和卡状态更新原子,失败可回滚 | ✓ |
| 异步 goroutine | 套餐激活后异步更新卡/设备状态 |
User's choice: 事务内同步更新(推荐)
| Option | Description | Selected |
|---|---|---|
| activateNextMainPackage 后检查 active/pending count | 在现有到期处理循环内,激活下一个失败时检查剩余套餐数量 | ✓ |
| 独立轮询任务定期检查 | 新建 Asynq 定时任务扫描无 active 套餐的卡/设备 |
User's choice: 调用 activateNextMainPackage 后检查无剩余 active/pending 套餐(推荐)
| Option | Description | Selected |
|---|---|---|
| 分开更新两张表 | 根据 carrierType 分支到 iot_card/device 各自的 Store | ✓ |
| 统一封装 UpdateCarrierStatus() | 新建封装方法处理两种类型 |
User's choice: 分开更新两张表(推荐)
| Option | Description | Selected |
|---|---|---|
| 直接输出 DB 字段,删除所有映射函数 | DB 存的 payment_status 与管理端完全一致(1/2/3/4) | ✓ |
| 先确认 DB 存在的实际值 | 不确定 DB 值是否真的 1/2/3/4 |
User's choice: 是,直接输出 DB 字段,删除所有映射函数
PAY-04 平台代购的具体场景
| Option | Description | Selected |
|---|---|---|
| 仅 CreateLegacy | 规格书指定 | |
| 仅 CreateAdminOrder | Handler 实际调用的是 CreateAdminOrder,CreateLegacy 已废弃 | ✓ |
Notes: 用户指出 CreateLegacy 已废弃,讨论后确认修改目标为 CreateAdminOrder。规格书中的引用有误,这是本次讨论中最重要的一个勘误。
| Option | Description | Selected |
|---|---|---|
| 资产所属代理的钱包(*resourceShopID) | 平台帮代理买,用代理自己的钱包 | ✓ |
| 平台自己的测试钱包 | 平台先垫付 |
User's choice: 资产所属代理的钱包(*resourceShopID)(推荐)
| Option | Description | Selected |
|---|---|---|
| purchaseRole=purchased_by_platform, operatorType=platform | 使用已有枚举 | ✓ |
| purchaseRole=self_purchase | 按代理自购处理 |
User's choice: purchaseRole=purchased_by_platform, operatorType=platform(推荐)
| Option | Description | Selected |
|---|---|---|
| 与代理自购相同(sellerCostPrice=资产所属代理成本价) | 上下级佣金链照常计算 | ✓ |
| sellerCostPrice=0(不计佣金差) | 平台代购无差价 |
Notes: 用户初始对 sellerCostPrice 含义不清楚,解释了佣金差价逻辑后确认:平台代购等同于代理自购,佣金链正常计算。
the Agent's Discretion
- 富友支付 WxPreCreate 调用时的 goodsDesc 字段内容
- 退款 Store 层具体查询方法实现
- status=3/4 更新时的日志内容
- 富友 DTO 字段命名(参考 WechatPayJSAPIResponse 风格)
Deferred Ideas
None — discussion stayed within phase scope.