mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	code review 退款逻辑
This commit is contained in:
		| @@ -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); | ||||
| } | ||||
| @@ -47,6 +47,4 @@ public interface PayOrderCoreService { | ||||
|     */ | ||||
|    void notifyPayOrder(Long channelId,  PayNotifyDataDTO notifyData) throws Exception; | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.experimental.Accessors; | ||||
|  | ||||
| // TODO @jason:改到 dto 哈。我们项目,统一使用 DTO | ||||
| @Data | ||||
| @Accessors(chain = true) | ||||
| @Builder | ||||
|   | ||||
| @@ -5,6 +5,8 @@ import lombok.Builder; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.experimental.Accessors; | ||||
|  | ||||
| // TODO @jason:改到 dto 哈。我们项目,统一使用 DTO | ||||
| /** | ||||
|  * 退款申请单 Request DTO | ||||
|  */ | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.experimental.Accessors; | ||||
|  | ||||
| // TODO @jason:改到 dto 哈。我们项目,统一使用 DTO | ||||
| /** | ||||
|  * 退款申请单 Response DTO | ||||
|  */ | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
| } | ||||
| @@ -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<PayRefundChannelPostHandler> handlerList; | ||||
|  | ||||
|     @Resource | ||||
|     private PayNotifyCoreService payNotifyCoreService; | ||||
|  | ||||
|  | ||||
|     // TODO @json:mapHandlers | ||||
|     private final EnumMap<PayChannelRespEnum, PayRefundChannelPostHandler> 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  退款的期限  退款次数的控制 | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; | ||||
| 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; | ||||
| @@ -1,4 +1,4 @@ | ||||
| package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; | ||||
| 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; | ||||
| @@ -1,4 +1,4 @@ | ||||
| package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; | ||||
| 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; | ||||
| @@ -1,4 +1,4 @@ | ||||
| package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; | ||||
| 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; | ||||
| @@ -1,4 +1,4 @@ | ||||
| package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; | ||||
| 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; | ||||
| @@ -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; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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<String, String> 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 | ||||
| @@ -96,18 +97,25 @@ public class PayOrderController { | ||||
|     public String notifyChannelPay(@PathVariable("channelId") Long channelId, | ||||
|                                    @RequestParam Map<String, String> 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()); | ||||
|         // 校验支付渠道是否存在 | ||||
|         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"; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -40,4 +40,5 @@ public class PayRefundController { | ||||
|         //reqBO.setMerchantRefundNo("MO202111210814084370000"); | ||||
|         return CommonResult.success( PayRefundConvert.INSTANCE.convert(payRefundCoreService.refund(reqBO))); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV