mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-06-20 23:29:48 +08:00
104 lines
4.6 KiB
Markdown
104 lines
4.6 KiB
Markdown
|
|
# Plan: 余额支付退款重复退款优化
|
|||
|
|
|
|||
|
|
## 背景
|
|||
|
|
|
|||
|
|
余额支付订单退款当前允许同一订单产生多条钱包进账流水,这是合理的:客户投诉、人工补退、重算补退等场景都可能需要追加退款。
|
|||
|
|
|
|||
|
|
本次优化不采用“一单只能插一次”的唯一约束,而是改为累计金额控制:
|
|||
|
|
|
|||
|
|
- 同一订单余额退款可以多次发生。
|
|||
|
|
- 累计退款金额不能超过该订单余额支付金额。
|
|||
|
|
- 自动结算重复执行时,只能退到订单当前目标退款金额,不能重复按全量退款。
|
|||
|
|
- 钱包余额更新失败时,不能继续插入钱包流水。
|
|||
|
|
|
|||
|
|
## 风险点
|
|||
|
|
|
|||
|
|
### 风险 1:余额退款按全量重算
|
|||
|
|
|
|||
|
|
`balancePaymentOrderRefund` 和 `balancePaymentOrderRefundV2` 当前会按订单支付记录与消费金额重新计算本次退款金额。
|
|||
|
|
|
|||
|
|
如果同一订单已经存在部分退款流水,再次执行时没有按“目标退款金额 - 已退金额”计算差额,存在重复退款风险。
|
|||
|
|
|
|||
|
|
### 风险 2:钱包更新失败后仍可能插流水
|
|||
|
|
|
|||
|
|
`MemberBasicInfoServiceImpl.updateMemberBalance` 使用 `version` 更新钱包余额,但当更新返回 `0` 时只打印日志,后续仍可能插入 `member_wallet_log`。
|
|||
|
|
|
|||
|
|
这会造成余额与流水不一致,也会影响后续已退款金额判断。
|
|||
|
|
|
|||
|
|
### 风险 3:balancePaymentOrderRefundV2 无幂等校验
|
|||
|
|
|
|||
|
|
`OrderBasicInfoServiceImpl.balancePaymentOrderRefundV2` 没有已退金额校验,也没有累计退款上限。
|
|||
|
|
|
|||
|
|
重复调用时可能持续向会员钱包退款。
|
|||
|
|
|
|||
|
|
## 优化原则
|
|||
|
|
|
|||
|
|
1. 不限制同一订单只能插入一条退款流水。
|
|||
|
|
2. 同一订单累计余额退款总额不能超过余额支付总额。
|
|||
|
|
3. 自动结算退款以 `order_basic_info.refund_amount` 作为当前目标退款金额;如果需要客户投诉补退,应先把目标退款金额调整到新的业务目标,且不能超过支付总额。
|
|||
|
|
4. 本金与赠送金分别受各自支付金额上限约束。
|
|||
|
|
5. 钱包余额更新与钱包流水必须保持事务一致。
|
|||
|
|
|
|||
|
|
## 子任务
|
|||
|
|
|
|||
|
|
### BR-001
|
|||
|
|
|
|||
|
|
- 优先级:P0
|
|||
|
|
- 状态:done
|
|||
|
|
- 目标:补 `balancePaymentOrderRefundV2` 累计退款上限与差额退款。
|
|||
|
|
- 设计:
|
|||
|
|
- 查询订单已退本金、已退赠送金。
|
|||
|
|
- 订单目标退款金额取 `min(order.refundAmount, balancePayTotal)`。
|
|||
|
|
- 本次退款金额取 `目标退款金额 - 已退总额` 范围内的金额。
|
|||
|
|
- 本金累计退款不能超过本金支付金额,赠送金累计退款不能超过赠送金支付金额。
|
|||
|
|
- 验收:
|
|||
|
|
- 同一订单重复调用 V2,不会超过当前目标退款金额。
|
|||
|
|
- 如果目标退款金额被业务调整变大,可以继续补退,但累计不超过余额支付总额。
|
|||
|
|
|
|||
|
|
### BR-002
|
|||
|
|
|
|||
|
|
- 优先级:P1
|
|||
|
|
- 状态:done
|
|||
|
|
- 目标:统一新旧余额退款逻辑。
|
|||
|
|
- 设计:
|
|||
|
|
- 在 `OrderBasicInfoService` 提供统一的余额退款额度裁剪方法。
|
|||
|
|
- `DelayMerchantProgramLogic.balancePaymentOrderRefund`、`NotDelayMerchantProgramLogic.balancePaymentOrderRefund`、`OrderBasicInfoServiceImpl.balancePaymentOrderRefundV2` 都复用同一套累计上限判断。
|
|||
|
|
- 验收:
|
|||
|
|
- 三条余额支付退款路径的已退金额口径一致。
|
|||
|
|
|
|||
|
|
### BR-003
|
|||
|
|
|
|||
|
|
- 优先级:P2
|
|||
|
|
- 状态:done
|
|||
|
|
- 目标:修复钱包更新事务一致性。
|
|||
|
|
- 设计:
|
|||
|
|
- `updateMemberBalance` 增加事务。
|
|||
|
|
- `memberBasicInfoMapper.updateMemberBalance(...)` 返回 `0` 时抛异常。
|
|||
|
|
- 钱包余额更新失败时不插入 `member_wallet_log`。
|
|||
|
|
- 验收:
|
|||
|
|
- 乐观锁失败时不会产生钱包流水。
|
|||
|
|
|
|||
|
|
### BR-004
|
|||
|
|
|
|||
|
|
- 优先级:P3
|
|||
|
|
- 状态:done
|
|||
|
|
- 目标:补充验证。
|
|||
|
|
- 设计:
|
|||
|
|
- 编译受影响模块。
|
|||
|
|
- 对重复调用、目标退款金额调整、钱包乐观锁失败做回归验证。
|
|||
|
|
- 验收:
|
|||
|
|
- 编译通过,关键路径验证结果记录到本文档。
|
|||
|
|
- 当前进展:
|
|||
|
|
- 使用 JDK 8 执行 `mvn -pl jsowell-pile -am compile -DskipTests` 通过。
|
|||
|
|
- 当前默认 JDK 21 执行 Maven 会在 `jsowell-common` 编译阶段触发老 Lombok/javac 兼容性错误,未进入本次改动编译。
|
|||
|
|
|
|||
|
|
## 执行日志
|
|||
|
|
|
|||
|
|
- 2026-06-15:创建优化方案文档,开始执行 BR-001。
|
|||
|
|
- 2026-06-15:BR-001 已完成,`balancePaymentOrderRefundV2` 接入累计退款额度裁剪。
|
|||
|
|
- 2026-06-15:开始执行 BR-002,统一新旧余额退款路径的累计校验口径。
|
|||
|
|
- 2026-06-15:BR-002 已完成,延迟、非延迟和 V2 余额退款路径复用同一套额度裁剪逻辑。
|
|||
|
|
- 2026-06-15:BR-003 已完成,`updateMemberBalance` 增加事务,钱包余额更新失败时抛异常并阻止插入流水。
|
|||
|
|
- 2026-06-15:开始执行 BR-004,进行编译检查。
|
|||
|
|
- 2026-06-15:BR-004 已完成,JDK 8 环境下受影响模块编译通过。
|