From bcc2ff0f5bee343442898dcc17306b197552c08a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 25 Dec 2021 20:40:49 +0800 Subject: [PATCH] code review 退款逻辑 --- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayCommonCoreService.java | 25 ------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java | 2 -- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundChannelPostHandler.java | 6 ++++-- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java | 7 +++---- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundPostReqBO.java | 1 + yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundReqBO.java | 2 ++ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundRespBO.java | 1 + yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayCommonCoreServiceImpl.java | 62 -------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelFailedHandler.java | 62 -------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelNotifyHandler.java | 45 --------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelQueryHandler.java | 56 -------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelRetryHandler.java | 50 -------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelSuccessHandler.java | 64 ---------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java | 55 ++++++++++++++++++++++++------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelFailedHandler.java | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelNotifyHandler.java | 45 +++++++++++++++++++++++++++++++++++++++++++++ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelQueryHandler.java | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelRetryHandler.java | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelSuccessHandler.java | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java | 11 +++++++---- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java | 48 ++++++++++++++++++++++++++++-------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java | 3 ++- 22 files changed, 349 insertions(+), 428 deletions(-) delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayCommonCoreService.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayCommonCoreServiceImpl.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelFailedHandler.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelNotifyHandler.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelQueryHandler.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelRetryHandler.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelSuccessHandler.java create mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelFailedHandler.java create mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelNotifyHandler.java create mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelQueryHandler.java create mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelRetryHandler.java create mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelSuccessHandler.java diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayCommonCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayCommonCoreService.java deleted file mode 100644 index 38d1c7a..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayCommonCoreService.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order; - -import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; - -/** - * 支付通用 Core Service - * - * @author jason - */ -public interface PayCommonCoreService { - - /** - * 验证是否是渠道通知 - * @param notifyData 通知数据 - */ - void verifyNotifyData(Long channelId, PayNotifyDataDTO notifyData); - - /** - * 支付宝的支付回调通知,和退款回调通知 地址是同一个 - * 是否是退款回调通知 - * @param notifyData 通知数据 - * @return - */ - boolean isRefundNotify(Long channelId, PayNotifyDataDTO notifyData); -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java index 9a7b95f..07e6592 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java @@ -47,6 +47,4 @@ public interface PayOrderCoreService { */ void notifyPayOrder(Long channelId, PayNotifyDataDTO notifyData) throws Exception; - - } diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundChannelPostHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundChannelPostHandler.java index e99d46e..59ea07b 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundChannelPostHandler.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundChannelPostHandler.java @@ -5,19 +5,21 @@ import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; /** * 支付退款订单 ,渠道返回后 后置处理 + * * @author jason */ public interface PayRefundChannelPostHandler { /** * 支持的渠道返回值 + * * @return 支持的渠道返回值数组 */ PayChannelRespEnum[] supportHandleResp(); - /** - * 根据渠道返回, 处理支付退款单 + * 根据渠道返回,处理支付退款单 + * * @param respBO */ void handleRefundChannelResp(PayRefundPostReqBO respBO); diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java index adfd768..e6c1422 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java @@ -11,23 +11,22 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; */ public interface PayRefundCoreService { - + // TODO @jason:方法名改成,submitRefundOrder,发起退款订单。这样和发起支付单,保持一致 /** * 提交退款申请 + * * @param reqDTO 退款申请信息 * @return 退款申请返回信息 */ PayRefundRespBO refund(PayRefundReqBO reqDTO); - /** * 渠道的退款通知 + * * @param channelId 渠道编号 * @param notifyData 通知数据 * @throws Exception 退款通知异常 */ void notifyPayRefund(Long channelId, PayNotifyDataDTO notifyData) throws Exception; - - } diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundPostReqBO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundPostReqBO.java index 4ff7eb1..6d5ecaf 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundPostReqBO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundPostReqBO.java @@ -8,6 +8,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +// TODO @jason:改到 dto 哈。我们项目,统一使用 DTO @Data @Accessors(chain = true) @Builder diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundReqBO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundReqBO.java index 86fc9c1..526e86b 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundReqBO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundReqBO.java @@ -5,6 +5,8 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; + +// TODO @jason:改到 dto 哈。我们项目,统一使用 DTO /** * 退款申请单 Request DTO */ diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundRespBO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundRespBO.java index f66090a..037c626 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundRespBO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/bo/PayRefundRespBO.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +// TODO @jason:改到 dto 哈。我们项目,统一使用 DTO /** * 退款申请单 Response DTO */ diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayCommonCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayCommonCoreServiceImpl.java deleted file mode 100644 index 3825c51..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayCommonCoreServiceImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayChannelCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayCommonCoreService; -import cn.iocoder.yudao.framework.pay.core.client.PayClient; -import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_CHANNEL_CLIENT_NOT_FOUND; -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_CHANNEL_NOTIFY_VERIFY_FAILED; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; - -/** - * 支付通用 Core Service 实现类 - * - * @author jason - */ -@Service -@Slf4j -public class PayCommonCoreServiceImpl implements PayCommonCoreService { - - @Resource - private PayChannelCoreService payChannelCoreService; - - @Resource - private PayClientFactory payClientFactory; - - @Override - public void verifyNotifyData(Long channelId, PayNotifyDataDTO notifyData) { - // 校验支付渠道是否有效 - PayChannelDO channel = payChannelCoreService.validPayChannel(channelId); - // 校验支付客户端是否正确初始化 - PayClient client = payClientFactory.getPayClient(channel.getId()); - if (client == null) { - log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); - } - boolean verifyResult = client.verifyNotifyData(notifyData); - if(!verifyResult){ - //渠道通知验证失败 - throw exception(PAY_CHANNEL_NOTIFY_VERIFY_FAILED); - } - } - - @Override - public boolean isRefundNotify(Long channelId, PayNotifyDataDTO notifyData) { - // 校验支付渠道是否有效 - PayChannelDO channel = payChannelCoreService.validPayChannel(channelId); - // 校验支付客户端是否正确初始化 - PayClient client = payClientFactory.getPayClient(channel.getId()); - if (client == null) { - log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); - } - return client.isRefundNotify(notifyData); - } -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelFailedHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelFailedHandler.java deleted file mode 100644 index 86110e7..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelFailedHandler.java +++ /dev/null @@ -1,62 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.util.Optional; - -/** - * 支付退款订单渠道返回失败的后置处理类 - * {@link PayChannelRespEnum#CALL_EXCEPTION} - * {@link PayChannelRespEnum#CAN_NOT_RETRY_FAILURE} - */ -@Service -public class PayRefundChannelFailedHandler extends PayRefundAbstractChannelPostHandler { - - @Resource - private PayNotifyCoreService payNotifyCoreService; - - public PayRefundChannelFailedHandler(PayOrderCoreMapper payOrderCoreMapper, PayRefundCoreMapper payRefundMapper) { - super(payOrderCoreMapper, payRefundMapper); - } - - @Override - public PayChannelRespEnum[] supportHandleResp() { - return new PayChannelRespEnum[] {PayChannelRespEnum.CALL_EXCEPTION, PayChannelRespEnum.CAN_NOT_RETRY_FAILURE}; - } - - - @Override - public void handleRefundChannelResp(PayRefundPostReqBO respBO) { - //退款失败 - //更新退款单表 - PayRefundDO updateRefundDO = new PayRefundDO(); - - updateRefundDO.setId(respBO.getRefundId()) - .setStatus(PayRefundStatusEnum.FAILURE.getStatus()) - .setChannelErrorCode(respBO.getChannelErrCode()) - .setChannelErrorMsg(Optional.ofNullable(respBO.getChannelErrMsg()) - .orElse(respBO.getExceptionMsg())); - updatePayRefund(updateRefundDO); - PayOrderDO updateOrderDO = new PayOrderDO(); - //更新订单表 - updateOrderDO.setId(respBO.getOrderId()) - .setRefundTimes(respBO.getRefundedTimes() + 1); - updatePayOrder(updateOrderDO); - // 立刻插入退款通知记录 - // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调 - payNotifyCoreService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() - .type(PayNotifyTypeEnum.REFUND.getType()).dataId(respBO.getRefundId()).build()); - } -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelNotifyHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelNotifyHandler.java deleted file mode 100644 index 6b994de..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelNotifyHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; -import org.springframework.stereotype.Service; - -/** - * 支付退款订单渠道返回通知 {@link PayChannelRespEnum#PROCESSING_NOTIFY},后置处理类 - * 支付宝退款单好像没有回调, 微信会触发回调 - */ -@Service -public class PayRefundChannelNotifyHandler extends PayRefundAbstractChannelPostHandler { - - public PayRefundChannelNotifyHandler(PayOrderCoreMapper payOrderCoreMapper, - PayRefundCoreMapper payRefundMapper) { - super(payOrderCoreMapper, payRefundMapper); - } - - @Override - public PayChannelRespEnum[] supportHandleResp() { - return new PayChannelRespEnum[] {PayChannelRespEnum.PROCESSING_NOTIFY}; - } - - @Override - public void handleRefundChannelResp(PayRefundPostReqBO respBO) { - PayRefundDO updateRefundDO = new PayRefundDO(); - //更新退款单表 - updateRefundDO.setId(respBO.getRefundId()) - .setStatus(PayRefundStatusEnum.PROCESSING_NOTIFY.getStatus()); - updatePayRefund(updateRefundDO); - - PayOrderDO updateOrderDO = new PayOrderDO(); - //更新订单表 - updateOrderDO.setId(respBO.getOrderId()) - .setRefundTimes(respBO.getRefundedTimes() + 1); - updatePayOrder(updateOrderDO); - - } -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelQueryHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelQueryHandler.java deleted file mode 100644 index 6464341..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelQueryHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; -import org.springframework.stereotype.Service; - -import java.util.Objects; - -/** - * 支付退款订单渠道返回需调用查询接口的后置处理类 - * {@link PayChannelRespEnum#PROCESSING_QUERY} //TODO 芋道源码 是不是微信有这样的情况 - * {@link PayChannelRespEnum#READ_TIME_OUT_EXCEPTION} - */ -@Service -public class PayRefundChannelQueryHandler extends PayRefundAbstractChannelPostHandler { - - - public PayRefundChannelQueryHandler(PayOrderCoreMapper payOrderCoreMapper, - PayRefundCoreMapper payRefundMapper) { - super(payOrderCoreMapper, payRefundMapper); - } - - @Override - public PayChannelRespEnum[] supportHandleResp() { - return new PayChannelRespEnum[]{PayChannelRespEnum.PROCESSING_QUERY, PayChannelRespEnum.READ_TIME_OUT_EXCEPTION}; - } - - @Override - public void handleRefundChannelResp(PayRefundPostReqBO respBO) { - final PayChannelRespEnum respEnum = respBO.getRespEnum(); - PayRefundStatusEnum refundStatus = - Objects.equals(PayChannelRespEnum.PROCESSING_QUERY, respEnum) ? PayRefundStatusEnum.PROCESSING_QUERY - : PayRefundStatusEnum.UNKNOWN_QUERY; - //更新退款单表 - PayRefundDO updateRefundDO = new PayRefundDO(); - updateRefundDO.setId(respBO.getRefundId()) - .setStatus(refundStatus.getStatus()) - .setChannelErrorCode(respBO.getChannelErrCode()) - .setChannelErrorMsg(respBO.getChannelErrMsg()); - updatePayRefund(updateRefundDO); - - PayOrderDO updateOrderDO = new PayOrderDO(); - //更新订单表 - updateOrderDO.setId(respBO.getOrderId()) - .setRefundTimes(respBO.getRefundedTimes() + 1); - updatePayOrder(updateOrderDO); - - //TODO 发起查询任务 - } -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelRetryHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelRetryHandler.java deleted file mode 100644 index 874dc65..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelRetryHandler.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; -import org.springframework.stereotype.Service; - -/** - * 支付退款订单渠道返回重试的后置处理类 - * {@link PayChannelRespEnum#RETRY_FAILURE} - */ -@Service -public class PayRefundChannelRetryHandler extends PayRefundAbstractChannelPostHandler { - - - public PayRefundChannelRetryHandler(PayOrderCoreMapper payOrderCoreMapper, - PayRefundCoreMapper payRefundMapper) { - super(payOrderCoreMapper, payRefundMapper); - } - - @Override - public PayChannelRespEnum[] supportHandleResp() { - return new PayChannelRespEnum[] {PayChannelRespEnum.RETRY_FAILURE}; - } - - @Override - public void handleRefundChannelResp(PayRefundPostReqBO respBO) { - - PayRefundDO updateRefundDO = new PayRefundDO(); - //更新退款单表 - updateRefundDO.setId(respBO.getRefundId()) - .setStatus(PayRefundStatusEnum.UNKNOWN_RETRY.getStatus()) - .setChannelErrorCode(respBO.getChannelErrCode()) - .setChannelErrorMsg(respBO.getChannelErrMsg()); - updatePayRefund(updateRefundDO); - - PayOrderDO updateOrderDO = new PayOrderDO(); - //更新订单表 - updateOrderDO.setId(respBO.getOrderId()) - .setRefundTimes(respBO.getRefundedTimes() + 1); - updatePayOrder(updateOrderDO); - - //TODO 发起重试任务 - } -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelSuccessHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelSuccessHandler.java deleted file mode 100644 index f41edcb..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelSuccessHandler.java +++ /dev/null @@ -1,64 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.util.Date; -/** - * 支付退款订单渠道返回退款成功的后置处理类 - * {@link PayChannelRespEnum#SYNC_SUCCESS} - */ -@Service -public class PayRefundChannelSuccessHandler extends PayRefundAbstractChannelPostHandler { - - - @Resource - private PayNotifyCoreService payNotifyCoreService; - - - public PayRefundChannelSuccessHandler(PayOrderCoreMapper payOrderCoreMapper, - PayRefundCoreMapper payRefundMapper) { - super(payOrderCoreMapper, payRefundMapper); - } - - @Override - public PayChannelRespEnum[] supportHandleResp() { - return new PayChannelRespEnum[]{PayChannelRespEnum.SYNC_SUCCESS}; - } - - @Override - public void handleRefundChannelResp(PayRefundPostReqBO respBO) { - //退款成功 - PayRefundDO updateRefundDO = new PayRefundDO(); - //更新退款单表 - updateRefundDO.setId(respBO.getRefundId()) - .setStatus(PayRefundStatusEnum.SUCCESS.getStatus()) - .setChannelRefundNo(respBO.getChannelRefundNo()) - .setSuccessTime(new Date()); - updatePayRefund(updateRefundDO); - - PayOrderDO updateOrderDO = new PayOrderDO(); - //更新订单表 - updateOrderDO.setId(respBO.getOrderId()) - .setRefundTimes(respBO.getRefundedTimes() + 1) - .setRefundStatus(respBO.getRefundTypeEnum().getStatus()) - .setRefundAmount(respBO.getRefundedAmount()+respBO.getRefundAmount()); - updatePayOrder(updateOrderDO); - - // 立刻插入退款通知记录 - // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调 - payNotifyCoreService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() - .type(PayNotifyTypeEnum.REFUND.getType()).dataId(respBO.getRefundId()).build()); - } -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java index b7eae8b..8d68964 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java @@ -50,18 +50,17 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { @Resource private PayOrderCoreMapper payOrderCoreMapper; - @Resource private PayRefundCoreMapper payRefundCoreMapper; - @Resource private PayOrderExtensionCoreMapper payOrderExtensionCoreMapper; @Resource private PayAppCoreService payAppCoreService; - @Resource private PayChannelCoreService payChannelCoreService; + @Resource + private PayNotifyCoreService payNotifyCoreService; @Resource private PayClientFactory payClientFactory; @@ -72,25 +71,18 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { @Resource private List handlerList; - @Resource - private PayNotifyCoreService payNotifyCoreService; - - + // TODO @json:mapHandlers private final EnumMap mapHandler = new EnumMap<>(PayChannelRespEnum.class); - - @PostConstruct public void init(){ - if (Objects.nonNull(handlerList)) { - handlerList.forEach(t->{ - for (PayChannelRespEnum item : t.supportHandleResp()) { - mapHandler.put(item, t); + handlerList.forEach(handler -> { + for (PayChannelRespEnum item : handler.supportHandleResp()) { + mapHandler.put(item, handler); } }); } - } @Override @@ -113,16 +105,16 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); } - //校验退款的条件 + // 校验退款的条件 validatePayRefund(reqBO, order); - //退款类型 + // 退款类型 PayRefundTypeEnum refundType = PayRefundTypeEnum.SOME; if (Objects.equals(reqBO.getAmount(), order.getAmount())) { refundType = PayRefundTypeEnum.ALL; } - //退款单入库 退款单状态:生成, 没有和渠道产生交互 + // 退款单入库 退款单状态:生成, 没有和渠道产生交互 PayOrderExtensionDO orderExtensionDO = payOrderExtensionCoreMapper.selectById(order.getSuccessExtensionId()); PayRefundDO refundDO = PayRefundDO.builder().channelOrderNo(order.getChannelOrderNo()) .appId(order.getAppId()) @@ -144,9 +136,9 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { .reqNo(PaySeqUtils.genRefundReqNo()) .type(refundType.getStatus()) .build(); - payRefundCoreMapper.insert(refundDO); + // TODO @jason:可以把“调用渠道进行退款"写到这里,这样分块更明确 PayRefundUnifiedReqDTO unifiedReqDTO = PayRefundUnifiedReqDTO.builder() .userIp(reqBO.getUserIp()) .channelOrderNo(refundDO.getChannelOrderNo()) @@ -156,13 +148,14 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { .reason(refundDO.getReason()) .build(); - //调用渠道进行退款 + // 调用渠道进行退款 PayRefundUnifiedRespDTO refundUnifiedRespDTO = client.unifiedRefund(unifiedReqDTO); - //根据渠道返回,获取退款后置处理,由postHandler 进行处理 + // TODO @jason:下面这块,是一整块逻辑,不要空开。不然阅读的时候,会以为不是一块逻辑 + // 根据渠道返回,获取退款后置处理,由postHandler 进行处理 PayRefundChannelPostHandler payRefundChannelPostHandler = mapHandler.get(refundUnifiedRespDTO.getRespEnum()); - if(Objects.isNull(payRefundChannelPostHandler)){ + if (Objects.isNull(payRefundChannelPostHandler)) { throw exception(PAY_REFUND_POST_HANDLER_NOT_FOUND); } @@ -192,11 +185,12 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); } - //解析渠道退款通知数据, 统一处理 + // 解析渠道退款通知数据, 统一处理 PayRefundNotifyDTO refundNotify = client.parseRefundNotify(notifyData); - if(Objects.equals(PayNotifyRefundStatusEnum.SUCCESS,refundNotify.getStatus())){ - //退款成功。 支付宝只有退款成功才会发通知 + // TODO @jason:抽一个 notifyPayRefundSuccess 方法 + if (Objects.equals(PayNotifyRefundStatusEnum.SUCCESS,refundNotify.getStatus())){ + // 退款成功。 支付宝只有退款成功才会发通知 PayRefundDO refundDO = payRefundCoreMapper.selectByReqNo(refundNotify.getReqNo()); if (refundDO == null) { log.error("不存在 seqNo 为{} 的支付退款单",refundNotify.getReqNo()); @@ -208,9 +202,9 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { if(PayRefundTypeEnum.ALL.getStatus().equals(type)){ orderStatus = PayOrderStatusEnum.CLOSED; } - //更新支付订单 + // 更新支付订单 PayOrderDO payOrderDO = payOrderCoreMapper.selectById(refundDO.getOrderId()); - //需更新已退金额 + // 需更新已退金额 Long refundedAmount = payOrderDO.getRefundAmount(); PayOrderDO updateOrderDO = new PayOrderDO(); updateOrderDO.setId(refundDO.getOrderId()) @@ -219,7 +213,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { .setRefundStatus(type); payOrderCoreMapper.updateById(updateOrderDO); - //跟新退款订单 + // 跟新退款订单 PayRefundDO updateRefundDO = new PayRefundDO(); updateRefundDO.setId(refundDO.getId()) .setSuccessTime(refundNotify.getRefundSuccessTime()) @@ -233,10 +227,9 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调 payNotifyCoreService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refundDO.getId()).build()); - }else{ + } else { //TODO 退款失败 } - } /** @@ -245,7 +238,6 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { * @param order 原始支付订单信息 */ private void validatePayRefund(PayRefundReqBO reqBO, PayOrderDO order) { - // 校验状态,必须是支付状态 if (!PayOrderStatusEnum.SUCCESS.getStatus().equals(order.getStatus())) { throw exception(PAY_ORDER_STATUS_IS_NOT_SUCCESS); @@ -258,10 +250,11 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { if(reqBO.getAmount() + order.getRefundAmount() > order.getAmount()){ throw exception(PAY_REFUND_AMOUNT_EXCEED); } - //校验渠道订单号 + // 校验渠道订单号 if (StrUtil.isEmpty(order.getChannelOrderNo())) { throw exception(PAY_REFUND_CHN_ORDER_NO_IS_NULL); } //TODO 退款的期限 退款次数的控制 } + } diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelFailedHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelFailedHandler.java new file mode 100644 index 0000000..35066eb --- /dev/null +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelFailedHandler.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl.handler; + +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; +import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService; +import cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Optional; + +/** + * 支付退款订单渠道返回失败的后置处理类 + * {@link PayChannelRespEnum#CALL_EXCEPTION} + * {@link PayChannelRespEnum#CAN_NOT_RETRY_FAILURE} + */ +@Service +public class PayRefundChannelFailedHandler extends PayRefundAbstractChannelPostHandler { + + @Resource + private PayNotifyCoreService payNotifyCoreService; + + public PayRefundChannelFailedHandler(PayOrderCoreMapper payOrderCoreMapper, PayRefundCoreMapper payRefundMapper) { + super(payOrderCoreMapper, payRefundMapper); + } + + @Override + public PayChannelRespEnum[] supportHandleResp() { + return new PayChannelRespEnum[] {PayChannelRespEnum.CALL_EXCEPTION, PayChannelRespEnum.CAN_NOT_RETRY_FAILURE}; + } + + + @Override + public void handleRefundChannelResp(PayRefundPostReqBO respBO) { + //退款失败 + //更新退款单表 + PayRefundDO updateRefundDO = new PayRefundDO(); + + updateRefundDO.setId(respBO.getRefundId()) + .setStatus(PayRefundStatusEnum.FAILURE.getStatus()) + .setChannelErrorCode(respBO.getChannelErrCode()) + .setChannelErrorMsg(Optional.ofNullable(respBO.getChannelErrMsg()) + .orElse(respBO.getExceptionMsg())); + updatePayRefund(updateRefundDO); + PayOrderDO updateOrderDO = new PayOrderDO(); + //更新订单表 + updateOrderDO.setId(respBO.getOrderId()) + .setRefundTimes(respBO.getRefundedTimes() + 1); + updatePayOrder(updateOrderDO); + // 立刻插入退款通知记录 + // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调 + payNotifyCoreService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() + .type(PayNotifyTypeEnum.REFUND.getType()).dataId(respBO.getRefundId()).build()); + } +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelNotifyHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelNotifyHandler.java new file mode 100644 index 0000000..8763ab2 --- /dev/null +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelNotifyHandler.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl.handler; + +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; +import org.springframework.stereotype.Service; + +/** + * 支付退款订单渠道返回通知 {@link PayChannelRespEnum#PROCESSING_NOTIFY},后置处理类 + * 支付宝退款单好像没有回调, 微信会触发回调 + */ +@Service +public class PayRefundChannelNotifyHandler extends PayRefundAbstractChannelPostHandler { + + public PayRefundChannelNotifyHandler(PayOrderCoreMapper payOrderCoreMapper, + PayRefundCoreMapper payRefundMapper) { + super(payOrderCoreMapper, payRefundMapper); + } + + @Override + public PayChannelRespEnum[] supportHandleResp() { + return new PayChannelRespEnum[] {PayChannelRespEnum.PROCESSING_NOTIFY}; + } + + @Override + public void handleRefundChannelResp(PayRefundPostReqBO respBO) { + PayRefundDO updateRefundDO = new PayRefundDO(); + //更新退款单表 + updateRefundDO.setId(respBO.getRefundId()) + .setStatus(PayRefundStatusEnum.PROCESSING_NOTIFY.getStatus()); + updatePayRefund(updateRefundDO); + + PayOrderDO updateOrderDO = new PayOrderDO(); + //更新订单表 + updateOrderDO.setId(respBO.getOrderId()) + .setRefundTimes(respBO.getRefundedTimes() + 1); + updatePayOrder(updateOrderDO); + + } +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelQueryHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelQueryHandler.java new file mode 100644 index 0000000..d8e3dcd --- /dev/null +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelQueryHandler.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl.handler; + +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +/** + * 支付退款订单渠道返回需调用查询接口的后置处理类 + * {@link PayChannelRespEnum#PROCESSING_QUERY} //TODO 芋道源码 是不是微信有这样的情况 + * {@link PayChannelRespEnum#READ_TIME_OUT_EXCEPTION} + */ +@Service +public class PayRefundChannelQueryHandler extends PayRefundAbstractChannelPostHandler { + + + public PayRefundChannelQueryHandler(PayOrderCoreMapper payOrderCoreMapper, + PayRefundCoreMapper payRefundMapper) { + super(payOrderCoreMapper, payRefundMapper); + } + + @Override + public PayChannelRespEnum[] supportHandleResp() { + return new PayChannelRespEnum[]{PayChannelRespEnum.PROCESSING_QUERY, PayChannelRespEnum.READ_TIME_OUT_EXCEPTION}; + } + + @Override + public void handleRefundChannelResp(PayRefundPostReqBO respBO) { + final PayChannelRespEnum respEnum = respBO.getRespEnum(); + PayRefundStatusEnum refundStatus = + Objects.equals(PayChannelRespEnum.PROCESSING_QUERY, respEnum) ? PayRefundStatusEnum.PROCESSING_QUERY + : PayRefundStatusEnum.UNKNOWN_QUERY; + //更新退款单表 + PayRefundDO updateRefundDO = new PayRefundDO(); + updateRefundDO.setId(respBO.getRefundId()) + .setStatus(refundStatus.getStatus()) + .setChannelErrorCode(respBO.getChannelErrCode()) + .setChannelErrorMsg(respBO.getChannelErrMsg()); + updatePayRefund(updateRefundDO); + + PayOrderDO updateOrderDO = new PayOrderDO(); + //更新订单表 + updateOrderDO.setId(respBO.getOrderId()) + .setRefundTimes(respBO.getRefundedTimes() + 1); + updatePayOrder(updateOrderDO); + + //TODO 发起查询任务 + } +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelRetryHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelRetryHandler.java new file mode 100644 index 0000000..19f38f2 --- /dev/null +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelRetryHandler.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl.handler; + +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; +import org.springframework.stereotype.Service; + +/** + * 支付退款订单渠道返回重试的后置处理类 + * {@link PayChannelRespEnum#RETRY_FAILURE} + */ +@Service +public class PayRefundChannelRetryHandler extends PayRefundAbstractChannelPostHandler { + + + public PayRefundChannelRetryHandler(PayOrderCoreMapper payOrderCoreMapper, + PayRefundCoreMapper payRefundMapper) { + super(payOrderCoreMapper, payRefundMapper); + } + + @Override + public PayChannelRespEnum[] supportHandleResp() { + return new PayChannelRespEnum[] {PayChannelRespEnum.RETRY_FAILURE}; + } + + @Override + public void handleRefundChannelResp(PayRefundPostReqBO respBO) { + + PayRefundDO updateRefundDO = new PayRefundDO(); + //更新退款单表 + updateRefundDO.setId(respBO.getRefundId()) + .setStatus(PayRefundStatusEnum.UNKNOWN_RETRY.getStatus()) + .setChannelErrorCode(respBO.getChannelErrCode()) + .setChannelErrorMsg(respBO.getChannelErrMsg()); + updatePayRefund(updateRefundDO); + + PayOrderDO updateOrderDO = new PayOrderDO(); + //更新订单表 + updateOrderDO.setId(respBO.getOrderId()) + .setRefundTimes(respBO.getRefundedTimes() + 1); + updatePayOrder(updateOrderDO); + + //TODO 发起重试任务 + } +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelSuccessHandler.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelSuccessHandler.java new file mode 100644 index 0000000..756f0a0 --- /dev/null +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/handler/PayRefundChannelSuccessHandler.java @@ -0,0 +1,64 @@ +package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl.handler; + +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; +import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; +import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService; +import cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler; +import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Date; +/** + * 支付退款订单渠道返回退款成功的后置处理类 + * {@link PayChannelRespEnum#SYNC_SUCCESS} + */ +@Service +public class PayRefundChannelSuccessHandler extends PayRefundAbstractChannelPostHandler { + + + @Resource + private PayNotifyCoreService payNotifyCoreService; + + + public PayRefundChannelSuccessHandler(PayOrderCoreMapper payOrderCoreMapper, + PayRefundCoreMapper payRefundMapper) { + super(payOrderCoreMapper, payRefundMapper); + } + + @Override + public PayChannelRespEnum[] supportHandleResp() { + return new PayChannelRespEnum[]{PayChannelRespEnum.SYNC_SUCCESS}; + } + + @Override + public void handleRefundChannelResp(PayRefundPostReqBO respBO) { + //退款成功 + PayRefundDO updateRefundDO = new PayRefundDO(); + //更新退款单表 + updateRefundDO.setId(respBO.getRefundId()) + .setStatus(PayRefundStatusEnum.SUCCESS.getStatus()) + .setChannelRefundNo(respBO.getChannelRefundNo()) + .setSuccessTime(new Date()); + updatePayRefund(updateRefundDO); + + PayOrderDO updateOrderDO = new PayOrderDO(); + //更新订单表 + updateOrderDO.setId(respBO.getOrderId()) + .setRefundTimes(respBO.getRefundedTimes() + 1) + .setRefundStatus(respBO.getRefundTypeEnum().getStatus()) + .setRefundAmount(respBO.getRefundedAmount()+respBO.getRefundAmount()); + updatePayOrder(updateOrderDO); + + // 立刻插入退款通知记录 + // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调 + payNotifyCoreService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() + .type(PayNotifyTypeEnum.REFUND.getType()).dataId(respBO.getRefundId()).build()); + } +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java index 5eac6d1..072859e 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java @@ -34,7 +34,6 @@ public interface PayClient { */ PayOrderNotifyRespDTO parseOrderNotify(PayNotifyDataDTO data) throws Exception; - /** * 调用支付渠道,进行退款 * @param reqDTO 统一退款请求信息 @@ -49,22 +48,26 @@ public interface PayClient { */ PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData); - + // TODO @芋艿:后续改成非 default,避免不知道去实现 /** * 验证是否渠道通知 + * * @param notifyData 通知数据 * @return 默认是 true */ - default boolean verifyNotifyData(PayNotifyDataDTO notifyData){ + default boolean verifyNotifyData(PayNotifyDataDTO notifyData) { return true; } + // TODO @芋艿:后续改成非 default,避免不知道去实现 /** - * 是否退款通知 + * 判断是否为退款通知 + * * @param notifyData 通知数据 * @return 默认是 false */ default boolean isRefundNotify(PayNotifyDataDTO notifyData){ return false; } + } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java index 0a80d4e..fb022b1 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java @@ -2,27 +2,27 @@ package cn.iocoder.yudao.userserver.modules.pay.controller.order; import cn.hutool.core.bean.BeanUtil; import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayCommonCoreService; import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayOrderCoreService; import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundCoreService; import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO; import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitRespDTO; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.pay.core.client.PayClient; +import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; import cn.iocoder.yudao.userserver.modules.pay.controller.order.vo.PayOrderSubmitReqVO; import cn.iocoder.yudao.userserver.modules.pay.controller.order.vo.PayOrderSubmitRespVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; - import java.util.Map; +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_CHANNEL_CLIENT_NOT_FOUND; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; @@ -35,11 +35,11 @@ public class PayOrderController { @Resource private PayOrderCoreService payOrderCoreService; - @Resource private PayRefundCoreService payRefundCoreService; - @Resource PayCommonCoreService commonCoreService; + @Resource + private PayClientFactory payClientFactory; @PostMapping("/submit") @@ -81,11 +81,12 @@ public class PayOrderController { public String returnAliPayOrder(@PathVariable("channelId") Long channelId, @RequestParam Map params){ //TODO 可以根据渠道和 app_id 返回不同的页面 log.info("app_id is {}", params.get("app_id")); - return String.format("渠道[%s]支付成功", String.valueOf(channelId)); + return String.format("渠道[%s]支付成功", channelId); } /** * 统一的渠道支付回调,支付宝的退款回调 + * * @param channelId 渠道编号 * @param params form 参数 * @param originData http request body @@ -94,20 +95,27 @@ public class PayOrderController { @PostMapping(value = "/notify/{channelId}") @ApiOperation("渠道统一的支付成功,或退款成功 通知url") public String notifyChannelPay(@PathVariable("channelId") Long channelId, - @RequestParam Map params, - @RequestBody String originData) throws Exception { - //校验是否是渠道回调 - commonCoreService.verifyNotifyData(channelId, PayNotifyDataDTO.builder().params(params).body(originData).build()); - //支付宝退款交易也会触发支付回调接口 - //参考 https://opensupport.alipay.com/support/helpcenter/193/201602484851 - //判断是否为退款通知 - if(commonCoreService.isRefundNotify(channelId, PayNotifyDataDTO.builder().params(params).body(originData).build())) { - //退款通知 - payRefundCoreService.notifyPayRefund(channelId,PayNotifyDataDTO.builder().params(params).body(originData).build()); - }else{ - //支付通知 - payOrderCoreService.notifyPayOrder(channelId,PayNotifyDataDTO.builder().params(params).body(originData).build()); + @RequestParam Map params, + @RequestBody String originData) throws Exception { + // 校验支付渠道是否存在 + PayClient payClient = payClientFactory.getPayClient(channelId); + if (payClient == null) { + log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channelId); + throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); } + + // 校验通知数据是否合法 + PayNotifyDataDTO notifyData = PayNotifyDataDTO.builder().params(params).body(originData).build(); + payClient.verifyNotifyData(notifyData); + + // 如果是退款,则发起退款通知 + if (payClient.isRefundNotify(notifyData)) { + payRefundCoreService.notifyPayRefund(channelId, PayNotifyDataDTO.builder().params(params).body(originData).build()); + return "success"; + } + + // 如果非退款,则发起支付通知 + payOrderCoreService.notifyPayOrder(channelId, PayNotifyDataDTO.builder().params(params).body(originData).build()); return "success"; } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java index 9b9ba89..0608d53 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java @@ -32,7 +32,7 @@ public class PayRefundController { @PostMapping("/refund") @ApiOperation("提交退款订单") - public CommonResult refund(@RequestBody PayRefundReqVO reqVO){ + public CommonResult refund(@RequestBody PayRefundReqVO reqVO){ PayRefundReqBO reqBO = PayRefundConvert.INSTANCE.convert(reqVO); reqBO.setUserIp(getClientIP()); //TODO 测试暂时模拟生成商户退款订单 @@ -40,4 +40,5 @@ public class PayRefundController { //reqBO.setMerchantRefundNo("MO202111210814084370000"); return CommonResult.success( PayRefundConvert.INSTANCE.convert(payRefundCoreService.refund(reqBO))); } + } -- libgit2 0.21.4