diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundMapper.java index 471ea33e8..150372837 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundMapper.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundMapper.java @@ -1,12 +1,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order; -import java.util.*; - import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; - import org.apache.ibatis.annotations.Mapper; @@ -17,5 +12,7 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface PayRefundMapper extends BaseMapperX { - + default PayRefundDO selectByReqNo(String reqNo) { + return selectOne("req_no", reqNo); + } } diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java index d2796e36a..e0ea59299 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java @@ -47,8 +47,8 @@ public interface PayErrorCodeCoreConstants { ErrorCode PAY_REFUND_AMOUNT_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额"); ErrorCode PAY_REFUND_ALL_REFUNDED = new ErrorCode(1007006001, "订单已经全额退款"); ErrorCode PAY_REFUND_CHN_ORDER_NO_IS_NULL = new ErrorCode(1007006002, "该订单的渠道订单为空"); - ErrorCode PAY_REFUND_POST_HANDLER_NOT_FOUND = new ErrorCode(1007006002, "未找到对应的退款后置处理类"); - + ErrorCode PAY_REFUND_POST_HANDLER_NOT_FOUND = new ErrorCode(1007006003, "未找到对应的退款后置处理类"); + ErrorCode PAY_REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在"); // TODO @aquan:下面还两个要合并上去哈。另外一般中英文之间要有空格。例如说, 新建一个 order 数据;这样可读性更好。 /** 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 f9faf70de..525f69fb0 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 @@ -2,6 +2,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.order; import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundReqBO; import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundRespBO; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; /** * 退款单 Core Service @@ -17,4 +18,17 @@ public interface PayRefundCoreService { * @return 退款申请返回信息 */ PayRefundRespBO refund(PayRefundReqBO reqDTO); + + + /** + * 渠道的退款通知 + * @param channelId 渠道编号 + * @param channelCode 渠道编码 + * @param notifyData 通知数据 + * @throws Exception 退款通知异常 + */ + void notifyPayRefund(Long channelId, String channelCode, PayNotifyDataDTO notifyData) throws Exception; + + + } 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 1e5fef729..68ba7ae34 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 @@ -10,7 +10,11 @@ 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.PayOrderExtensionCoreMapper; import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper; +import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum; +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.framework.pay.core.client.dto.PayRefundNotifyDTO; import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum; import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; @@ -24,8 +28,10 @@ import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundRespBO import cn.iocoder.yudao.coreservice.modules.pay.util.PaySeqUtils; 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.client.dto.PayRefundUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundUnifiedRespDTO; +import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -66,6 +72,9 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { @Resource private List handlerList; + @Resource + private PayNotifyCoreService payNotifyCoreService; + private final EnumMap mapHandler = new EnumMap<>(PayChannelRespEnum.class); @@ -84,7 +93,6 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { } - @Override @Transactional(rollbackFor = Exception.class) public PayRefundRespBO refund(PayRefundReqBO reqBO) { @@ -173,6 +181,64 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { } + @Override + public void notifyPayRefund(Long channelId, String channelCode, PayNotifyDataDTO notifyData) { + log.info("[notifyPayRefund][channelId({}) 回调数据({})]", channelId, notifyData.getBody()); + // 校验支付渠道是否有效 + 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); + } + //解析渠道退款通知数据, 统一处理 + PayRefundNotifyDTO refundNotify = client.parseRefundNotify(notifyData); + + if(Objects.equals(PayNotifyRefundStatusEnum.SUCCESS,refundNotify.getStatus())){ + //退款成功。 支付宝只有退款成功才会发通知 + PayRefundDO refundDO = payRefundMapper.selectByReqNo(refundNotify.getReqNo()); + if (refundDO == null) { + log.error("不存在 seqNo 为{} 的支付退款单",refundNotify.getReqNo()); + throw exception(PAY_REFUND_NOT_FOUND); + } + Long refundAmount = refundDO.getRefundAmount(); + Integer type = refundDO.getType(); + PayOrderStatusEnum orderStatus = PayOrderStatusEnum.SUCCESS; + 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()) + .setRefundAmount(refundedAmount + refundAmount) + .setStatus(orderStatus.getStatus()) + .setRefundStatus(type); + payOrderCoreMapper.updateById(updateOrderDO); + + //跟新退款订单 + PayRefundDO updateRefundDO = new PayRefundDO(); + updateRefundDO.setId(refundDO.getId()) + .setSuccessTime(refundNotify.getRefundSuccessTime()) + .setChannelRefundNo(refundNotify.getChannelOrderNo()) + .setTradeNo(refundNotify.getTradeNo()) + .setNotifyTime(new Date()) + .setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); + payRefundMapper.updateById(updateRefundDO); + + //插入退款通知记录 + // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调 + payNotifyCoreService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() + .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refundDO.getId()).build()); + }else{ + //TODO 退款失败 + } + + } + /** * 校验是否进行退款 * @param reqBO 退款申请信息 @@ -197,7 +263,5 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { throw exception(PAY_REFUND_CHN_ORDER_NO_IS_NULL); } //TODO 退款的期限 退款次数的控制 - - } } 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 f49d27981..ceea4b45e 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 @@ -42,4 +42,11 @@ public interface PayClient { */ PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO); + /** + * 解析支付退款通知数据 + * @param notifyData 支付退款通知请求数据 + * @return 支付退款通知的Notify DTO + */ + PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData); + } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayNotifyDataDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayNotifyDataDTO.java index 194a8348f..bbd237e9c 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayNotifyDataDTO.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayNotifyDataDTO.java @@ -8,7 +8,7 @@ import java.util.Map; /** - * 支付订单回调,渠道的统一通知请求数据 + * 支付订单,退款订单回调,渠道的统一通知请求数据 */ @Data @ToString diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundNotifyDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundNotifyDTO.java new file mode 100644 index 000000000..05fcff3c1 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundNotifyDTO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto; + +import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; +import lombok.Builder; +import lombok.Data; +import lombok.ToString; + +import java.util.Date; + +/** + * 从渠道返回数据中解析得到的支付退款通知的Notify DTO + * + * @author jason + */ +@Data +@ToString +@Builder +public class PayRefundNotifyDTO { + + /** + * 支付渠道编号 + */ + private String channelOrderNo; + + + /** + * 交易订单号,根据规则生成 + * 调用支付渠道时,使用该字段作为对接的订单号。 + * 1. 调用微信支付 https://api.mch.weixin.qq.com/pay/unifiedorder 时,使用该字段作为 out_trade_no + * 2. 调用支付宝 https://opendocs.alipay.com/apis 时,使用该字段作为 out_trade_no + * 这里对应 pay_extension 里面的 no + * 例如说,P202110132239124200055 + */ + private String tradeNo; + + /** + * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no + * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_request_no + * 退款请求号。 + * 标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。 + * 注:针对同一次退款请求,如果调用接口失败或异常了,重试时需要保证退款请求号不能变更, + * 防止该笔交易重复退款。支付宝会保证同样的退款请求号多次请求只会退一次。 + * 退款单请求号,根据规则生成 + * + * 例如说,RR202109181134287570000 + */ + private String reqNo; + + + /** + * 退款是否成功 + */ + private PayNotifyRefundStatusEnum status; + + + + /** + * 退款成功时间 + */ + private Date refundSuccessTime; + + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java index 650592998..d046c9558 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java @@ -83,6 +83,12 @@ public class AlipayQrPayClient extends AbstractPayClient } + @Override + public PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData) { + //TODO 需要实现 + throw new UnsupportedOperationException("需要实现"); + } + @Override protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable { //TODO 需要实现 diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java index 658acc915..07291d749 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; import cn.iocoder.yudao.framework.pay.core.client.dto.*; import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayConfig; @@ -103,7 +104,6 @@ public class AlipayWapPayClient extends AbstractPayClient .data(data.getBody()).build(); } - @Override protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { AlipayTradeRefundModel model=new AlipayTradeRefundModel(); @@ -119,11 +119,10 @@ public class AlipayWapPayClient extends AbstractPayClient AlipayTradeRefundResponse response = client.execute(refundRequest); log.info("[doUnifiedRefund][response({}) 发起退款 渠道返回", toJsonString(response)); if (response.isSuccess()) { - //退款成功 + //退款成功,更新为PROCESSING_NOTIFY, 而不是 SYNC_SUCCESS 通过支付宝回调接口处理。退款导致触发的异步通知, + //退款导致触发的异步通知是发送到支付接口中设置的notify_url //TODO 沙箱环境 返回 的tradeNo(渠道退款单号) 和 订单的tradNo 是一个值,是不是理解不对? - respDTO.setRespEnum(PayChannelRespEnum.SYNC_SUCCESS) - .setChannelRefundNo(response.getTradeNo()) - .setPayTradeNo(response.getOutTradeNo()); + respDTO.setRespEnum(PayChannelRespEnum.PROCESSING_NOTIFY); }else{ //特殊处理 sub_code ACQ.SYSTEM_ERROR(系统错误), 需要调用重试任务 //沙箱环境返回的貌似是”aop.ACQ.SYSTEM_ERROR“, 用contain @@ -153,12 +152,20 @@ public class AlipayWapPayClient extends AbstractPayClient .setChannelErrMsg(e.getErrMsg()) .setRespEnum(PayChannelRespEnum.CALL_EXCEPTION); } - return respDTO; - } + } - + @Override + public PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData) { + Map params = notifyData.getParams(); + PayRefundNotifyDTO notifyDTO = PayRefundNotifyDTO.builder().channelOrderNo(params.get("trade_no")) + .tradeNo(params.get("out_trade_no")) + .reqNo(params.get("out_biz_no")) + .status(PayNotifyRefundStatusEnum.SUCCESS) + .refundSuccessTime(DateUtil.parse(params.get("gmt_refund"), "yyyy-MM-dd HH:mm:ss")) + .build(); + return notifyDTO; } } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java index bf4f5f32c..db1b8cd57 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java @@ -141,6 +141,12 @@ public class WXPubPayClient extends AbstractPayClient { .data(data.getBody()).build(); } + @Override + public PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData) { + //TODO 需要实现 + throw new UnsupportedOperationException("需要实现"); + } + @Override protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable { diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayNotifyRefundStatusEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayNotifyRefundStatusEnum.java new file mode 100644 index 000000000..5137600e0 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayNotifyRefundStatusEnum.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.framework.pay.core.enums; + +/** + * 退款通知, 统一的渠道退款状态 + * + * @author jason + */ +public enum PayNotifyRefundStatusEnum { + /** + * 支付宝 中 全额退款 trade_status=TRADE_CLOSED, 部分退款 trade_status=TRADE_SUCCESS + * 退款成功 + */ + SUCCESS, + + /** + * 支付宝退款通知没有这个状态 + * 退款异常 + */ + ABNORMAL; +} 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 d4c31395e..909a4fa62 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 @@ -3,6 +3,7 @@ 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.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; @@ -34,6 +35,9 @@ public class PayOrderController { @Resource private PayOrderCoreService payOrderCoreService; + @Resource + private PayRefundCoreService payRefundCoreService; + @PostMapping("/submit") @ApiOperation("提交支付订单") // @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好 @@ -85,11 +89,21 @@ public class PayOrderController { public String notifyAliPayWapPayOrder(@PathVariable("channelId") Long channelId, @RequestParam Map params, @RequestBody String originData) throws Exception { - //TODO @jason 校验 是否支付宝调用。 payclient 中加一个校验方法 - payOrderCoreService.notifyPayOrder(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), PayNotifyDataDTO.builder().params(params).body(originData).build()); + //TODO 校验是否支付宝调用。 payclient 中加一个校验方法 + //支付宝退款交易也会触发支付回调接口 + //参考 https://opensupport.alipay.com/support/helpcenter/193/201602484851 + //判断是否为支付宝的退款交易 + if(isAliPayRefund(params)) { + //退款通知 + payRefundCoreService.notifyPayRefund(channelId,PayChannelEnum.ALIPAY_WAP.getCode(), PayNotifyDataDTO.builder().params(params).body(originData).build()); + }else{ + //支付通知 + payOrderCoreService.notifyPayOrder(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), PayNotifyDataDTO.builder().params(params).body(originData).build()); + } return "success"; } + /** * https://opendocs.alipay.com/open/203/105285#%E5%89%8D%E5%8F%B0%E5%9B%9E%E8%B7%B3%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E * @param channelId 渠道id @@ -102,6 +116,19 @@ public class PayOrderController { return "支付成功"; } + /** + * 是否是支付宝的退款交易 + * @param params http content-type application/x-www-form-urlencoded 的参数 + * @return + */ + private boolean isAliPayRefund(Map params) { + if (params.containsKey("refund_fee")) { + return true; + } else { + return false; + } + } + @RequestMapping("/notify/test") @ApiOperation("通知的测试接口") public String notifyTest() { 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 42d042720..9b9ba8997 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 @@ -37,6 +37,7 @@ public class PayRefundController { reqBO.setUserIp(getClientIP()); //TODO 测试暂时模拟生成商户退款订单 reqBO.setMerchantRefundNo(PaySeqUtils.genMerchantRefundNo()); + //reqBO.setMerchantRefundNo("MO202111210814084370000"); return CommonResult.success( PayRefundConvert.INSTANCE.convert(payRefundCoreService.refund(reqBO))); } }