From e3ba0641b7261f9becef7a74c88be1d693fb98eb Mon Sep 17 00:00:00 2001 From: Guoqs <123456@jsowell.com> Date: Wed, 17 Jun 2026 09:15:44 +0800 Subject: [PATCH] bugfix balance refund duplicate risk --- ...5-balance-refund-duplicate-optimization.md | 103 +++++++++++++ .../pile/service/OrderBasicInfoService.java | 7 + .../impl/MemberBasicInfoServiceImpl.java | 3 + .../impl/OrderBasicInfoServiceImpl.java | 143 ++++++++++++++++-- .../DelayMerchantProgramLogic.java | 15 +- .../NotDelayMerchantProgramLogic.java | 15 ++ 6 files changed, 272 insertions(+), 14 deletions(-) create mode 100644 docs/plan/2026-06-15-balance-refund-duplicate-optimization.md diff --git a/docs/plan/2026-06-15-balance-refund-duplicate-optimization.md b/docs/plan/2026-06-15-balance-refund-duplicate-optimization.md new file mode 100644 index 000000000..1d83d2843 --- /dev/null +++ b/docs/plan/2026-06-15-balance-refund-duplicate-optimization.md @@ -0,0 +1,103 @@ +# 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 环境下受影响模块编译通过。 diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderBasicInfoService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderBasicInfoService.java index 5e1e18238..8f2e9c7b9 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderBasicInfoService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderBasicInfoService.java @@ -482,6 +482,13 @@ public interface OrderBasicInfoService{ */ BigDecimal getOrderRefundedAmount(String orderCode); + /** + * 计算余额支付订单本次允许退款金额 + */ + Map calculateAllowableBalanceRefund(String orderCode, BigDecimal refundAmount, + BigDecimal principalPay, BigDecimal giftPay, + BigDecimal returnPrincipal, BigDecimal returnGift); + /** * 通过orderCode获取退款明细列表 * @param orderCode diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java index 058d4dbd3..7c5c876d4 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java @@ -35,6 +35,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.*; @@ -213,6 +214,7 @@ public class MemberBasicInfoServiceImpl implements MemberBasicInfoService { * 接收的金额都是正数,通过操作类型判断 充值还是扣减 */ @Override + @Transactional(rollbackFor = Exception.class) public int updateMemberBalance(UpdateMemberBalanceDTO dto) { String memberId = dto.getMemberId(); // 会员id BigDecimal updateGiftBalance = dto.getUpdateGiftBalance() != null ? dto.getUpdateGiftBalance() : BigDecimal.ZERO; // 更新赠送金额 @@ -412,6 +414,7 @@ public class MemberBasicInfoServiceImpl implements MemberBasicInfoService { i = memberBasicInfoMapper.updateMemberBalance(memberId, walletCode, newPrincipalBalance, newGiftBalance, walletInfo.getVersion()); if (i == 0) { log.info("修改用户余额-修改余额失败, memberId:{}", memberId); + throw new BusinessException("", "修改用户余额失败,请重试"); } } // 插入 member_wallet_log 表 diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java index 7f520642e..aee935de0 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java @@ -1584,32 +1584,55 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { public void balancePaymentOrderRefundV2(OrderBasicInfo orderBasicInfo) { // 订单编号 String orderCode = orderBasicInfo.getOrderCode(); + BigDecimal refundAmount = orderBasicInfo.getRefundAmount(); + if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) { + logger.info("balancePaymentOrderRefundV2-退款金额小于等于0,orderCode:{}, 退款金额:{}", orderCode, refundAmount); + return; + } // 订单消费金额 - BigDecimal orderAmount = orderBasicInfo.getOrderAmount(); + BigDecimal orderAmount = orderBasicInfo.getOrderAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getOrderAmount(); // 查支付记录 List payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode); + if (CollectionUtils.isEmpty(payRecordList)) { + logger.info("balancePaymentOrderRefundV2-订单支付记录为空,orderCode:{}", orderCode); + return; + } // Map payRecordMap = payRecordList.stream() // .collect(Collectors.toMap(OrderPayRecord::getPayMode, Function.identity(), (k1, k2) -> k1)); Map> payRecordMap = payRecordList.stream().collect(Collectors.groupingBy(OrderPayRecord::getPayMode)); // 获取本金支付的记录 - List orderPayRecordList = payRecordMap.get(Constants.ONE); - BigDecimal principalPay = orderPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add); + List principalPayRecordList = payRecordMap.get(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue()); + BigDecimal principalPay = null; + if (CollectionUtils.isNotEmpty(principalPayRecordList)) { + principalPay = principalPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add); + } - // 取出本金支付金额 - // BigDecimal principalPay = null; - - // if (principalPayRecord != null) { - // principalPay = principalPayRecord.getPayAmount(); - // } + // 获取赠送金支付的记录 + List giftPayRecordList = payRecordMap.get(OrderPayRecordEnum.GIFT_BALANCE_PAYMENT.getValue()); + BigDecimal giftPay = null; + if (CollectionUtils.isNotEmpty(giftPayRecordList)) { + giftPay = giftPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add); + } // 计算需要退回的金额 - Map returnAmountMap = calculateReturnAmount(principalPay, null, orderAmount); + Map returnAmountMap = calculateReturnAmount(principalPay, giftPay, orderAmount); logger.info("结算订单:{}, 剩余金额退回余额, 订单消费金额:{}, 本金支付金额:{}, 赠送支付金额:{}, 退回金额map:{}", - orderCode, orderAmount, principalPay, null, JSON.toJSONString(returnAmountMap)); + orderCode, orderAmount, principalPay, giftPay, JSON.toJSONString(returnAmountMap)); // 需要退回本金的金额 BigDecimal returnPrincipal = returnAmountMap.get("returnPrincipal"); + // 需要退回赠送金的金额 + BigDecimal returnGift = returnAmountMap.get("returnGift"); + + Map allowableRefundMap = calculateAllowableBalanceRefund(orderCode, refundAmount, + principalPay, giftPay, returnPrincipal, returnGift); + returnPrincipal = allowableRefundMap.get("returnPrincipal"); + returnGift = allowableRefundMap.get("returnGift"); + if (returnPrincipal.compareTo(BigDecimal.ZERO) <= 0 && returnGift.compareTo(BigDecimal.ZERO) <= 0) { + logger.info("balancePaymentOrderRefundV2-订单:{}本次可退金额为0,不执行退款", orderCode); + return; + } // 更新会员钱包/余额退回到钱包 UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder() @@ -1617,6 +1640,7 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { .type(MemberWalletEnum.TYPE_IN.getValue()) // 进账 .subType(MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue()) // 订单结算退款 .updatePrincipalBalance(returnPrincipal) + .updateGiftBalance(returnGift) .relatedOrderCode(orderCode) .build(); memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO); @@ -5618,6 +5642,102 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { return orderBasicInfoMapper.queryRepayOrder(memberId); } + /** + * 计算余额支付订单本次允许退款金额 + */ + @Override + public Map calculateAllowableBalanceRefund(String orderCode, BigDecimal refundAmount, + BigDecimal principalPay, BigDecimal giftPay, + BigDecimal returnPrincipal, BigDecimal returnGift) { + Map resultMap = Maps.newHashMap(); + resultMap.put("returnPrincipal", BigDecimal.ZERO); + resultMap.put("returnGift", BigDecimal.ZERO); + + principalPay = positiveOrZero(principalPay); + giftPay = positiveOrZero(giftPay); + returnPrincipal = positiveOrZero(returnPrincipal); + returnGift = positiveOrZero(returnGift); + + BigDecimal balancePayTotal = principalPay.add(giftPay); + BigDecimal targetRefundAmount = positiveOrZero(refundAmount); + if (StringUtils.isBlank(orderCode) || balancePayTotal.compareTo(BigDecimal.ZERO) <= 0 + || targetRefundAmount.compareTo(BigDecimal.ZERO) <= 0) { + logger.info("余额退款额度裁剪-参数不足,orderCode:{}, 目标退款金额:{}, 余额支付总额:{}", + orderCode, targetRefundAmount, balancePayTotal); + return resultMap; + } + + if (targetRefundAmount.compareTo(balancePayTotal) > 0) { + logger.info("余额退款额度裁剪-orderCode:{}, 目标退款金额:{}大于余额支付总额:{},按余额支付总额限制", + orderCode, targetRefundAmount, balancePayTotal); + targetRefundAmount = balancePayTotal; + } + + Map refundedAmountMap = getBalanceRefundedAmountByCategory(orderCode); + BigDecimal refundedPrincipal = refundedAmountMap.get("refundedPrincipal"); + BigDecimal refundedGift = refundedAmountMap.get("refundedGift"); + BigDecimal refundedTotal = refundedPrincipal.add(refundedGift); + BigDecimal remainingTargetAmount = targetRefundAmount.subtract(refundedTotal); + if (remainingTargetAmount.compareTo(BigDecimal.ZERO) <= 0) { + logger.info("余额退款额度裁剪-orderCode:{}, 目标退款金额:{}, 已退总额:{},不再退款", + orderCode, targetRefundAmount, refundedTotal); + return resultMap; + } + + BigDecimal remainingPrincipalPay = positiveOrZero(principalPay.subtract(refundedPrincipal)); + BigDecimal remainingGiftPay = positiveOrZero(giftPay.subtract(refundedGift)); + + BigDecimal allowedPrincipal = min(returnPrincipal, remainingPrincipalPay, remainingTargetAmount); + remainingTargetAmount = remainingTargetAmount.subtract(allowedPrincipal); + BigDecimal allowedGift = min(returnGift, remainingGiftPay, remainingTargetAmount); + + resultMap.put("returnPrincipal", allowedPrincipal); + resultMap.put("returnGift", allowedGift); + + logger.info("余额退款额度裁剪-orderCode:{}, 目标退款金额:{}, 支付本金:{}, 支付赠送:{}, 已退本金:{}, 已退赠送:{}, 原计算本金:{}, 原计算赠送:{}, 本次本金:{}, 本次赠送:{}", + orderCode, targetRefundAmount, principalPay, giftPay, refundedPrincipal, refundedGift, + returnPrincipal, returnGift, allowedPrincipal, allowedGift); + return resultMap; + } + + private Map getBalanceRefundedAmountByCategory(String orderCode) { + Map resultMap = Maps.newHashMap(); + BigDecimal refundedPrincipal = BigDecimal.ZERO; + BigDecimal refundedGift = BigDecimal.ZERO; + + List walletLogs = memberWalletLogService.getOrderRecord(orderCode, MemberWalletEnum.TYPE_IN.getValue()); + if (CollectionUtils.isNotEmpty(walletLogs)) { + for (MemberWalletLog walletLog : walletLogs) { + String subType = walletLog.getSubType(); + if (StringUtils.isNotBlank(subType) + && !StringUtils.equals(subType, MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue())) { + continue; + } + BigDecimal amount = walletLog.getAmount() == null ? BigDecimal.ZERO : walletLog.getAmount().abs(); + if (StringUtils.equals(Constants.TWO, walletLog.getCategory())) { + refundedGift = refundedGift.add(amount); + } else { + refundedPrincipal = refundedPrincipal.add(amount); + } + } + } + + resultMap.put("refundedPrincipal", refundedPrincipal); + resultMap.put("refundedGift", refundedGift); + return resultMap; + } + + private BigDecimal positiveOrZero(BigDecimal amount) { + if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) { + return BigDecimal.ZERO; + } + return amount; + } + + private BigDecimal min(BigDecimal first, BigDecimal second, BigDecimal third) { + return first.min(second).min(third); + } + /** * 获取订单已退款金额 */ @@ -6735,4 +6855,3 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { return total; } } - diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/DelayMerchantProgramLogic.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/DelayMerchantProgramLogic.java index e835a7243..1e59d4ada 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/DelayMerchantProgramLogic.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/DelayMerchantProgramLogic.java @@ -1076,6 +1076,7 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic { } BigDecimal discountAmount = orderBasicInfo.getDiscountAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getDiscountAmount(); + BigDecimal insuranceAmount = orderBasicInfo.getInsuranceAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getInsuranceAmount(); // 计算需要退回的金额 Map returnAmountMap = calculateReturnAmount(principalPay, giftPay, orderAmount, discountAmount); @@ -1102,14 +1103,14 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic { .build(); // 判断消费金额,如果消费金额 - 折扣金额小于 1 元,则将保险费也进行退回 - if (orderBasicInfo.getOrderAmount().subtract(orderBasicInfo.getDiscountAmount()).compareTo(BigDecimal.ONE) < 0) { + if (orderAmount.subtract(discountAmount).compareTo(BigDecimal.ONE) < 0) { // 判断是否需要退保险费用 boolean checkResult = orderBasicInfoService.checkRefundInsuranceAmount(orderBasicInfo); if (checkResult) { // 退保险, 使用 calculateBalanceRefund 重新计算完整的退款金额(电费退款+保险费退款) // 注意:不能在 calculateReturnAmount 的基础上叠加保险费,因为 calculateReturnAmount 不感知保险费, // 算出的退款金额中已包含保险费部分,叠加会导致保险费被重复退还 - Map refundMap = calculateBalanceRefund(principalPay, giftPay, orderBasicInfo.getOrderAmount(), orderBasicInfo.getDiscountAmount(), orderBasicInfo.getInsuranceAmount()); + Map refundMap = calculateBalanceRefund(principalPay, giftPay, orderAmount, discountAmount, insuranceAmount); BigDecimal refundPrincipal = refundMap.get("returnPrincipal"); BigDecimal refundGift = refundMap.get("returnGift"); BigDecimal returnPrincipalForInsurance = refundMap.get("returnPrincipalForInsurance"); @@ -1121,6 +1122,16 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic { updateMemberBalanceDTO.setUpdateGiftBalance(refundGift.add(returnGiftForInsurance)); } } + + Map allowableRefundMap = orderBasicInfoService.calculateAllowableBalanceRefund(orderCode, refundAmount, + principalPay, giftPay, updateMemberBalanceDTO.getUpdatePrincipalBalance(), updateMemberBalanceDTO.getUpdateGiftBalance()); + updateMemberBalanceDTO.setUpdatePrincipalBalance(allowableRefundMap.get("returnPrincipal")); + updateMemberBalanceDTO.setUpdateGiftBalance(allowableRefundMap.get("returnGift")); + if (updateMemberBalanceDTO.getUpdatePrincipalBalance().compareTo(BigDecimal.ZERO) <= 0 + && updateMemberBalanceDTO.getUpdateGiftBalance().compareTo(BigDecimal.ZERO) <= 0) { + logger.info("balancePaymentOrderRefund-订单:{}本次可退金额为0,不执行退款", orderCode); + return; + } // 统一退款 memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO); diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/NotDelayMerchantProgramLogic.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/NotDelayMerchantProgramLogic.java index 312e0525a..36cb8461f 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/NotDelayMerchantProgramLogic.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/NotDelayMerchantProgramLogic.java @@ -755,6 +755,11 @@ public class NotDelayMerchantProgramLogic extends AbstractProgramLogic { @Transactional(rollbackFor = Exception.class) public void balancePaymentOrderRefund(OrderBasicInfo orderBasicInfo) { logger.info("【{}】-余额支付订单退款start orderBasicInfo:{}", this.getClass().getSimpleName(), JSON.toJSONString(orderBasicInfo)); + BigDecimal refundAmount = orderBasicInfo.getRefundAmount(); + if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) { + logger.info("balancePaymentOrderRefund-退款金额小于等于0,orderCode:{}, 退款金额:{}", orderBasicInfo.getOrderCode(), refundAmount); + return; + } // 订单编号 String orderCode = orderBasicInfo.getOrderCode(); // 订单消费金额 @@ -801,6 +806,16 @@ public class NotDelayMerchantProgramLogic extends AbstractProgramLogic { .updateGiftBalance(returnGift) .relatedOrderCode(orderCode) .build(); + + Map allowableRefundMap = orderBasicInfoService.calculateAllowableBalanceRefund(orderCode, refundAmount, + principalPay, giftPay, updateMemberBalanceDTO.getUpdatePrincipalBalance(), updateMemberBalanceDTO.getUpdateGiftBalance()); + updateMemberBalanceDTO.setUpdatePrincipalBalance(allowableRefundMap.get("returnPrincipal")); + updateMemberBalanceDTO.setUpdateGiftBalance(allowableRefundMap.get("returnGift")); + if (updateMemberBalanceDTO.getUpdatePrincipalBalance().compareTo(BigDecimal.ZERO) <= 0 + && updateMemberBalanceDTO.getUpdateGiftBalance().compareTo(BigDecimal.ZERO) <= 0) { + logger.info("balancePaymentOrderRefund-订单:{}本次可退金额为0,不执行退款", orderCode); + return; + } memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO); // 更新order_pay_record, 解冻部分