mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-08-14 18:17:31 +08:00
优化余额退款
This commit is contained in:
@@ -75,6 +75,9 @@ public class CacheConstants {
|
|||||||
// 会员余额退款正在进行中
|
// 会员余额退款正在进行中
|
||||||
public static final String MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS = "member_balance_refunds_are_in_progress:";
|
public static final String MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS = "member_balance_refunds_are_in_progress:";
|
||||||
|
|
||||||
|
// 余额支付订单退款锁
|
||||||
|
public static final String ORDER_BALANCE_PAYMENT_REFUND_LOCK = "order_balance_payment_refund_lock:";
|
||||||
|
|
||||||
// 平台测试员
|
// 平台测试员
|
||||||
public static final String PLATFORM_TESTER = "platform_tester:";
|
public static final String PLATFORM_TESTER = "platform_tester:";
|
||||||
|
|
||||||
|
|||||||
@@ -434,6 +434,11 @@ public interface OrderBasicInfoService{
|
|||||||
|
|
||||||
OrderDetail returnUpdateOrderDetail(OrderBasicInfo orderBasicInfo, TransactionRecordsData data);
|
OrderDetail returnUpdateOrderDetail(OrderBasicInfo orderBasicInfo, TransactionRecordsData data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 余额支付订单退款统一入口
|
||||||
|
*/
|
||||||
|
void refundBalancePaymentOrder(OrderBasicInfo orderBasicInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过站点id修改运营商id
|
* 通过站点id修改运营商id
|
||||||
* @param stationId
|
* @param stationId
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import com.jsowell.pile.dto.ningxiajiaotou.NXJTQueryOrdersInfoDTO;
|
|||||||
import com.jsowell.pile.mapper.OrderBasicInfoMapper;
|
import com.jsowell.pile.mapper.OrderBasicInfoMapper;
|
||||||
import com.jsowell.pile.service.*;
|
import com.jsowell.pile.service.*;
|
||||||
import com.jsowell.pile.service.programlogic.AbstractProgramLogic;
|
import com.jsowell.pile.service.programlogic.AbstractProgramLogic;
|
||||||
import com.jsowell.pile.service.programlogic.DelayMerchantProgramLogic;
|
|
||||||
import com.jsowell.pile.service.programlogic.ProgramLogicFactory;
|
import com.jsowell.pile.service.programlogic.ProgramLogicFactory;
|
||||||
import com.jsowell.pile.transaction.dto.ClearingBillTransactionDTO;
|
import com.jsowell.pile.transaction.dto.ClearingBillTransactionDTO;
|
||||||
import com.jsowell.pile.transaction.dto.OrderTransactionDTO;
|
import com.jsowell.pile.transaction.dto.OrderTransactionDTO;
|
||||||
@@ -1290,7 +1289,7 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService {
|
|||||||
String payMode = orderBasicInfo.getPayMode();
|
String payMode = orderBasicInfo.getPayMode();
|
||||||
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
||||||
// 余额支付
|
// 余额支付
|
||||||
balancePaymentOrderRefundV2(orderBasicInfo);
|
SpringUtils.getBean(OrderBasicInfoService.class).refundBalancePaymentOrder(orderBasicInfo);
|
||||||
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
|
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
|
||||||
// 微信支付
|
// 微信支付
|
||||||
onlinePaymentOrderRefund(orderBasicInfo);
|
onlinePaymentOrderRefund(orderBasicInfo);
|
||||||
@@ -1318,7 +1317,7 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService {
|
|||||||
String payMode = orderBasicInfo.getPayMode();
|
String payMode = orderBasicInfo.getPayMode();
|
||||||
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
||||||
// 余额支付
|
// 余额支付
|
||||||
balancePaymentOrderRefundV2(orderBasicInfo);
|
SpringUtils.getBean(OrderBasicInfoService.class).refundBalancePaymentOrder(orderBasicInfo);
|
||||||
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
|
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
|
||||||
// 微信支付
|
// 微信支付
|
||||||
onlinePaymentOrderRefund(orderBasicInfo);
|
onlinePaymentOrderRefund(orderBasicInfo);
|
||||||
@@ -1580,81 +1579,150 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void balancePaymentOrderRefundV2(OrderBasicInfo orderBasicInfo) {
|
public void refundBalancePaymentOrder(OrderBasicInfo orderBasicInfo) {
|
||||||
// 订单编号
|
if (orderBasicInfo == null) {
|
||||||
|
logger.info("余额支付订单退款-订单信息为空,不执行退款");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String orderCode = orderBasicInfo.getOrderCode();
|
String orderCode = orderBasicInfo.getOrderCode();
|
||||||
BigDecimal refundAmount = orderBasicInfo.getRefundAmount();
|
BigDecimal refundAmount = orderBasicInfo.getRefundAmount();
|
||||||
if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
if (StringUtils.isBlank(orderCode) || refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
logger.info("balancePaymentOrderRefundV2-退款金额小于等于0,orderCode:{}, 退款金额:{}", orderCode, refundAmount);
|
logger.info("余额支付订单退款-参数不足,orderCode:{}, 退款金额:{}", orderCode, refundAmount);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 订单消费金额
|
|
||||||
BigDecimal orderAmount = orderBasicInfo.getOrderAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getOrderAmount();
|
if (!StringUtils.equals(orderBasicInfo.getPayMode(), OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
||||||
// 查支付记录
|
logger.info("余额支付订单退款-订单:{}支付方式:{}不是余额支付,不执行退款",
|
||||||
|
orderCode, OrderPayModeEnum.getPayModeDescription(orderBasicInfo.getPayMode()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String lockKey = CacheConstants.ORDER_BALANCE_PAYMENT_REFUND_LOCK + orderCode;
|
||||||
|
Boolean locked = redisCache.setnx(lockKey, Constants.ONE, 60);
|
||||||
|
if (!Boolean.TRUE.equals(locked)) {
|
||||||
|
logger.info("余额支付订单退款-订单:{}正在退款处理中,本次跳过", orderCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
doRefundBalancePaymentOrder(orderBasicInfo);
|
||||||
|
} finally {
|
||||||
|
redisCache.deleteObject(lockKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doRefundBalancePaymentOrder(OrderBasicInfo orderBasicInfo) {
|
||||||
|
String orderCode = orderBasicInfo.getOrderCode();
|
||||||
|
BigDecimal refundAmount = orderBasicInfo.getRefundAmount();
|
||||||
|
BigDecimal orderAmount = positiveOrZero(orderBasicInfo.getOrderAmount());
|
||||||
|
BigDecimal discountAmount = positiveOrZero(orderBasicInfo.getDiscountAmount());
|
||||||
|
BigDecimal insuranceAmount = positiveOrZero(orderBasicInfo.getInsuranceAmount());
|
||||||
|
|
||||||
List<OrderPayRecord> payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
|
List<OrderPayRecord> payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
|
||||||
if (CollectionUtils.isEmpty(payRecordList)) {
|
if (CollectionUtils.isEmpty(payRecordList)) {
|
||||||
logger.info("balancePaymentOrderRefundV2-订单支付记录为空,orderCode:{}", orderCode);
|
logger.info("余额支付订单退款-订单支付记录为空,orderCode:{}", orderCode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map<String, OrderPayRecord> payRecordMap = payRecordList.stream()
|
|
||||||
// .collect(Collectors.toMap(OrderPayRecord::getPayMode, Function.identity(), (k1, k2) -> k1));
|
|
||||||
Map<String, List<OrderPayRecord>> payRecordMap = payRecordList.stream().collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
|
Map<String, List<OrderPayRecord>> payRecordMap = payRecordList.stream().collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
|
||||||
// 获取本金支付的记录
|
BigDecimal principalPay = sumPayAmount(payRecordMap.get(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue()));
|
||||||
List<OrderPayRecord> principalPayRecordList = payRecordMap.get(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue());
|
BigDecimal giftPay = sumPayAmount(payRecordMap.get(OrderPayRecordEnum.GIFT_BALANCE_PAYMENT.getValue()));
|
||||||
BigDecimal principalPay = null;
|
|
||||||
if (CollectionUtils.isNotEmpty(principalPayRecordList)) {
|
if (insuranceAmount.compareTo(BigDecimal.ZERO) > 0 && !checkRefundInsuranceAmount(orderBasicInfo)) {
|
||||||
principalPay = principalPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
insuranceAmount = BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取赠送金支付的记录
|
Map<String, BigDecimal> refundMap = calculateBalanceRefund(principalPay, giftPay, orderAmount, discountAmount, insuranceAmount);
|
||||||
List<OrderPayRecord> giftPayRecordList = payRecordMap.get(OrderPayRecordEnum.GIFT_BALANCE_PAYMENT.getValue());
|
BigDecimal returnPrincipal = positiveOrZero(refundMap.get("returnPrincipal"))
|
||||||
BigDecimal giftPay = null;
|
.add(positiveOrZero(refundMap.get("returnPrincipalForInsurance")));
|
||||||
if (CollectionUtils.isNotEmpty(giftPayRecordList)) {
|
BigDecimal returnGift = positiveOrZero(refundMap.get("returnGift"))
|
||||||
giftPay = giftPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
.add(positiveOrZero(refundMap.get("returnGiftForInsurance")));
|
||||||
}
|
|
||||||
|
|
||||||
// 计算需要退回的金额
|
logger.info("余额支付订单退款-订单:{}, 订单消费金额:{}, 折扣金额:{}, 保险金额:{}, 本金支付:{}, 赠送支付:{}, 原计算本金:{}, 原计算赠送:{}",
|
||||||
Map<String, BigDecimal> returnAmountMap = calculateReturnAmount(principalPay, giftPay, orderAmount);
|
orderCode, orderAmount, discountAmount, insuranceAmount, principalPay, giftPay, returnPrincipal, returnGift);
|
||||||
logger.info("结算订单:{}, 剩余金额退回余额, 订单消费金额:{}, 本金支付金额:{}, 赠送支付金额:{}, 退回金额map:{}",
|
|
||||||
orderCode, orderAmount, principalPay, giftPay, JSON.toJSONString(returnAmountMap));
|
|
||||||
|
|
||||||
// 需要退回本金的金额
|
|
||||||
BigDecimal returnPrincipal = returnAmountMap.get("returnPrincipal");
|
|
||||||
// 需要退回赠送金的金额
|
|
||||||
BigDecimal returnGift = returnAmountMap.get("returnGift");
|
|
||||||
|
|
||||||
Map<String, BigDecimal> allowableRefundMap = calculateAllowableBalanceRefund(orderCode, refundAmount,
|
Map<String, BigDecimal> allowableRefundMap = calculateAllowableBalanceRefund(orderCode, refundAmount,
|
||||||
principalPay, giftPay, returnPrincipal, returnGift);
|
principalPay, giftPay, returnPrincipal, returnGift);
|
||||||
returnPrincipal = allowableRefundMap.get("returnPrincipal");
|
returnPrincipal = allowableRefundMap.get("returnPrincipal");
|
||||||
returnGift = allowableRefundMap.get("returnGift");
|
returnGift = allowableRefundMap.get("returnGift");
|
||||||
if (returnPrincipal.compareTo(BigDecimal.ZERO) <= 0 && returnGift.compareTo(BigDecimal.ZERO) <= 0) {
|
if (returnPrincipal.compareTo(BigDecimal.ZERO) <= 0 && returnGift.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
logger.info("balancePaymentOrderRefundV2-订单:{}本次可退金额为0,不执行退款", orderCode);
|
logger.info("余额支付订单退款-订单:{}本次可退金额为0,不执行退款", orderCode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新会员钱包/余额退回到钱包
|
|
||||||
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
|
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
|
||||||
.memberId(orderBasicInfo.getMemberId())
|
.memberId(orderBasicInfo.getMemberId())
|
||||||
.type(MemberWalletEnum.TYPE_IN.getValue()) // 进账
|
.targetMerchantId(orderBasicInfo.getMerchantId())
|
||||||
.subType(MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue()) // 订单结算退款
|
.type(MemberWalletEnum.TYPE_IN.getValue())
|
||||||
|
.subType(MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue())
|
||||||
.updatePrincipalBalance(returnPrincipal)
|
.updatePrincipalBalance(returnPrincipal)
|
||||||
.updateGiftBalance(returnGift)
|
.updateGiftBalance(returnGift)
|
||||||
.relatedOrderCode(orderCode)
|
.relatedOrderCode(orderCode)
|
||||||
.build();
|
.build();
|
||||||
memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO);
|
memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO);
|
||||||
|
|
||||||
// 更新order_pay_record, 解冻部分
|
unfreezeBalancePaymentRecords(orderAmount, payRecordList);
|
||||||
AbstractProgramLogic orderLogic = new DelayMerchantProgramLogic();
|
}
|
||||||
List<Map<String, Object>> list = orderLogic.calculateUnfreezeAmount(orderAmount, payRecordList);
|
|
||||||
|
private BigDecimal sumPayAmount(List<OrderPayRecord> payRecords) {
|
||||||
|
if (CollectionUtils.isEmpty(payRecords)) {
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
return payRecords.stream()
|
||||||
|
.map(OrderPayRecord::getPayAmount)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unfreezeBalancePaymentRecords(BigDecimal orderAmount, List<OrderPayRecord> payRecordList) {
|
||||||
|
List<Map<String, Object>> list = calculateUnfreezeAmount(orderAmount, payRecordList);
|
||||||
for (Map<String, Object> map : list) {
|
for (Map<String, Object> map : list) {
|
||||||
String paymentId = (String) map.get("paymentId");
|
String paymentId = (String) map.get("paymentId");
|
||||||
BigDecimal unfreezeAmount = (BigDecimal) map.get("unfreezeAmount");
|
BigDecimal unfreezeAmount = (BigDecimal) map.get("unfreezeAmount");
|
||||||
|
if (StringUtils.isBlank(paymentId) || unfreezeAmount == null || unfreezeAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
memberAdapayRecordService.unfreezeAmount(paymentId, unfreezeAmount);
|
memberAdapayRecordService.unfreezeAmount(paymentId, unfreezeAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Map<String, Object>> calculateUnfreezeAmount(BigDecimal orderAmount, List<OrderPayRecord> payRecordList) {
|
||||||
|
List<Map<String, Object>> resultList = Lists.newArrayList();
|
||||||
|
if (CollectionUtils.isEmpty(payRecordList)) {
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal tempAmount = positiveOrZero(orderAmount);
|
||||||
|
for (OrderPayRecord record : payRecordList) {
|
||||||
|
if (!StringUtils.equals(record.getPayMode(), OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<PaymentInfo> paymentInfos = orderPayRecordService.parseDeductionRecord(record.getDeductionRecord());
|
||||||
|
for (PaymentInfo object : paymentInfos) {
|
||||||
|
String paymentId = object.getPaymentId();
|
||||||
|
BigDecimal payAmount = new BigDecimal(object.getAmount());
|
||||||
|
BigDecimal unfreezeAmount;
|
||||||
|
|
||||||
|
if (tempAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
unfreezeAmount = payAmount;
|
||||||
|
} else {
|
||||||
|
BigDecimal min = tempAmount.min(payAmount);
|
||||||
|
unfreezeAmount = payAmount.subtract(min);
|
||||||
|
tempAmount = tempAmount.subtract(min);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> map = Maps.newHashMap();
|
||||||
|
map.put("paymentId", paymentId);
|
||||||
|
map.put("unfreezeAmount", unfreezeAmount);
|
||||||
|
resultList.add(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单分账逻辑
|
* 订单分账逻辑
|
||||||
* orderSplittingOperations
|
* orderSplittingOperations
|
||||||
|
|||||||
@@ -833,7 +833,7 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic {
|
|||||||
String payMode = orderBasicInfo.getPayMode();
|
String payMode = orderBasicInfo.getPayMode();
|
||||||
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
||||||
// 余额支付
|
// 余额支付
|
||||||
balancePaymentOrderRefund(orderBasicInfo);
|
orderBasicInfoService.refundBalancePaymentOrder(orderBasicInfo);
|
||||||
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
|
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
|
||||||
|| StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())) {
|
|| StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())) {
|
||||||
// 在线支付
|
// 在线支付
|
||||||
@@ -1023,127 +1023,6 @@ public class DelayMerchantProgramLogic 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();
|
|
||||||
|
|
||||||
// 如果退款金额小于等于0, 不执行退款
|
|
||||||
if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
|
||||||
logger.info("balancePaymentOrderRefund-退款金额小于等于0,orderCode:{}, 退款金额:{}", orderBasicInfo.getOrderCode(), refundAmount);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取订单已退款金额
|
|
||||||
BigDecimal orderRefundedAmount = orderBasicInfoService.getOrderRefundedAmount(orderBasicInfo.getOrderCode());
|
|
||||||
if (orderRefundedAmount.compareTo(refundAmount) >= 0) {
|
|
||||||
logger.info("执行订单退款-校验已退款金额,orderCode:{}, 应退款金额:{}, 已经退款金额:{}, 不再执行退款", orderBasicInfo.getOrderCode(), refundAmount, orderRefundedAmount);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 订单编号
|
|
||||||
String orderCode = orderBasicInfo.getOrderCode();
|
|
||||||
|
|
||||||
// 运营商id
|
|
||||||
String merchantId = orderBasicInfo.getMerchantId();
|
|
||||||
|
|
||||||
// 订单消费金额
|
|
||||||
BigDecimal orderAmount = orderBasicInfo.getOrderAmount();
|
|
||||||
|
|
||||||
// 查支付记录
|
|
||||||
List<OrderPayRecord> payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
|
|
||||||
|
|
||||||
// 根据payMode分组
|
|
||||||
Map<String, List<OrderPayRecord>> payRecordMap = payRecordList.stream()
|
|
||||||
.collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
|
|
||||||
|
|
||||||
// 获取本金支付的记录
|
|
||||||
List<OrderPayRecord> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取赠送金支付的记录
|
|
||||||
List<OrderPayRecord> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
BigDecimal discountAmount = orderBasicInfo.getDiscountAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getDiscountAmount();
|
|
||||||
BigDecimal insuranceAmount = orderBasicInfo.getInsuranceAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getInsuranceAmount();
|
|
||||||
|
|
||||||
// 计算需要退回的金额
|
|
||||||
Map<String, BigDecimal> returnAmountMap = calculateReturnAmount(principalPay, giftPay, orderAmount, discountAmount);
|
|
||||||
logger.info("结算订单:{}, 剩余金额退回余额, 订单消费金额:{}, 本金支付金额:{}, 赠送支付金额:{}, 退回金额map:{}",
|
|
||||||
orderCode, orderAmount, principalPay, giftPay, JSON.toJSONString(returnAmountMap));
|
|
||||||
|
|
||||||
// 需要退回本金的金额
|
|
||||||
BigDecimal returnPrincipal = returnAmountMap.get("returnPrincipal");
|
|
||||||
returnPrincipal = returnPrincipal == null ? BigDecimal.ZERO : returnPrincipal;
|
|
||||||
|
|
||||||
// 需要退回赠送金的金额
|
|
||||||
BigDecimal returnGift = returnAmountMap.get("returnGift");
|
|
||||||
returnGift = returnGift == null ? BigDecimal.ZERO : returnGift;
|
|
||||||
|
|
||||||
// 更新会员钱包/余额退回到钱包
|
|
||||||
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
|
|
||||||
.memberId(orderBasicInfo.getMemberId())
|
|
||||||
.targetMerchantId(merchantId)
|
|
||||||
.type(MemberWalletEnum.TYPE_IN.getValue()) // 进账
|
|
||||||
.subType(MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue()) // 订单结算退款
|
|
||||||
.updatePrincipalBalance(returnPrincipal)
|
|
||||||
.updateGiftBalance(returnGift)
|
|
||||||
.relatedOrderCode(orderCode)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// 判断消费金额,如果消费金额 - 折扣金额小于 1 元,则将保险费也进行退回
|
|
||||||
if (orderAmount.subtract(discountAmount).compareTo(BigDecimal.ONE) < 0) {
|
|
||||||
// 判断是否需要退保险费用
|
|
||||||
boolean checkResult = orderBasicInfoService.checkRefundInsuranceAmount(orderBasicInfo);
|
|
||||||
if (checkResult) {
|
|
||||||
// 退保险, 使用 calculateBalanceRefund 重新计算完整的退款金额(电费退款+保险费退款)
|
|
||||||
// 注意:不能在 calculateReturnAmount 的基础上叠加保险费,因为 calculateReturnAmount 不感知保险费,
|
|
||||||
// 算出的退款金额中已包含保险费部分,叠加会导致保险费被重复退还
|
|
||||||
Map<String, BigDecimal> refundMap = calculateBalanceRefund(principalPay, giftPay, orderAmount, discountAmount, insuranceAmount);
|
|
||||||
BigDecimal refundPrincipal = refundMap.get("returnPrincipal");
|
|
||||||
BigDecimal refundGift = refundMap.get("returnGift");
|
|
||||||
BigDecimal returnPrincipalForInsurance = refundMap.get("returnPrincipalForInsurance");
|
|
||||||
BigDecimal returnGiftForInsurance = refundMap.get("returnGiftForInsurance");
|
|
||||||
refundPrincipal = refundPrincipal == null ? BigDecimal.ZERO : refundPrincipal;
|
|
||||||
refundGift = refundGift == null ? BigDecimal.ZERO : refundGift;
|
|
||||||
|
|
||||||
updateMemberBalanceDTO.setUpdatePrincipalBalance(refundPrincipal.add(returnPrincipalForInsurance));
|
|
||||||
updateMemberBalanceDTO.setUpdateGiftBalance(refundGift.add(returnGiftForInsurance));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, BigDecimal> 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, 解冻部分
|
|
||||||
// List<Map<String, Object>> list = calculateUnfreezeAmount(orderAmount, payRecordList);
|
|
||||||
// for (Map<String, Object> map : list) {
|
|
||||||
// String paymentId = (String) map.get("paymentId");
|
|
||||||
// BigDecimal unfreezeAmount = (BigDecimal) map.get("unfreezeAmount");
|
|
||||||
// memberAdapayRecordService.unfreezeAmount(paymentId, unfreezeAmount);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线支付订单退款
|
* 在线支付订单退款
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -542,7 +542,7 @@ public class NotDelayMerchantProgramLogic extends AbstractProgramLogic {
|
|||||||
String payMode = orderBasicInfo.getPayMode();
|
String payMode = orderBasicInfo.getPayMode();
|
||||||
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
||||||
// 余额支付
|
// 余额支付
|
||||||
balancePaymentOrderRefund(orderBasicInfo);
|
orderBasicInfoService.refundBalancePaymentOrder(orderBasicInfo);
|
||||||
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
|
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
|
||||||
|| StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())) {
|
|| StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())) {
|
||||||
// 在线支付
|
// 在线支付
|
||||||
@@ -747,86 +747,6 @@ public class NotDelayMerchantProgramLogic extends AbstractProgramLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 余额支付订单退款
|
|
||||||
*
|
|
||||||
* @param orderBasicInfo
|
|
||||||
*/
|
|
||||||
@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();
|
|
||||||
// 订单消费金额
|
|
||||||
BigDecimal orderAmount = orderBasicInfo.getOrderAmount();
|
|
||||||
// 查支付记录
|
|
||||||
List<OrderPayRecord> payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
|
|
||||||
|
|
||||||
// 根据payMode分组
|
|
||||||
Map<String, List<OrderPayRecord>> payRecordMap = payRecordList.stream()
|
|
||||||
.collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
|
|
||||||
|
|
||||||
// 获取本金支付的记录
|
|
||||||
List<OrderPayRecord> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取赠送金支付的记录
|
|
||||||
List<OrderPayRecord> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
BigDecimal discountAmount = orderBasicInfo.getDiscountAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getDiscountAmount();
|
|
||||||
|
|
||||||
// 计算需要退回的金额
|
|
||||||
Map<String, BigDecimal> returnAmountMap = calculateReturnAmount(principalPay, giftPay, orderAmount, discountAmount);
|
|
||||||
logger.info("结算订单:{}, 剩余金额退回余额, 订单消费金额:{}, 本金支付金额:{}, 赠送支付金额:{}, 退回金额map:{}",
|
|
||||||
orderCode, orderAmount, principalPay, giftPay, JSON.toJSONString(returnAmountMap));
|
|
||||||
|
|
||||||
// 需要退回本金的金额
|
|
||||||
BigDecimal returnPrincipal = returnAmountMap.get("returnPrincipal");
|
|
||||||
// 需要退回赠送金的金额
|
|
||||||
BigDecimal returnGift = returnAmountMap.get("returnGift");
|
|
||||||
|
|
||||||
// 更新会员钱包/余额退回到钱包
|
|
||||||
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
|
|
||||||
.memberId(orderBasicInfo.getMemberId())
|
|
||||||
.type(MemberWalletEnum.TYPE_IN.getValue()) // 进账
|
|
||||||
.subType(MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue()) // 订单结算退款
|
|
||||||
.updatePrincipalBalance(returnPrincipal)
|
|
||||||
.updateGiftBalance(returnGift)
|
|
||||||
.relatedOrderCode(orderCode)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Map<String, BigDecimal> 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, 解冻部分
|
|
||||||
List<Map<String, Object>> list = calculateUnfreezeAmount(orderAmount, payRecordList);
|
|
||||||
for (Map<String, Object> map : list) {
|
|
||||||
String paymentId = (String) map.get("paymentId");
|
|
||||||
BigDecimal unfreezeAmount = (BigDecimal) map.get("unfreezeAmount");
|
|
||||||
memberAdapayRecordService.unfreezeAmount(paymentId, unfreezeAmount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线支付订单退款
|
* 在线支付订单退款
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user