Files
jsowell-charger-web/docs/plan/2026-06-15-balance-refund-duplicate-optimization.md
2026-06-17 09:15:44 +08:00

4.6 KiB
Raw Blame History

Plan: 余额支付退款重复退款优化

背景

余额支付订单退款当前允许同一订单产生多条钱包进账流水,这是合理的:客户投诉、人工补退、重算补退等场景都可能需要追加退款。

本次优化不采用“一单只能插一次”的唯一约束,而是改为累计金额控制:

  • 同一订单余额退款可以多次发生。
  • 累计退款金额不能超过该订单余额支付金额。
  • 自动结算重复执行时,只能退到订单当前目标退款金额,不能重复按全量退款。
  • 钱包余额更新失败时,不能继续插入钱包流水。

风险点

风险 1余额退款按全量重算

balancePaymentOrderRefundbalancePaymentOrderRefundV2 当前会按订单支付记录与消费金额重新计算本次退款金额。

如果同一订单已经存在部分退款流水,再次执行时没有按“目标退款金额 - 已退金额”计算差额,存在重复退款风险。

风险 2钱包更新失败后仍可能插流水

MemberBasicInfoServiceImpl.updateMemberBalance 使用 version 更新钱包余额,但当更新返回 0 时只打印日志,后续仍可能插入 member_wallet_log

这会造成余额与流水不一致,也会影响后续已退款金额判断。

风险 3balancePaymentOrderRefundV2 无幂等校验

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.balancePaymentOrderRefundNotDelayMerchantProgramLogic.balancePaymentOrderRefundOrderBasicInfoServiceImpl.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-15BR-001 已完成,balancePaymentOrderRefundV2 接入累计退款额度裁剪。
  • 2026-06-15开始执行 BR-002统一新旧余额退款路径的累计校验口径。
  • 2026-06-15BR-002 已完成,延迟、非延迟和 V2 余额退款路径复用同一套额度裁剪逻辑。
  • 2026-06-15BR-003 已完成,updateMemberBalance 增加事务,钱包余额更新失败时抛异常并阻止插入流水。
  • 2026-06-15开始执行 BR-004进行编译检查。
  • 2026-06-15BR-004 已完成JDK 8 环境下受影响模块编译通过。