From 3aa19814bc96796686bb1f827fd05a42bd4e5f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=AE=87=E5=A5=87?= Date: Sat, 17 May 2025 19:12:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=81=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xkt/AlipayCallbackController.java | 28 +++++++----- .../web/controller/xkt/AssetController.java | 1 + .../controller/xkt/StoreOrderController.java | 1 + .../com/ruoyi/xkt/enums/EProcessStatus.java | 9 +++- .../xkt/service/IAlipayCallbackService.java | 14 ++++++ .../ruoyi/xkt/service/IStoreOrderService.java | 9 ++++ .../impl/AlipayCallbackServiceImpl.java | 44 +++++++++++++++++++ .../service/impl/StoreOrderServiceImpl.java | 42 ++++++++++++++++++ 8 files changed, 135 insertions(+), 13 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayCallbackController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayCallbackController.java index 80de97e81..44a8fbf88 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayCallbackController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayCallbackController.java @@ -100,20 +100,22 @@ public class AlipayCallbackController extends XktBaseController { info = alipayCallback; alipayCallbackService.insertAlipayCallback(info); } + if (EProcessStatus.isSkip(info.getProcessStatus())){ + logger.warn("支付回调重复请求处理: {}", info); + return SUCCESS; + } if (!"TRADE_SUCCESS".equals(info.getTradeStatus())) { //非交易支付成功的回调不处理 + alipayCallbackService.noNeedProcess(info); return SUCCESS; } if (info.getRefundFee() != null && !NumberUtil.equals(info.getRefundFee(), BigDecimal.ZERO)) { //如果有退款金额,可能是部分退款的回调,这里不做处理 + alipayCallbackService.noNeedProcess(info); return SUCCESS; } - if (EProcessStatus.INIT.getValue().equals(info.getProcessStatus())) { - //更新回调状态和订单状态,创建收款单 - alipayCallbackService.processOrderPaid(info); - } else { - logger.warn("支付回调重复请求处理: {}", info.getId()); - } + //更新回调状态和订单状态,创建收款单 + alipayCallbackService.processOrderPaid(info); return SUCCESS; } else { //充值业务 @@ -133,20 +135,22 @@ public class AlipayCallbackController extends XktBaseController { info = alipayCallback; alipayCallbackService.insertAlipayCallback(info); } + if (EProcessStatus.isSkip(info.getProcessStatus())){ + logger.warn("支付回调重复请求处理: {}", info); + return SUCCESS; + } if (!"TRADE_SUCCESS".equals(info.getTradeStatus())) { //非交易支付成功的回调不处理 + alipayCallbackService.noNeedProcess(info); return SUCCESS; } if (info.getRefundFee() != null && !NumberUtil.equals(info.getRefundFee(), BigDecimal.ZERO)) { //如果有退款金额,可能是部分退款的回调,这里不做处理 + alipayCallbackService.noNeedProcess(info); return SUCCESS; } - if (EProcessStatus.INIT.getValue().equals(info.getProcessStatus())) { - //更新回调状态,收款单到账 - alipayCallbackService.processRecharge(info); - } else { - logger.warn("支付回调重复请求处理: {}", info.getId()); - } + //更新回调状态,收款单到账 + alipayCallbackService.processRecharge(info); return SUCCESS; } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AssetController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AssetController.java index fd8857d8a..72d38e74f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AssetController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AssetController.java @@ -82,6 +82,7 @@ public class AssetController extends XktBaseController { //创建付款单 WithdrawPrepareResult prepareResult = assetService.prepareWithdraw(SecurityUtils.getStoreId(), vo.getAmount(), vo.getTransactionPassword(), EPayChannel.ALI_PAY); + //TODO 失败补偿 //支付宝转账 aliPaymentManger.transfer(prepareResult.getBillNo(), prepareResult.getAccountOwnerNumber(), prepareResult.getAccountOwnerName(), prepareResult.getAmount()); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java index 700cbc049..6195cfefb 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java @@ -229,6 +229,7 @@ public class StoreOrderController extends XktBaseController { dto.setOperatorId(SecurityUtils.getUserId()); //售后状态->售后完成,支付状态->支付中,创建收款单 StoreOrderRefund storeOrderRefund = storeOrderService.prepareRefundOrder(dto); + //TODO 失败补偿 //三方退款 PaymentManager paymentManager = getPaymentManager(EPayChannel.of(storeOrderRefund.getRefundOrder().getPayChannel())); paymentManager.refundStoreOrder(storeOrderRefund); diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java index d421a81c5..f7224cdf2 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java @@ -14,7 +14,8 @@ public enum EProcessStatus { INIT(1, "初始"), PROCESSING(2, "处理中"), SUCCESS(3, "处理成功"), - FAILURE(4, "处理失败"); + FAILURE(4, "处理失败"), + NO_PROCESSING(5,"不处理"); private final Integer value; private final String label; @@ -27,4 +28,10 @@ public enum EProcessStatus { } return null; } + + public static boolean isSkip(Integer value) { + return SUCCESS.getValue().equals(value) + || FAILURE.getValue().equals(value) + || NO_PROCESSING.getValue().equals(value); + } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java index 028584bf6..fc36d4a3e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java @@ -37,4 +37,18 @@ public interface IAlipayCallbackService { * @param info */ void processRecharge(AlipayCallback info); + + /** + * 标记为不处理 + * + * @param info + */ + void noNeedProcess(AlipayCallback info); + + /** + * 继续处理回调 + * + * @param count + */ + void continueProcess(int count); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java index cabe9b1ca..0bbc80ab5 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java @@ -8,6 +8,7 @@ import com.ruoyi.xkt.enums.EPayChannel; import com.ruoyi.xkt.enums.EPayPage; import java.math.BigDecimal; +import java.util.Date; import java.util.List; /** @@ -175,4 +176,12 @@ public interface IStoreOrderService { * @param trackAddDTO */ void addTrack(StoreOrderExpressTrackAddDTO trackAddDTO); + + /** + * 自动取消 + * + * @param beforeDate + * @param count + */ + void autoCancel(Date beforeDate, int count); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java index 7b03df73c..9d7c6d1e8 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java @@ -1,9 +1,14 @@ package com.ruoyi.xkt.service.impl; +import cn.hutool.core.util.NumberUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.SimpleEntity; import com.ruoyi.xkt.domain.AlipayCallback; import com.ruoyi.xkt.domain.StoreOrder; import com.ruoyi.xkt.dto.order.StoreOrderExt; +import com.ruoyi.xkt.enums.EAlipayCallbackBizType; import com.ruoyi.xkt.enums.EPayChannel; import com.ruoyi.xkt.enums.EProcessStatus; import com.ruoyi.xkt.mapper.AlipayCallbackMapper; @@ -15,6 +20,9 @@ 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.List; + /** * @author liangyq * @date 2025-04-08 17:40 @@ -68,4 +76,40 @@ public class AlipayCallbackServiceImpl implements IAlipayCallbackService { //收款单到账 financeBillService.entryRechargeCollectionBill(info.getOutTradeNo()); } + + @Transactional(rollbackFor = Exception.class) + @Override + public void noNeedProcess(AlipayCallback info) { + info.setProcessStatus(EProcessStatus.NO_PROCESSING.getValue()); + alipayCallbackMapper.updateById(info); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void continueProcess(int count) { + PageHelper.startPage(1, count, false); + List infoList = alipayCallbackMapper.selectList(Wrappers.lambdaQuery(AlipayCallback.class) + .eq(AlipayCallback::getProcessStatus, EProcessStatus.INIT.getValue()) + .eq(SimpleEntity::getDelFlag, Constants.UNDELETED)); + for (AlipayCallback info : infoList) { + if (!"TRADE_SUCCESS".equals(info.getTradeStatus())) { + //非交易支付成功的回调不处理 + noNeedProcess(info); + continue; + } + if (info.getRefundFee() != null && !NumberUtil.equals(info.getRefundFee(), BigDecimal.ZERO)) { + //如果有退款金额,可能是部分退款的回调,这里不做处理 + noNeedProcess(info); + continue; + } + if (EAlipayCallbackBizType.ORDER_PAY.getValue().equals(info.getBizType())) { + processOrderPaid(info); + } else if (EAlipayCallbackBizType.RECHARGE.getValue().equals(info.getBizType())) { + processRecharge(info); + } else { + noNeedProcess(info); + } + } + + } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java index 39243d96d..49164407a 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java @@ -1259,6 +1259,48 @@ public class StoreOrderServiceImpl implements IStoreOrderService { expressService.addTrackRecord(expressTrackRecordAddDTO); } + @Transactional(rollbackFor = Exception.class) + @Override + public void autoCancel(Date beforeDate, int count) { + PageHelper.startPage(1, count, false); + List orders = storeOrderMapper.selectList(Wrappers.lambdaQuery(StoreOrder.class) + .eq(StoreOrder::getOrderStatus, EOrderStatus.PENDING_PAYMENT.getValue()) + .ne(StoreOrder::getPayStatus, EPayStatus.PAID.getValue()) + .eq(SimpleEntity::getDelFlag, Constants.UNDELETED) + .le(SimpleEntity::getCreateTime, beforeDate)); + for (StoreOrder order : orders) { + PaymentManager paymentManager = getPaymentManager(EPayChannel.of(order.getPayChannel())); + boolean isPaid = paymentManager.isStoreOrderPaid(order.getOrderNo()); + if (isPaid) { + log.warn("订单[{}]已支付,无法取消", order.getId()); + continue; + } + //订单已取消 + order.setOrderStatus(EOrderStatus.CANCELLED.getValue()); + int orderSuccess = storeOrderMapper.updateById(order); + if (orderSuccess == 0) { + throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG); + } + List orderDetails = storeOrderDetailMapper.selectList( + Wrappers.lambdaQuery(StoreOrderDetail.class) + .eq(StoreOrderDetail::getStoreOrderId, order.getId()) + .eq(SimpleEntity::getDelFlag, Constants.UNDELETED)); + List orderDetailIdList = new ArrayList<>(orderDetails.size()); + for (StoreOrderDetail orderDetail : orderDetails) { + //明细已取消 + orderDetail.setDetailStatus(EOrderStatus.CANCELLED.getValue()); + int orderDetailSuccess = storeOrderDetailMapper.updateById(orderDetail); + if (orderDetailSuccess == 0) { + throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG); + } + orderDetailIdList.add(orderDetail.getId()); + } + //操作记录 + addOperationRecords(order.getId(), EOrderAction.CANCEL, orderDetailIdList, EOrderAction.CANCEL, + "超时取消", null, new Date()); + } + } + /** * 添加操作记录 *