From 5bf3045544ede01a9ced03a6040d7831cdc00b54 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 3 Jan 2022 22:32:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=80=80=E6=AC=BE=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/change_db.sql | 3 + sql/ruoyi-vue-pro.sql | 3 +- .../service/refund/PayRefundServiceTest.java | 2 - .../pay/dal/dataobject/order/PayRefundDO.java | 14 --- .../service/order/dto/PayRefundReqDTO.java | 12 ++- .../service/order/dto/PayRefundRespDTO.java | 18 ---- .../order/impl/PayRefundCoreServiceImpl.java | 85 ++++++------------- .../framework/pay/core/client/PayClient.java | 2 +- .../client/dto/PayRefundUnifiedReqDTO.java | 3 +- .../client/dto/PayRefundUnifiedRespDTO.java | 18 +--- .../core/client/impl/AbstractPayClient.java | 8 +- .../impl/alipay/AbstractAlipayClient.java | 27 +++--- .../core/client/impl/wx/WXPubPayClient.java | 2 +- .../controller/order/PayRefundController.java | 4 +- .../controller/order/vo/PayRefundReqVO.java | 2 +- .../controller/order/vo/PayRefundRespVO.java | 17 ---- 16 files changed, 63 insertions(+), 157 deletions(-) diff --git a/sql/change_db.sql b/sql/change_db.sql index 4cffc8cff..810183f3e 100644 --- a/sql/change_db.sql +++ b/sql/change_db.sql @@ -3,3 +3,6 @@ CHANGE COLUMN `channel_notify_data` `channel_notify_data` VARCHAR(2048) CHARACTE ALTER TABLE `ruoyi-vue-pro`.`pay_refund` CHANGE COLUMN `req_no` `req_no` VARCHAR(64) NULL COMMENT '退款单请求号' ; + +ALTER TABLE `ruoyi-vue-pro`.`pay_refund` +DROP COLUMN `req_no`; diff --git a/sql/ruoyi-vue-pro.sql b/sql/ruoyi-vue-pro.sql index 62d4b8d3d..685e3a733 100644 --- a/sql/ruoyi-vue-pro.sql +++ b/sql/ruoyi-vue-pro.sql @@ -607,7 +607,7 @@ CREATE TABLE `pay_order_extension` ( `user_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户 IP', `status` tinyint NOT NULL COMMENT '支付状态', `channel_extras` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '支付渠道的额外参数', - `channel_notify_data` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '支付渠道异步通知的内容', + `channel_notify_data` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '支付渠道异步通知的内容', `creator` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', @@ -720,7 +720,6 @@ COMMIT; DROP TABLE IF EXISTS `pay_refund`; CREATE TABLE `pay_refund` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '支付退款编号', - `req_no` varchar(64) NOT NULL COMMENT '退款单请求号', `merchant_id` bigint NOT NULL COMMENT '商户编号', `app_id` bigint NOT NULL COMMENT '应用编号', `channel_id` bigint NOT NULL COMMENT '渠道编号', diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java index 2741144e2..ee19dba14 100755 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java +++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java @@ -43,7 +43,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest { public void testGetRefundPage() { // mock 数据 PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到 - o.setReqNo("RF0000001"); o.setMerchantId(1L); o.setAppId(1L); o.setChannelId(1L); @@ -115,7 +114,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest { public void testGetRefundList() { // mock 数据 PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到 - o.setReqNo("RF0000001"); o.setMerchantId(1L); o.setAppId(1L); o.setChannelId(1L); diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java index 6c94ecb76..1886117c7 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java @@ -36,20 +36,6 @@ public class PayRefundDO extends BaseDO { @TableId private Long id; - /** - * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no - * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_request_no - * 退款请求号。 - * 标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。 - * 注:针对同一次退款请求,如果调用接口失败或异常了,重试时需要保证退款请求号不能变更, - * 防止该笔交易重复退款。支付宝会保证同样的退款请求号多次请求只会退一次。 - * 退款单请求号,根据规则生成 - * 例如说,R202109181134287570000 - * 废弃,使用 merchantRefundNo 做退款请求号 - */ - @Deprecated - private String reqNo; - /** * 商户编号 * diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java index 02bd9cbfa..6ec3fb13d 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java @@ -6,6 +6,10 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + /** * 退款申请单 Request DTO */ @@ -16,15 +20,17 @@ import lombok.experimental.Accessors; @AllArgsConstructor public class PayRefundReqDTO { - // TODO @jason:增加下 validation 注解哈 /** * 支付订单编号 */ + @NotNull(message = "支付订单编号不能为空") private Long payOrderId; /** * 退款金额 */ + @NotNull(message = "退款金额不能为空") + @DecimalMin(value = "0", inclusive = false, message = "退款金额必须大于零") private Long amount; /** @@ -35,8 +41,8 @@ public class PayRefundReqDTO { /** * 商户退款订单号 */ - // TODO @jason:merchantRefundNo=》merchantRefundId,保持和 PayOrder 的 merchantOrderId 一致哈 - private String merchantRefundNo; + @NotEmpty(message = "商户退款订单号不能为空") + private String merchantRefundId; /** * 用户 IP diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java index 1468fe451..d065f3852 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java @@ -16,24 +16,6 @@ import lombok.experimental.Accessors; @AllArgsConstructor public class PayRefundRespDTO { - /** - * 渠道返回结果 - * 退款处理中和退款成功 返回 1 - * 失败和其他情况 返回 2 - */ - // TODO @jason:这个 result,可以使用 CommonResult 里呢 - private Integer channelReturnResult; - - /** - * 渠道返回 code - */ - private String channelReturnCode; - - /** - * 渠道返回消息 - */ - private String channelReturnMsg; - /** * 支付退款单编号,自增 */ 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 abd534b61..f1921667e 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 @@ -23,11 +23,11 @@ import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundReqDT import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundRespDTO; 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.PayCommonResult; import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundNotifyDTO; 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.PayChannelRefundRespEnum; import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -88,11 +88,8 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { if (Objects.equals(req.getAmount(), order.getAmount())) { refundType = PayRefundTypeEnum.ALL; } - PayOrderExtensionDO orderExtensionDO = payOrderExtensionCoreMapper.selectById(order.getSuccessExtensionId()); - PayRefundDO payRefundDO = payRefundCoreMapper.selectByTradeNoAndMerchantRefundNo(orderExtensionDO.getNo(), req.getMerchantRefundNo()); - // 构造渠道的统一的退款请求参数 - PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO(); + PayRefundDO payRefundDO = payRefundCoreMapper.selectByTradeNoAndMerchantRefundNo(orderExtensionDO.getNo(), req.getMerchantRefundId()); if(Objects.nonNull(payRefundDO)){ // 退款订单已经提交过。 //TODO 校验相同退款单的金额 @@ -101,19 +98,10 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { || Objects.equals(PayRefundStatusEnum.CLOSE.getStatus(), payRefundDO.getStatus())) { //已成功退款 throw exception(PAY_REFUND_SUCCEED); - } else{ - // TODO @jason:这里不用 else,简洁一些 - // 保证商户退款单不变,重复向渠道发起退款。渠道保持幂等 - unifiedReqDTO.setUserIp(req.getUserIp()) - .setAmount(payRefundDO.getRefundAmount()) - .setChannelOrderNo(payRefundDO.getChannelOrderNo()) - .setPayTradeNo(payRefundDO.getTradeNo()) - .setRefundReqNo(payRefundDO.getMerchantRefundNo()) - .setReason(payRefundDO.getReason()); } - }else{ - // 新生成退款单。 退款单入库 退款单状态:生成 - // TODO @jason:封装一个小方法。插入退款单 + //可以重复提交,保证 退款请求号 一致,由渠道保证幂等 + }else { + //成功,插入退款单 状态为生成.没有和渠道交互 payRefundDO = PayRefundDO.builder().channelOrderNo(order.getChannelOrderNo()) .appId(order.getAppId()) .channelOrderNo(order.getChannelOrderNo()) @@ -121,7 +109,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { .channelId(order.getChannelId()) .merchantId(order.getMerchantId()) .orderId(order.getId()) - .merchantRefundNo(req.getMerchantRefundNo()) + .merchantRefundNo(req.getMerchantRefundId()) .notifyUrl(app.getRefundNotifyUrl()) .payAmount(order.getAmount()) .refundAmount(req.getAmount()) @@ -134,38 +122,21 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { .type(refundType.getStatus()) .build(); payRefundCoreMapper.insert(payRefundDO); - // TODO @jason:这块的逻辑,和已存在的这块,貌似是统一的? - unifiedReqDTO.setUserIp(req.getUserIp()) - .setAmount(payRefundDO.getRefundAmount()) - .setChannelOrderNo(payRefundDO.getChannelOrderNo()) - .setPayTradeNo(payRefundDO.getTradeNo()) - .setRefundReqNo(payRefundDO.getMerchantRefundNo()) - .setReason(req.getReason()); } + PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO(); + unifiedReqDTO.setUserIp(req.getUserIp()) + .setAmount(req.getAmount()) + .setChannelOrderNo(order.getChannelOrderNo()) + .setPayTradeNo(orderExtensionDO.getNo()) + .setMerchantRefundId(req.getMerchantRefundId()) + .setReason(req.getReason()); // 向渠道发起退款申请 - PayRefundUnifiedRespDTO refundUnifiedRespDTO = client.unifiedRefund(unifiedReqDTO); - // 构造退款申请返回对象 - PayRefundRespDTO respDTO = new PayRefundRespDTO(); - if (refundUnifiedRespDTO.getChannelResp() == PayChannelRefundRespEnum.SUCCESS - ||refundUnifiedRespDTO.getChannelResp() == PayChannelRefundRespEnum.PROCESSING) { - // 成功处理,在退款通知中处理, 这里不处理 - respDTO.setChannelReturnResult(PayChannelRefundRespEnum.SUCCESS.getStatus()); - respDTO.setRefundId(payRefundDO.getId()); - }else { - // 失败返回错误给前端,可以重新发起退款,保证退款请求号(这里是商户退款单号), 避免重复退款。 - // TODO @jason:失败的话,是不是可以跑出 ServiceException 业务异常。这样就是成功返回 refundId,失败业务异常 - respDTO.setChannelReturnResult(PayChannelRefundRespEnum.FAILURE.getStatus()); - // 更新退款单状态 - PayRefundDO updatePayRefund = new PayRefundDO(); - updatePayRefund.setId(payRefundDO.getId()) - .setChannelErrorMsg(refundUnifiedRespDTO.getChannelMsg()) - .setChannelErrorCode(refundUnifiedRespDTO.getChannelCode()) - .setStatus(PayRefundStatusEnum.FAILURE.getStatus()); - payRefundCoreMapper.updateById(updatePayRefund); - } - respDTO.setChannelReturnCode(refundUnifiedRespDTO.getChannelCode()) - .setChannelReturnMsg(refundUnifiedRespDTO.getChannelMsg()); - return respDTO; + PayCommonResult refundUnifiedResult = client.unifiedRefund(unifiedReqDTO); + //检查是否失败,失败抛出业务异常。 + //TODO 渠道的异常记录 + refundUnifiedResult.checkError(); + //成功在 退款回调中处理 + return PayRefundRespDTO.builder().refundId(payRefundDO.getId()).build(); } @@ -187,7 +158,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { payRefundSuccess(refundNotify); } else { //TODO 支付异常, 支付宝似乎没有支付异常的通知。 - // TODO @jason:那这里可以考虑打个 error logger + // TODO @jason:那这里可以考虑打个 error logger @芋艿 微信是否存在支付异常通知 } } @@ -199,22 +170,22 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService { throw exception(PAY_REFUND_NOT_FOUND); } - // 计算订单的状态。如果全部退款,则订单处于关闭。TODO @jason:建议这里按照金额来判断,因为可能退款多次 - 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(); + + PayOrderStatusEnum orderStatus = PayOrderStatusEnum.SUCCESS; + if(Objects.equals(payOrderDO.getAmount(), refundedAmount+ refundDO.getRefundAmount())){ + //支付金额 = 已退金额 + 本次退款金额。 + orderStatus = PayOrderStatusEnum.CLOSED; + } // 更新支付订单 PayOrderDO updateOrderDO = new PayOrderDO(); updateOrderDO.setId(refundDO.getOrderId()) .setRefundAmount(refundedAmount + refundDO.getRefundAmount()) .setStatus(orderStatus.getStatus()) .setRefundTimes(payOrderDO.getRefundTimes() + 1) - .setRefundStatus(type); + .setRefundStatus(refundDO.getType()); payOrderCoreMapper.updateById(updateOrderDO); // 更新退款订单 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 072859e1c..5cde0d5a0 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 @@ -39,7 +39,7 @@ public interface PayClient { * @param reqDTO 统一退款请求信息 * @return 各支付渠道的统一返回结果 */ - PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO); + PayCommonResult unifiedRefund(PayRefundUnifiedReqDTO reqDTO); /** * 解析支付退款通知数据 diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java index 994c46bd1..79e11eaff 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java @@ -43,7 +43,6 @@ public class PayRefundUnifiedReqDTO { */ private String payTradeNo; - // TODO @jason:这个字段,要不就使用 merchantRefundId,更直接 /** * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_trade_no @@ -51,7 +50,7 @@ public class PayRefundUnifiedReqDTO { * 使用 商户的退款单号。{PayRefundDO 字段 merchantRefundNo} */ @NotEmpty(message = "退款请求单号") - private String refundReqNo; + private String merchantRefundId; /** * 退款原因 diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedRespDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedRespDTO.java index e950933e1..d2e280ae5 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedRespDTO.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedRespDTO.java @@ -18,22 +18,8 @@ import lombok.experimental.Accessors; @Data public class PayRefundUnifiedRespDTO { - // TODO @jason:可以合并下。退款处理中、成功,都是成功;其它就业务失败。这样,可以复用 PayCommonResult;这个 RespDTO 可以返回渠道的退款编号 /** - * 渠道的退款结果 + * 渠道退款单编号 */ - private PayChannelRefundRespEnum channelResp; - - // TODO @json:channelReturnCode 和 channelReturnMsg 放到 PayCommonResult 里噶 - /** - * 渠道返回码 - */ - private String channelCode; - - /** - * 渠道返回信息 - */ - private String channelMsg; - - //TODO 退款资金渠 ??? + private String channelRefundId; } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index b265bd2ac..38b8875a1 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -103,19 +103,19 @@ public abstract class AbstractPayClient implemen @Override - public PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) { - PayRefundUnifiedRespDTO resp; + public PayCommonResult unifiedRefund(PayRefundUnifiedReqDTO reqDTO) { + PayCommonResult resp; try { resp = doUnifiedRefund(reqDTO); } catch (Throwable ex) { // 记录异常日志 log.error("[unifiedRefund][request({}) 发起退款失败]", toJsonString(reqDTO), ex); - throw exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR); + resp = PayCommonResult.error(ex); } return resp; } - protected abstract PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable; + protected abstract PayCommonResult 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/client/impl/alipay/AbstractAlipayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClient.java index 8dca7cbec..76d929da1 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClient.java @@ -3,9 +3,9 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping; +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.PayChannelRefundRespEnum; import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayConfig; @@ -100,39 +100,32 @@ public abstract class AbstractAlipayClient extends AbstractPayClient doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { AlipayTradeRefundModel model=new AlipayTradeRefundModel(); model.setTradeNo(reqDTO.getChannelOrderNo()); model.setOutTradeNo(reqDTO.getPayTradeNo()); - model.setOutRequestNo(reqDTO.getRefundReqNo()); + model.setOutRequestNo(reqDTO.getMerchantRefundId()); model.setRefundAmount(calculateAmount(reqDTO.getAmount()).toString()); model.setRefundReason(reqDTO.getReason()); AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest(); refundRequest.setBizModel(model); - PayRefundUnifiedRespDTO respDTO = new PayRefundUnifiedRespDTO(); try { AlipayTradeRefundResponse response = client.execute(refundRequest); log.info("[doUnifiedRefund][response({}) 发起退款 渠道返回", toJsonString(response)); if (response.isSuccess()) { - //退款成功,更新为PROCESSING_NOTIFY, 而不是 SYNC_SUCCESS 通过支付宝回调接口处理。退款导致触发的异步通知, //退款导致触发的异步通知是发送到支付接口中设置的notify_url - //TODO 沙箱环境 返回 的tradeNo(渠道退款单号) 和 订单的tradNo 是一个值,是不是理解不对? - respDTO.setChannelResp(PayChannelRefundRespEnum.SUCCESS) - .setChannelCode(response.getCode()) - .setChannelMsg(response.getMsg()); + //支付宝不返回退款单号,设置为空 + PayRefundUnifiedRespDTO respDTO = new PayRefundUnifiedRespDTO(); + respDTO.setChannelRefundId(""); + return PayCommonResult.build(response.getCode(), response.getMsg(), respDTO, codeMapping); }else{ - respDTO.setChannelResp(PayChannelRefundRespEnum.FAILURE) - .setChannelCode(response.getSubCode()) - .setChannelMsg(response.getSubMsg()); + //失败。需要抛出异常 + return PayCommonResult.build(response.getCode(), response.getMsg(), null, codeMapping); } - return respDTO; } catch (AlipayApiException e) { //TODO 记录异常日志 log.error("[doUnifiedRefund][request({}) 发起退款失败,网络读超时,退款状态未知]", toJsonString(reqDTO), e); - respDTO.setChannelResp(PayChannelRefundRespEnum.FAILURE) - .setChannelCode(e.getErrCode()) - .setChannelMsg(e.getErrMsg()); - return respDTO; + return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping); } } 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 db1b8cd57..5d5809ae3 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 @@ -149,7 +149,7 @@ public class WXPubPayClient extends AbstractPayClient { @Override - protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable { + protected PayCommonResult doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable { //TODO 需要实现 throw new UnsupportedOperationException(); } 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 13ab007b3..ba62bdd8a 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,8 +37,8 @@ public class PayRefundController { PayRefundReqDTO req = PayRefundConvert.INSTANCE.convert(reqVO); req.setUserIp(getClientIP()); //TODO 测试暂时模拟生成商户退款订单 - if(StrUtil.isEmpty(reqVO.getMerchantRefundNo())) { - req.setMerchantRefundNo(PaySeqUtils.genMerchantRefundNo()); + if(StrUtil.isEmpty(reqVO.getMerchantRefundId())) { + req.setMerchantRefundId(PaySeqUtils.genMerchantRefundNo()); } return CommonResult.success( PayRefundConvert.INSTANCE.convert(payRefundCoreService.submitRefundOrder(req))); } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java index dce32f7c7..8287ba036 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java @@ -29,6 +29,6 @@ public class PayRefundReqVO { @ApiModelProperty(value = "商户退款订单号", required = true, example = "MR202111180000000001") //TODO 测试暂时模拟生成 //@NotEmpty(message = "商户退款订单号") - private String merchantRefundNo; + private String merchantRefundId; } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java index ee5cce8fe..29059ab28 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java @@ -15,23 +15,6 @@ import lombok.experimental.Accessors; @AllArgsConstructor public class PayRefundRespVO { - /** - * 渠道返回结果 - * 退款处理中和退款成功 返回 1 - * 失败和其他情况 返回 2 - */ - private Integer channelReturnResult; - - /** - * 渠道返回code - */ - private String channelReturnCode; - - /** - * 渠道返回消息 - */ - private String channelReturnMsg; - /** * 支付退款单编号, 自增 */