diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 05e1dc1f2f..b2d72e4b01 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -36,8 +36,10 @@ public interface ErrorCodeConstants { ErrorCode ORDER_UPDATE_ADDRESS_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1_011_000_031, "交易订单修改收货地址失败,原因:订单不是【待发货】状态"); ErrorCode ORDER_CREATE_FAIL_EXIST_UNPAID = new ErrorCode(1_011_000_032, "交易订单创建失败,原因:存在未付款订单"); ErrorCode ORDER_CANCEL_PAID_FAIL = new ErrorCode(1_011_000_033, "交易订单取消支付失败,原因:订单不是【{}】状态"); - ErrorCode ORDER_PICK_UP_FAIL_NOT_VERIFY_USER = new ErrorCode(1_011_000_034, "交易订单自提失败,原因:你没有核销该门店订单的权限"); - ErrorCode ORDER_CREATE_FAIL_INSUFFICIENT_USER_POINTS = new ErrorCode(1_011_000_035, "交易订单创建失败,原因:用户积分不足"); + ErrorCode ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_NOT_FOUND = new ErrorCode(1_011_000_034, "交易订单更新支付订单退款状态失败,原因:退款单不存在"); + ErrorCode ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_STATUS_NOT_SUCCESS = new ErrorCode(1_011_000_035, "交易订单更新支付订单退款状态失败,原因:退款单状态不是【退款成功】"); + ErrorCode ORDER_PICK_UP_FAIL_NOT_VERIFY_USER = new ErrorCode(1_011_000_036, "交易订单自提失败,原因:你没有核销该门店订单的权限"); + ErrorCode ORDER_CREATE_FAIL_INSUFFICIENT_USER_POINTS = new ErrorCode(1_011_000_037, "交易订单创建失败,原因:用户积分不足"); // ========== After Sale 模块 1-011-000-100 ========== ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在"); @@ -51,9 +53,13 @@ public interface ErrorCodeConstants { ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE = new ErrorCode(1_011_000_108, "退货失败,售后单状态不处于【待买家退货】"); ErrorCode AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY = new ErrorCode(1_011_000_109, "确认收货失败,售后单状态不处于【待确认收货】"); ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1_011_000_110, "退款失败,售后单状态不是【待退款】"); + ErrorCode AFTER_SALE_REFUND_FAIL_REFUND_NOT_FOUND = new ErrorCode(1_011_000_111, "退款失败,退款单不存在"); + ErrorCode AFTER_SALE_REFUND_FAIL_REFUND_NOT_SUCCESS_OR_FAILURE = new ErrorCode(1_011_000_112, "退款失败,退款单未退款"); + ErrorCode AFTER_SALE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1_011_000_113, "退款失败,退款金额不匹配"); + ErrorCode AFTER_SALE_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1_011_000_114, "退款失败,退款单不匹配"); ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY = - new ErrorCode(1_011_000_111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】"); - ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS = new ErrorCode(1_011_000_112, "订单拼团中,无法申请售后"); + new ErrorCode(1_011_000_115, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】"); + ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS = new ErrorCode(1_011_000_116, "订单拼团中,无法申请售后"); // ========== Cart 模块 1-011-002-000 ========== ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1_011_002_000, "购物车项不存在"); @@ -101,7 +107,6 @@ public interface ErrorCodeConstants { ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1_011_008_001, "佣金提现记录状态不是审核中"); ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1_011_008_002, "提现金额不能低于 {} 元"); ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1_011_008_003, "您当前最多可提现 {} 元"); - ErrorCode BROKERAGE_WITHDRAW_TRANSFER_FAIL_WECHAT_NOT_BIND = new ErrorCode(1_011_008_004, "提现失败,原因:用户未绑定微信"); ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR = new ErrorCode(1_011_008_005, "提现单更新转账状态失败,转账单不匹配"); ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED = new ErrorCode(1_011_008_006, "提现单更新转账状态失败,转账单状态不是成功或关闭状态"); ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1_011_008_007, "提现单更新转账状态失败,转账单金额不匹配"); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java index db870c6375..5f23a5dbc9 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java @@ -19,7 +19,9 @@ public enum AfterSaleOperateTypeEnum { MEMBER_DELIVERY(20, "会员填写退货物流信息,快递公司:{deliveryName},快递单号:{logisticsNo}"), ADMIN_AGREE_RECEIVE(21, "商家收货"), ADMIN_DISAGREE_RECEIVE(22, "商家拒绝收货,原因:{reason}"), - ADMIN_REFUND(30, "商家退款"), + ADMIN_REFUND(30, "商家发起退款"), + SYSTEM_REFUND_SUCCESS(31, "退款成功"), + SYSTEM_REFUND_FAIL(32, "退款失败"), MEMBER_CANCEL(40, "会员取消退款"), ; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java index d6429b44fa..a87afb672c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; @@ -15,10 +16,12 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleLogService; import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -46,6 +49,8 @@ public class AfterSaleController { @Resource private TradeOrderQueryService tradeOrderQueryService; @Resource + private TradeOrderUpdateService tradeOrderUpdateService; + @Resource private AfterSaleLogService afterSaleLogService; @Resource private MemberUserApi memberUserApi; @@ -133,11 +138,19 @@ public class AfterSaleController { @PostMapping("/update-refunded") @Operation(summary = "更新售后订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob - @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 - public CommonResult updateAfterRefund(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { - // 目前业务逻辑,不需要做任何事情 - // 当然,退款会有小概率会失败的情况,可以监控失败状态,进行告警 + @PermitAll // 无需登录,安全由 AfterSaleService 内部校验实现 + public CommonResult updateAfterSaleRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); + if (StrUtil.startWithAny(notifyReqDTO.getMerchantRefundId(), "order-")) { + tradeOrderUpdateService.updatePaidOrderRefunded( + Long.parseLong(notifyReqDTO.getMerchantRefundId()), + notifyReqDTO.getPayRefundId()); + } else { + afterSaleService.updateAfterSaleRefunded( + Long.parseLong(notifyReqDTO.getMerchantRefundId()), + Long.parseLong(notifyReqDTO.getMerchantOrderId()), + notifyReqDTO.getPayRefundId()); + } return success(true); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java index dc0ce5ca4a..8a94833d8a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java @@ -88,7 +88,7 @@ public class BrokerageWithdrawController { public CommonResult updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); brokerageWithdrawService.updateBrokerageWithdrawTransferred( - Long.parseLong(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayTransferId()); + Long.parseLong(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId()); return success(true); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java index d0d60e2c12..c56f33afbe 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java @@ -1,18 +1,20 @@ package cn.iocoder.yudao.module.trade.framework.aftersale.core.aop; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO; +import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum; import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog; import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleLogService; import cn.iocoder.yudao.module.trade.service.aftersale.bo.AfterSaleLogCreateReqBO; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; -import jakarta.annotation.Resource; import java.util.Map; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; @@ -50,6 +52,10 @@ public class AfterSaleLogAspect { * 操作后的状态 */ private static final ThreadLocal AFTER_STATUS = new ThreadLocal<>(); + /** + * 操作类型(仅“动态场景”需要使用) + */ + private static final ThreadLocal OPERATE_TYPE = new ThreadLocal<>(); /** * 拓展参数 Map,用于格式化操作内容 */ @@ -69,6 +75,7 @@ public class AfterSaleLogAspect { if (afterSaleId == null) { // 如果未设置,只有注解,说明不需要记录日志 return; } + AfterSaleOperateTypeEnum operateType = ObjUtil.defaultIfNull(OPERATE_TYPE.get(), afterSaleLog.operateType()); Integer beforeStatus = BEFORE_STATUS.get(); Integer afterStatus = AFTER_STATUS.get(); Map exts = ObjectUtil.defaultIfNull(EXTS.get(), emptyMap()); @@ -78,7 +85,7 @@ public class AfterSaleLogAspect { AfterSaleLogCreateReqBO createBO = new AfterSaleLogCreateReqBO() .setUserId(userId).setUserType(userType) .setAfterSaleId(afterSaleId).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus) - .setOperateType(afterSaleLog.operateType().getType()).setContent(content); + .setOperateType(operateType.getType()).setContent(content); afterSaleLogService.createAfterSaleLog(createBO); } catch (Exception exception) { log.error("[doAfterReturning][afterSaleLog({}) 日志记录错误]", toJsonString(afterSaleLog), exception); @@ -116,6 +123,10 @@ public class AfterSaleLogAspect { EXTS.set(exts); } + public static void setAfterSaleOperateType(AfterSaleOperateTypeEnum operateType) { + OPERATE_TYPE.set(operateType); + } + public static void setUserInfo(Long userId, Integer userType) { USER_ID.set(userId); USER_TYPE.set(userType); @@ -127,6 +138,7 @@ public class AfterSaleLogAspect { AFTER_SALE_ID.remove(); BEFORE_STATUS.remove(); AFTER_STATUS.remove(); + OPERATE_TYPE.remove(); EXTS.remove(); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java index 3f9fc5d74b..14f97547bf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.framework.aftersale.core.utils; +import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum; import cn.iocoder.yudao.module.trade.framework.aftersale.core.aop.AfterSaleLogAspect; import java.util.Map; @@ -13,6 +14,10 @@ import java.util.Map; */ public class AfterSaleLogUtils { + public static void setAfterSaleOperateType(AfterSaleOperateTypeEnum operateType) { + AfterSaleLogAspect.setAfterSaleOperateType(operateType); + } + public static void setAfterSaleInfo(Long id, Integer beforeStatus, Integer afterStatus) { setAfterSaleInfo(id, beforeStatus, afterStatus, null); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java index 486a68b7c0..d2c0c3c849 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java @@ -108,6 +108,15 @@ public interface AfterSaleService { */ void refundAfterSale(Long userId, String userIp, Long id); + /** + * 更新售后订单为已退款 + * + * @param id 售后编号 + * @param orderId 订单编号 + * @param payRefundId 支付退款编号 + */ + void updateAfterSaleRefunded(Long id, Long orderId, Long payRefundId); + /** * 【会员】取消售后 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java index 915f253f0f..f0c63a032d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java @@ -7,6 +7,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; @@ -41,13 +43,12 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.validation.annotation.Validated; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; /** @@ -184,8 +185,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), null, AfterSaleStatusEnum.APPLY.getStatus()); - - // TODO 发送售后消息 return afterSale; } @@ -206,8 +205,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); - - // TODO 发送售后消息 } @Override @@ -226,8 +223,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); - // TODO 发送售后消息 - // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } @@ -281,8 +276,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { AfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), MapUtil.builder().put("deliveryName", express.getName()) .put("logisticsNo", deliveryReqVO.getLogisticsNo()).build()); - - // TODO 发送售后消息 } @Override @@ -299,8 +292,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.WAIT_REFUND.getStatus()); - - // TODO 发送售后消息 } @Override @@ -326,8 +317,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { AfterSaleStatusEnum.SELLER_REFUSE.getStatus(), MapUtil.of("reason", refuseReqVO.getRefuseMemo())); - // TODO 发送售后消息 - // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } @@ -365,33 +354,90 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 发起退款单。注意,需要在事务提交后,再进行发起,避免重复发起 createPayRefund(userIp, afterSale); - // 更新售后单的状态为【已完成】 - updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.WAIT_REFUND.getStatus(), new AfterSaleDO() - .setStatus(AfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); - // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), - AfterSaleStatusEnum.COMPLETE.getStatus()); - - // TODO 发送售后消息 - - // 更新交易订单项的售后状态为【已完成】 - tradeOrderUpdateService.updateOrderItemWhenAfterSaleSuccess(afterSale.getOrderItemId(), afterSale.getRefundPrice()); + afterSale.getStatus()); // 特殊:这里状态不变,而是最终 updateAfterSaleRefunded 处理!!! } private void createPayRefund(String userIp, AfterSaleDO afterSale) { - TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + // 创建退款单 + PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) + .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); + Long payRefundId = payRefundApi.createRefund(createReqDTO); - @Override - public void afterCommit() { - // 创建退款单 - PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) - .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); - Long payRefundId = payRefundApi.createRefund(createReqDTO); - // 更新售后单的退款单号 - tradeAfterSaleMapper.updateById(new AfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId)); - } - }); + // 更新售后单的退款单号 + tradeAfterSaleMapper.updateById(new AfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.SYSTEM_REFUND_SUCCESS) + public void updateAfterSaleRefunded(Long id, Long orderId, Long payRefundId) { + // 1. 校验售后单的状态,并状态待退款 + AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); + if (afterSale == null) { + throw exception(AFTER_SALE_NOT_FOUND); + } + if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.WAIT_REFUND.getStatus())) { + throw exception(AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND); + } + + // 2. 校验退款单 + PayRefundRespDTO payRefund = validatePayRefund(afterSale, payRefundId); + + // 3. 处理退款结果 + if (PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { + // 【情况一:退款成功】 + updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.WAIT_REFUND.getStatus(), new AfterSaleDO() + .setStatus(AfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); + + // 记录售后日志 + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.COMPLETE.getStatus()); + + // 更新交易订单项的售后状态为【已完成】 + tradeOrderUpdateService.updateOrderItemWhenAfterSaleSuccess(afterSale.getOrderItemId(), afterSale.getRefundPrice()); + // 【情况二:退款失败】 + } else if (PayRefundStatusEnum.isFailure(payRefund.getStatus())) { + // 记录售后日志 + AfterSaleLogUtils.setAfterSaleOperateType(AfterSaleOperateTypeEnum.SYSTEM_REFUND_FAIL); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), afterSale.getStatus()); + } + } + + /** + * 校验退款单的合法性 + * + * @param afterSale 售后单 + * @param payRefundId 退款单编号 + * @return 退款单 + */ + private PayRefundRespDTO validatePayRefund(AfterSaleDO afterSale, Long payRefundId) { + // 1. 校验退款单是否存在 + PayRefundRespDTO payRefund = payRefundApi.getRefund(payRefundId); + if (payRefund == null) { + log.error("[validatePayRefund][afterSale({}) payRefund({}) 不存在,请进行处理!]", afterSale.getId(), payRefundId); + throw exception(AFTER_SALE_REFUND_FAIL_REFUND_NOT_FOUND); + } + // 2.1 校验退款单无退款结果(成功、失败) + if (!PayRefundStatusEnum.isSuccess(payRefund.getStatus()) + && !PayRefundStatusEnum.isFailure(payRefund.getStatus())) { + log.error("[validatePayRefund][afterSale({}) payRefund({}) 无退款结果,请进行处理!payRefund 数据是:{}]", + afterSale.getId(), payRefundId, toJsonString(payRefund)); + throw exception(AFTER_SALE_REFUND_FAIL_REFUND_NOT_SUCCESS_OR_FAILURE); + } + // 2.2 校验退款金额一致 + if (ObjectUtil.notEqual(payRefund.getRefundPrice(), afterSale.getRefundPrice())) { + log.error("[validatePayRefund][afterSale({}) payRefund({}) 退款金额不匹配,请进行处理!afterSale 数据是:{},payRefund 数据是:{}]", + afterSale.getId(), payRefundId, toJsonString(afterSale), toJsonString(payRefund)); + throw exception(AFTER_SALE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); + } + // 2.3 校验退款订单匹配(二次) + if (ObjectUtil.notEqual(payRefund.getMerchantRefundId(), afterSale.getId().toString())) { + log.error("[validatePayRefund][afterSale({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", + afterSale.getId(), payRefundId, toJsonString(payRefund)); + throw exception(AFTER_SALE_REFUND_FAIL_REFUND_ORDER_ID_ERROR); + } + return payRefund; } @Override @@ -417,8 +463,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.BUYER_CANCEL.getStatus()); - // TODO 发送售后消息 - // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 4df5f3e085..353f75742b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -15,9 +15,6 @@ import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; -import cn.iocoder.yudao.module.system.api.social.SocialUserApi; -import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; -import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO; import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert; @@ -71,8 +68,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Resource private PayTransferApi payTransferApi; @Resource - private SocialUserApi socialUserApi; - @Resource private PayWalletApi payWalletApi; @Resource @@ -140,13 +135,8 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.ALIPAY_API.getType())) { channelCode = PayChannelEnum.ALIPAY_PC.getCode(); } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WECHAT_API.getType())) { - SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId( - UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_PROGRAM.getType()); - if (socialUser == null) { - throw exception(BROKERAGE_WITHDRAW_TRANSFER_FAIL_WECHAT_NOT_BIND); - } channelCode = PayChannelEnum.WX_LITE.getCode(); - userAccount = socialUser.getOpenid(); + userAccount = withdraw.getUserAccount(); // 特殊:微信需要有报备信息 channelExtras = PayTransferCreateReqDTO.buildWeiXinChannelExtra1000("佣金提现", "佣金提现"); } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WALLET.getType())) { @@ -158,7 +148,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { // 1.2 构建请求 PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode) - .setMerchantOrderId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) + .setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP()) .setChannelExtras(channelExtras); // 1.3 发起请求 @@ -293,7 +283,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH); } // 2.3 校验转账订单匹配 - if (ObjectUtil.notEqual(payTransfer.getMerchantOrderId(), withdraw.getId().toString())) { + if (ObjectUtil.notEqual(payTransfer.getMerchantTransferId(), withdraw.getId().toString())) { log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) 转账单不匹配({}),请进行处理!payTransfer 数据是:{}]", withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java index 59ad63acfb..408857d176 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java @@ -209,6 +209,14 @@ public interface TradeOrderUpdateService { */ void cancelPaidOrder(Long userId, Long orderId, Integer cancelType); + /** + * 取消支付订单的退款回调 + * + * @param id 订单编号 + * @param payRefundId 支付退款编号 + */ + void updatePaidOrderRefunded(Long id, Long payRefundId); + /** * 更新下单赠送的优惠券编号到订单 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index 030cc34317..9a59c1ace3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -20,7 +20,9 @@ import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi; import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; import cn.iocoder.yudao.module.system.api.social.SocialClientApi; @@ -938,10 +940,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { .setAppKey(tradeOrderProperties.getPayAppKey()) // 支付应用 .setUserIp(NetUtil.getLocalhostStr()) // 使用本机 IP,因为是服务器发起退款的 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 - .setMerchantRefundId(String.valueOf(order.getId())) + // 特殊:因为订单支持 AfterSale 单个售后退款,也支持整单退款,所以需要通过 order- 进行下区分 + // 具体可见 AfterSaleController 的 updateAfterSaleRefunded 方法 + .setMerchantRefundId("order-" + order.getId()) .setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice())); // 价格信息 } + @Override + public void updatePaidOrderRefunded(Long id, Long payRefundId) { + PayRefundRespDTO payRefund = payRefundApi.getRefund(payRefundId); + if (payRefund == null) { + throw exception(ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_NOT_FOUND); + } + // 特殊:因为在 cancelPaidOrder 已经进行订单的取消,所以这里必须退款成功!!! + if (!PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { + throw exception(ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_STATUS_NOT_SUCCESS); + } + } + @Override public void updateOrderGiveCouponIds(Long userId, Long orderId, List giveCouponIds) { // 1. 检验订单存在 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java index 29e670492c..6746c319fc 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java @@ -25,6 +25,12 @@ public class PayRefundNotifyReqDTO { @NotEmpty(message = "商户退款单编号不能为空") private String merchantOrderId; + /** + * 商户退款编号 + */ + @NotEmpty(message = "商户退款编号不能为空") + private String merchantRefundId; + /** * 支付退款编号 */ diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java index 982a3be75b..f3a92d8da9 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java @@ -23,7 +23,7 @@ public class PayTransferNotifyReqDTO { * 商户转账单号 */ @NotEmpty(message = "商户转账单号不能为空") - private String merchantOrderId; + private String merchantTransferId; /** * 转账订单编号 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundRespDTO.java index 0065cb4934..725f3911b4 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundRespDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundRespDTO.java @@ -42,9 +42,24 @@ public class PayRefundRespDTO { * 商户订单编号 */ private String merchantOrderId; + /** + * 商户退款编号 + */ + private String merchantRefundId; /** * 退款成功时间 */ private LocalDateTime successTime; + // ========== 渠道相关字段 ========== + + /** + * 调用渠道的错误码 + */ + private String channelErrorCode; + /** + * 调用渠道的错误提示 + */ + private String channelErrorMsg; + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java index ce92080191..1ac5c04af6 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java @@ -47,7 +47,7 @@ public class PayTransferCreateReqDTO { * 商户转账单编号 */ @NotEmpty(message = "商户转账单编号能为空") - private String merchantOrderId; + private String merchantTransferId; /** * 转账金额,单位:分 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java index cead3232c3..98abf5d3a0 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java @@ -31,7 +31,7 @@ public class PayTransferRespDTO { /** * 商户转账单编号 */ - private String merchantOrderId; + private String merchantTransferId; // ========== 转账相关字段 ========== diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/refund/PayRefundApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/refund/PayRefundApiImpl.java index 595f97d034..ccc538bc9b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/refund/PayRefundApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/refund/PayRefundApiImpl.java @@ -1,14 +1,14 @@ package cn.iocoder.yudao.module.pay.api.refund; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; -import cn.iocoder.yudao.module.pay.convert.refund.PayRefundConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; - /** * 退款单 API 实现类 * @@ -23,12 +23,13 @@ public class PayRefundApiImpl implements PayRefundApi { @Override public Long createRefund(PayRefundCreateReqDTO reqDTO) { - return payRefundService.createPayRefund(reqDTO); + return payRefundService.createRefund(reqDTO); } @Override public PayRefundRespDTO getRefund(Long id) { - return PayRefundConvert.INSTANCE.convert02(payRefundService.getRefund(id)); + PayRefundDO refund = payRefundService.getRefund(id); + return BeanUtils.toBean(refund, PayRefundRespDTO.class); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java index 25f0bf0f7b..f571d882af 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java @@ -66,7 +66,9 @@ public class PayDemoOrderController { @Operation(summary = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 public CommonResult updateDemoOrderRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { - payDemoOrderService.updateDemoOrderRefunded(Long.valueOf(notifyReqDTO.getMerchantOrderId()), + payDemoOrderService.updateDemoOrderRefunded( + Long.valueOf(notifyReqDTO.getMerchantOrderId()), + notifyReqDTO.getMerchantRefundId(), notifyReqDTO.getPayRefundId()); return success(true); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java index 251ec35ce7..033bc95d79 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java @@ -55,7 +55,7 @@ public class PayDemoWithdrawController { @Operation(summary = "更新示例提现单的转账状态") // 由 pay-module 转账服务,进行回调 @PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现 public CommonResult updateDemoWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { - demoWithdrawService.updateDemoWithdrawTransferred(Long.valueOf(notifyReqDTO.getMerchantOrderId()), + demoWithdrawService.updateDemoWithdrawTransferred(Long.valueOf(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId()); return success(true); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java index 3c1a86ec8f..048210169e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.notify; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; @@ -11,7 +12,6 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO; -import cn.iocoder.yudao.module.pay.convert.notify.PayNotifyTaskConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; @@ -138,7 +138,12 @@ public class PayNotifyController { // 拼接返回 PayAppDO app = appService.getApp(task.getAppId()); List logs = notifyService.getNotifyLogList(id); - return success(PayNotifyTaskConvert.INSTANCE.convert(task, app, logs)); + return success(BeanUtils.toBean(task, PayNotifyTaskDetailRespVO.class, respVO -> { + if (app != null) { + respVO.setAppName(app.getName()); + } + respVO.setLogs(BeanUtils.toBean(logs, PayNotifyTaskDetailRespVO.Log.class)); + })); } @GetMapping("/page") @@ -150,8 +155,15 @@ public class PayNotifyController { return success(PageResult.empty()); } // 拼接返回 - Map appMap = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTaskDO::getAppId)); - return success(PayNotifyTaskConvert.INSTANCE.convertPage(pageResult, appMap)); + Map apps = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTaskDO::getAppId)); + + // 转换对象 + return success(BeanUtils.toBean(pageResult, PayNotifyTaskRespVO.class, order -> { + PayAppDO app = apps.get(order.getAppId()); + if (app != null) { + order.setAppName(app.getName()); + } + })); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskBaseVO.java deleted file mode 100644 index 1e623751ba..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskBaseVO.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.admin.notify.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -/** - * 回调通知 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class PayNotifyTaskBaseVO { - - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10636") - private Long appId; - - @Schema(description = "通知类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Byte type; - - @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6722") - private Long dataId; - - @Schema(description = "通知状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Byte status; - - @Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26697") - private String merchantOrderId; - - @Schema(description = "下一次通知时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime nextNotifyTime; - - @Schema(description = "最后一次执行时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime lastExecuteTime; - - @Schema(description = "当前通知次数", requiredMode = Schema.RequiredMode.REQUIRED) - private Byte notifyTimes; - - @Schema(description = "最大可通知次数", requiredMode = Schema.RequiredMode.REQUIRED) - private Byte maxNotifyTimes; - - @Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn") - private String notifyUrl; - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java index 7c75613e21..739cedf1dc 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java @@ -13,19 +13,7 @@ import java.util.List; @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class PayNotifyTaskDetailRespVO extends PayNotifyTaskBaseVO { - - @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380") - private Long id; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - - @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime updateTime; - - @Schema(description = "应用名称", example = "wx_pay") - private String appName; +public class PayNotifyTaskDetailRespVO extends PayNotifyTaskRespVO { @Schema(description = "回调日志列表") private List logs; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java index 003d2fb336..f6dbc8402d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java @@ -32,6 +32,12 @@ public class PayNotifyTaskPageReqVO extends PageParam { @Schema(description = "商户订单编号", example = "26697") private String merchantOrderId; + @Schema(description = "商户退款编号", example = "26697") + private String merchantRefundId; + + @Schema(description = "商户转账编号", example = "26697") + private String merchantTransferId; + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java index d7f7fe6fb1..75228b1e8c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java @@ -6,17 +6,51 @@ import java.time.LocalDateTime; @Schema(description = "管理后台 - 回调通知 Response VO") @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayNotifyTaskRespVO extends PayNotifyTaskBaseVO { +public class PayNotifyTaskRespVO { @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380") private Long id; - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10636") + private Long appId; @Schema(description = "应用名称", example = "wx_pay") private String appName; + @Schema(description = "通知类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Byte type; + + @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6722") + private Long dataId; + + @Schema(description = "商户订单编号", example = "26697") + private String merchantOrderId; + + @Schema(description = "商户退款编号", example = "26697") + private String merchantRefundId; + + @Schema(description = "商户转账编号", example = "26697") + private String merchantTransferId; + + @Schema(description = "通知状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Byte status; + + @Schema(description = "下一次通知时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime nextNotifyTime; + + @Schema(description = "最后一次执行时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime lastExecuteTime; + + @Schema(description = "当前通知次数", requiredMode = Schema.RequiredMode.REQUIRED) + private Byte notifyTimes; + + @Schema(description = "最大可通知次数", requiredMode = Schema.RequiredMode.REQUIRED) + private Byte maxNotifyTimes; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime updateTime; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java index bfa7917a0e..c5e84aa700 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java @@ -37,8 +37,7 @@ public class PayWalletRechargeController { return success(true); } - // TODO @jason:发起退款,要 post 操作哈; - @GetMapping("/refund") + @PostMapping("/refund") @Operation(summary = "发起钱包充值退款") @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult refundWalletRecharge(@RequestParam("id") Long id) { @@ -51,7 +50,9 @@ public class PayWalletRechargeController { @PermitAll // 无需登录, 内部校验实现 public CommonResult updateWalletRechargeRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { walletRechargeService.updateWalletRechargeRefunded( - Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayRefundId()); + Long.valueOf(notifyReqDTO.getMerchantOrderId()), + Long.valueOf(notifyReqDTO.getMerchantRefundId()), + notifyReqDTO.getPayRefundId()); return success(true); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/notify/PayNotifyTaskConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/notify/PayNotifyTaskConvert.java deleted file mode 100644 index d0b8e36ff8..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/notify/PayNotifyTaskConvert.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.module.pay.convert.notify; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO; -import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO; -import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; - -/** - * 支付通知 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface PayNotifyTaskConvert { - - PayNotifyTaskConvert INSTANCE = Mappers.getMapper(PayNotifyTaskConvert.class); - - PayNotifyTaskRespVO convert(PayNotifyTaskDO bean); - - default PageResult convertPage(PageResult page, Map appMap){ - PageResult result = convertPage(page); - result.getList().forEach(order -> MapUtils.findAndThen(appMap, order.getAppId(), app -> order.setAppName(app.getName()))); - return result; - } - PageResult convertPage(PageResult page); - - default PayNotifyTaskDetailRespVO convert(PayNotifyTaskDO task, PayAppDO app, List logs) { - PayNotifyTaskDetailRespVO respVO = convert(task, logs); - if (app != null) { - respVO.setAppName(app.getName()); - } - return respVO; - } - PayNotifyTaskDetailRespVO convert(PayNotifyTaskDO task, List logs); -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java index 9f087f7029..c94aa00037 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; -import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundDetailsRespVO; import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExcelVO; import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageItemRespVO; @@ -42,8 +41,6 @@ public interface PayRefundConvert { PayRefundDO convert(PayRefundCreateReqDTO bean); - PayRefundRespDTO convert02(PayRefundDO bean); - default List convertList(List list, Map appMap) { return CollectionUtils.convertList(list, order -> { PayRefundExcelVO excelVO = convertExcel(order); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java index ec2c4a7046..92f1c8c4a2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -60,12 +61,21 @@ public class PayNotifyTaskDO extends TenantBaseDO { * * 1. {@link PayNotifyTypeEnum#ORDER} 时,关联 {@link PayOrderDO#getId()} * 2. {@link PayNotifyTypeEnum#REFUND} 时,关联 {@link PayRefundDO#getId()} + * 3. {@link PayNotifyTypeEnum#TRANSFER} 时,关联 {@link PayTransferDO#getId()} */ private Long dataId; /** * 商户订单编号 */ private String merchantOrderId; + /** + * 商户退款编号 + */ + private String merchantRefundId; + /** + * 商户转账编号 + */ + private String merchantTransferId; /** * 通知状态 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java index cadf815609..fe443e96e3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java @@ -63,7 +63,7 @@ public class PayTransferDO extends BaseDO { * * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一 */ - private String merchantOrderId; + private String merchantTransferId; // ========== 转账相关字段 ========== diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java index cc7701271c..a3e3effa3b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java @@ -37,6 +37,8 @@ public interface PayNotifyTaskMapper extends BaseMapperX { .eqIfPresent(PayNotifyTaskDO::getDataId, reqVO.getDataId()) .eqIfPresent(PayNotifyTaskDO::getStatus, reqVO.getStatus()) .eqIfPresent(PayNotifyTaskDO::getMerchantOrderId, reqVO.getMerchantOrderId()) + .eqIfPresent(PayNotifyTaskDO::getMerchantRefundId, reqVO.getMerchantRefundId()) + .eqIfPresent(PayNotifyTaskDO::getMerchantTransferId, reqVO.getMerchantTransferId()) .betweenIfPresent(PayNotifyTaskDO::getCreateTime, reqVO.getCreateTime()) .orderByDesc(PayNotifyTaskDO::getId)); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java index a3ee56c6e8..05f920900a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java @@ -28,7 +28,7 @@ public interface PayTransferMapper extends BaseMapperX { default PayTransferDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) { return selectOne(PayTransferDO::getAppId, appId, - PayTransferDO::getMerchantOrderId, merchantOrderId); + PayTransferDO::getMerchantTransferId, merchantOrderId); } default PageResult selectPage(PayTransferPageReqVO reqVO) { @@ -36,7 +36,7 @@ public interface PayTransferMapper extends BaseMapperX { .eqIfPresent(PayTransferDO::getNo, reqVO.getNo()) .eqIfPresent(PayTransferDO::getAppId, reqVO.getAppId()) .eqIfPresent(PayTransferDO::getChannelCode, reqVO.getChannelCode()) - .eqIfPresent(PayTransferDO::getMerchantOrderId, reqVO.getMerchantOrderId()) + .eqIfPresent(PayTransferDO::getMerchantTransferId, reqVO.getMerchantOrderId()) .eqIfPresent(PayTransferDO::getStatus, reqVO.getStatus()) .likeIfPresent(PayTransferDO::getUserName, reqVO.getUserName()) .eqIfPresent(PayTransferDO::getChannelTransferNo, reqVO.getChannelTransferNo()) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java index 512007e7dd..18de7b97d4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java @@ -59,8 +59,9 @@ public interface PayDemoOrderService { * 更新示例订单为已退款 * * @param id 编号 + * @param refundId 退款编号 * @param payRefundId 退款订单号 */ - void updateDemoOrderRefunded(Long id, Long payRefundId); + void updateDemoOrderRefunded(Long id, String refundId, Long payRefundId); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java index bf34278e3c..76571f355c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java @@ -184,7 +184,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { // 2.1 生成退款单号 // 一般来说,用户发起退款的时候,都会单独插入一个售后维权表,然后使用该表的 id 作为 refundId - // 这里我们是个简单的 demo,所以没有售后维权表,直接使用订单 id + "-refund" 来演示 + // 这里我们是个简单的 demo,所以没有售后维权表,直接使用订单 id + "-refund" 来演示 String refundId = order.getId() + "-refund"; // 2.2 创建退款单 Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() @@ -215,16 +215,18 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { } @Override - public void updateDemoOrderRefunded(Long id, Long payRefundId) { + public void updateDemoOrderRefunded(Long id, String refundId, Long payRefundId) { // 1. 校验并获得退款订单(可退款) - PayRefundRespDTO payRefund = validateDemoOrderCanRefunded(id, payRefundId); + PayRefundRespDTO payRefund = validateDemoOrderCanRefunded(id, refundId, payRefundId); // 2.2 更新退款单到 demo 订单 payDemoOrderMapper.updateById(new PayDemoOrderDO().setId(id) .setRefundTime(payRefund.getSuccessTime())); } - private PayRefundRespDTO validateDemoOrderCanRefunded(Long id, Long payRefundId) { + private PayRefundRespDTO validateDemoOrderCanRefunded(Long id, String refundId, Long payRefundId) { // 1.1 校验示例订单 + // 一般来说,这里应该用 refundId 来查询退款单,然后再校验订单是否匹配 + // 这里我们是个简单的 demo,所以没有售后维权表,直接使用订单 id 来查询订单 PayDemoOrderDO order = payDemoOrderMapper.selectById(id); if (order == null) { throw exception(DEMO_ORDER_NOT_FOUND); @@ -241,7 +243,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { if (payRefund == null) { throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND); } - // 2.2 + // 2.2 必须是退款成功状态 if (!PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS); } @@ -252,7 +254,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); } // 2.4 校验退款订单匹配(二次) - if (notEqual(payRefund.getMerchantOrderId(), id.toString())) { + if (notEqual(payRefund.getMerchantRefundId(), id.toString() + "-refund")) { log.error("[validateDemoOrderCanRefunded][order({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", id, payRefundId, toJsonString(payRefund)); throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 29e175c2a8..90e79db979 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -75,7 +75,7 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { // 2.1 创建支付单 PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 - .setMerchantOrderId(String.valueOf(withdraw.getId())) // 业务的订单编号 + .setMerchantTransferId(String.valueOf(withdraw.getId())) // 业务的订单编号 .setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 .setUserAccount(withdraw.getUserAccount()).setUserName(withdraw.getUserName()); // 收款信息 if (ObjectUtil.equal(withdraw.getType(), PayDemoWithdrawTypeEnum.WECHAT.getType())) { @@ -177,7 +177,7 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH); } // 2.3 校验转账订单匹配(二次) - if (ObjectUtil.notEqual(payTransfer.getMerchantOrderId(), withdraw.getId().toString())) { + if (ObjectUtil.notEqual(payTransfer.getMerchantTransferId(), withdraw.getId().toString())) { log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) 转账单不匹配({}),请进行处理!payTransfer 数据是:{}]", withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java index bf56680544..0956087675 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java @@ -31,6 +31,7 @@ import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; +import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -97,19 +98,19 @@ public class PayNotifyServiceImpl implements PayNotifyService { PayNotifyTaskDO task = new PayNotifyTaskDO().setType(type).setDataId(dataId); task.setStatus(PayNotifyStatusEnum.WAITING.getStatus()).setNextNotifyTime(LocalDateTime.now()) .setNotifyTimes(0).setMaxNotifyTimes(PayNotifyTaskDO.NOTIFY_FREQUENCY.length + 1); - // 补充 appId + notifyUrl 字段 + // 补充 appId + notifyUrl + merchant* 字段 if (Objects.equals(task.getType(), PayNotifyTypeEnum.ORDER.getType())) { PayOrderDO order = orderService.getOrder(task.getDataId()); // 不进行非空判断,有问题直接异常 - task.setAppId(order.getAppId()). - setMerchantOrderId(order.getMerchantOrderId()).setNotifyUrl(order.getNotifyUrl()); + task.setAppId(order.getAppId()).setNotifyUrl(order.getNotifyUrl()) + .setMerchantOrderId(order.getMerchantOrderId()); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) { - PayRefundDO refundDO = refundService.getRefund(task.getDataId()); - task.setAppId(refundDO.getAppId()) - .setMerchantOrderId(refundDO.getMerchantOrderId()).setNotifyUrl(refundDO.getNotifyUrl()); + PayRefundDO refund = refundService.getRefund(task.getDataId()); + task.setAppId(refund.getAppId()).setNotifyUrl(refund.getNotifyUrl()) + .setMerchantOrderId(refund.getMerchantOrderId()).setMerchantRefundId(refund.getMerchantRefundId()); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.TRANSFER.getType())) { PayTransferDO transfer = transferService.getTransfer(task.getDataId()); - task.setAppId(transfer.getAppId()) - .setMerchantOrderId(transfer.getMerchantOrderId()).setNotifyUrl(transfer.getNotifyUrl()); + task.setAppId(transfer.getAppId()).setNotifyUrl(transfer.getNotifyUrl()) + .setMerchantTransferId(transfer.getMerchantTransferId()); } // 执行插入 @@ -117,10 +118,13 @@ public class PayNotifyServiceImpl implements PayNotifyService { // 必须在事务提交后,在发起任务,否则 PayNotifyTaskDO 还没入库,就提前回调接入的业务 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + @Override public void afterCommit() { - executeNotify(task); + // 异步的原因:避免阻塞当前事务,无需等待结果 + getSelf().executeNotifyAsync(task); } + }); } @@ -166,7 +170,17 @@ public class PayNotifyServiceImpl implements PayNotifyService { } /** - * 同步执行单个支付通知 + * 异步执行单个支付通知 + * + * @param task 通知任务 + */ + @Async + public void executeNotifyAsync(PayNotifyTaskDO task) { + executeNotify(task); + } + + /** + * 【加锁】执行单个支付通知 * * @param task 通知任务 */ @@ -223,9 +237,10 @@ public class PayNotifyServiceImpl implements PayNotifyService { .payOrderId(task.getDataId()).build(); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) { request = PayRefundNotifyReqDTO.builder().merchantOrderId(task.getMerchantOrderId()) + .merchantRefundId(task.getMerchantRefundId()) .payRefundId(task.getDataId()).build(); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.TRANSFER.getType())) { - request = PayTransferNotifyReqDTO.builder().merchantOrderId(task.getMerchantOrderId()) + request = PayTransferNotifyReqDTO.builder().merchantTransferId(task.getMerchantTransferId()) .payTransferId(task.getDataId()).build(); } else { throw new RuntimeException("未知的通知任务类型:" + JsonUtils.toJsonString(task)); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java index 258cea9640..bf872eb8e8 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java @@ -62,7 +62,7 @@ public interface PayRefundService { * @param reqDTO 退款申请信息 * @return 退款单号 */ - Long createPayRefund(PayRefundCreateReqDTO reqDTO); + Long createRefund(PayRefundCreateReqDTO reqDTO); /** * 渠道的退款通知 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java index 8df7f88615..57ada01bc2 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java @@ -91,7 +91,7 @@ public class PayRefundServiceImpl implements PayRefundService { } @Override - public Long createPayRefund(PayRefundCreateReqDTO reqDTO) { + public Long createRefund(PayRefundCreateReqDTO reqDTO) { // 1.1 校验 App PayAppDO app = appService.validPayApp(reqDTO.getAppKey()); // 1.2 校验支付订单 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 677d5c657c..42f77e6298 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -116,7 +116,7 @@ public class PayTransferServiceImpl implements PayTransferService { } private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO reqDTO, Long appId) { - PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantOrderId(appId, reqDTO.getMerchantOrderId()); + PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantOrderId(appId, reqDTO.getMerchantTransferId()); if (transfer != null) { // 只有转账单状态为关闭,才能再次发起转账 if (!PayTransferStatusEnum.isClosed(transfer.getStatus())) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java index f2de1677bd..f2ab50ed68 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargePackageDO; /** * 钱包充值 Service 接口 @@ -16,7 +15,7 @@ public interface PayWalletRechargeService { /** * 创建钱包充值记录(发起充值) * - * @param userId 用户 id + * @param userId 用户编号 * @param userType 用户类型 * @param createReqVO 钱包充值请求 VO * @param userIp 用户Ip @@ -40,8 +39,8 @@ public interface PayWalletRechargeService { /** * 更新钱包充值成功 * - * @param id 钱包充值记录 id - * @param payOrderId 支付订单 id + * @param id 钱包充值记录编号 + * @param payOrderId 支付订单编号 */ void updateWalletRechargerPaid(Long id, Long payOrderId); @@ -56,9 +55,10 @@ public interface PayWalletRechargeService { /** * 更新钱包充值记录为已退款 * - * @param id 钱包充值 id + * @param id 钱包充值记录编号 + * @param refundId 钱包充值退款编号(实际和 id 相同) * @param payRefundId 退款单id */ - void updateWalletRechargeRefunded(Long id, Long payRefundId); + void updateWalletRechargeRefunded(Long id, Long refundId, Long payRefundId); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java index d7144f60e3..9f575d7c27 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java @@ -8,10 +8,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargePackageDO; @@ -21,7 +22,6 @@ import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; -import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import cn.iocoder.yudao.module.system.api.social.SocialClientApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialWxaSubscribeMessageSendReqDTO; import jakarta.annotation.Resource; @@ -61,13 +61,15 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { private PayWalletService payWalletService; @Resource private PayOrderService payOrderService; - @Resource - private PayRefundService payRefundService; +// @Resource +// private PayRefundService payRefundService; @Resource private PayWalletRechargePackageService payWalletRechargePackageService; @Resource public SocialClientApi socialClientApi; + @Resource + private PayRefundApi payRefundApi; @Resource private PayProperties payProperties; @@ -186,7 +188,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { // 3. 创建退款单 String walletRechargeId = String.valueOf(id); String refundId = walletRechargeId + "-refund"; - Long payRefundId = payRefundService.createPayRefund(new PayRefundCreateReqDTO() + Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp) .setMerchantOrderId(walletRechargeId) .setMerchantRefundId(refundId) @@ -199,18 +201,20 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @Override @Transactional(rollbackFor = Exception.class) - public void updateWalletRechargeRefunded(Long id, Long payRefundId) { + public void updateWalletRechargeRefunded(Long id, Long refundId, Long payRefundId) { // 1.1 获取钱包充值记录 + // 说明:因为 id 和 refundId 是相同的,所以直接使用 id 查询即可! PayWalletRechargeDO walletRecharge = walletRechargeMapper.selectById(id); if (walletRecharge == null) { log.error("[updateWalletRechargerPaid][钱包充值记录不存在,钱包充值记录 id({})]", id); throw exception(WALLET_RECHARGE_NOT_FOUND); } // 1.2 校验钱包充值是否可以更新已退款 - PayRefundDO payRefund = validateWalletRechargeCanRefunded(walletRecharge, payRefundId); + PayRefundRespDTO payRefund = validateWalletRechargeCanRefunded(walletRecharge, payRefundId); + // 2. 处理退款结果 PayWalletRechargeDO updateObj = new PayWalletRechargeDO().setId(id); - // 退款成功 + // 情况一:退款成功 if (PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { // 2.1 更新钱包余额 payWalletService.reduceWalletBalance(walletRecharge.getWalletId(), id, @@ -219,19 +223,19 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { updateObj.setRefundStatus(SUCCESS.getStatus()).setRefundTime(payRefund.getSuccessTime()) .setRefundTotalPrice(walletRecharge.getTotalPrice()).setRefundPayPrice(walletRecharge.getPayPrice()) .setRefundBonusPrice(walletRecharge.getBonusPrice()); - } - // 退款失败 - if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) { + // 情况二:退款失败 + } else if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) { // 2.2 解冻余额 payWalletService.unfreezePrice(walletRecharge.getWalletId(), walletRecharge.getTotalPrice()); updateObj.setRefundStatus(FAILURE.getStatus()); } + // 3. 更新钱包充值的退款字段 walletRechargeMapper.updateByIdAndRefunded(id, WAITING.getStatus(), updateObj); } - private PayRefundDO validateWalletRechargeCanRefunded(PayWalletRechargeDO walletRecharge, Long payRefundId) { + private PayRefundRespDTO validateWalletRechargeCanRefunded(PayWalletRechargeDO walletRecharge, Long payRefundId) { // 1. 校验退款订单匹配 if (notEqual(walletRecharge.getPayRefundId(), payRefundId)) { log.error("[validateWalletRechargeCanRefunded][钱包充值({}) 退款单不匹配({}),请进行处理!钱包充值的数据是:{}]", @@ -240,7 +244,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { } // 2.1 校验退款订单 - PayRefundDO payRefund = payRefundService.getRefund(payRefundId); + PayRefundRespDTO payRefund = payRefundApi.getRefund(payRefundId); if (payRefund == null) { log.error("[validateWalletRechargeCanRefunded][payRefund({})不存在]", payRefundId); throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_NOT_FOUND); @@ -252,7 +256,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); } // 2.3 校验退款订单商户订单是否匹配 - if (notEqual(payRefund.getMerchantOrderId(), walletRecharge.getId().toString())) { + if (notEqual(payRefund.getMerchantRefundId(), walletRecharge.getId().toString())) { log.error("[validateWalletRechargeCanRefunded][钱包({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", walletRecharge.getId(), payRefundId, toJsonString(payRefund)); throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_ORDER_ID_ERROR); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java index c001336fc3..adbf480d2a 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java @@ -215,7 +215,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(appService.validPayApp(eq("demo"))).thenReturn(app); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), PAY_ORDER_NOT_FOUND); } @@ -241,7 +241,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), PAY_ORDER_REFUND_FAIL_STATUS_ERROR); } @@ -260,7 +260,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), REFUND_PRICE_EXCEED); } @@ -283,7 +283,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { refundMapper.insert(refund); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), REFUND_PRICE_EXCEED); } @@ -307,7 +307,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(channelService.validPayChannel(eq(1L))).thenReturn(channel); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), CHANNEL_NOT_FOUND); } @@ -339,7 +339,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { refundMapper.insert(refund); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), REFUND_EXISTS); } @@ -369,7 +369,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(client.unifiedRefund(any(PayRefundUnifiedReqDTO.class))).thenThrow(new RuntimeException()); // 调用 - Long refundId = refundService.createPayRefund(reqDTO); + Long refundId = refundService.createRefund(reqDTO); // 断言 PayRefundDO refundDO = refundMapper.selectById(refundId); assertPojoEquals(reqDTO, refundDO); @@ -422,7 +422,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { }))).thenReturn(refundRespDTO); // 调用 - Long refundId = refundService.createPayRefund(reqDTO); + Long refundId = refundService.createRefund(reqDTO); // 断言 PayRefundDO refundDO = refundMapper.selectById(refundId); assertPojoEquals(reqDTO, refundDO);