From df702e8d246fee0043a7e53aeecf92eaf7548752 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 18 Feb 2023 10:39:48 +0800 Subject: [PATCH] pay: 临时性的提交,准备 client 部分的重构 --- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java | 7 ++++++- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayNotifyDataDTO.java | 29 ----------------------------- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderNotifyRespDTO.java | 54 ------------------------------------------------------ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java | 81 --------------------------------------------------------------------------------- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundNotifyDTO.java | 63 --------------------------------------------------------------- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java | 74 -------------------------------------------------------------------------- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedRespDTO.java | 25 ------------------------- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayNotifyDataDTO.java | 29 +++++++++++++++++++++++++++++ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayOrderNotifyRespDTO.java | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayRefundNotifyDTO.java | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedReqDTO.java | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedRespDTO.java | 25 +++++++++++++++++++++++++ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java | 6 +++--- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClient.java | 12 ++++++++++-- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java | 14 ++++++++------ yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java | 2 +- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java | 6 ++++-- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXLitePayClient.java | 7 ++++++- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXNativePayClient.java | 7 ++++++- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java | 7 ++++++- yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/PayClientFactoryImplIntegrationTest.java | 2 +- yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/alipay/AlipayQrPayClientTest.java | 2 +- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java | 2 +- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java | 2 +- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java | 2 +- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java | 7 +++---- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java | 2 +- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java | 23 +++++++++++++++++++---- yudao-ui-admin/src/views/pay/order/submit.vue | 34 ++++++++++++++++++++++++++++++++-- 30 files changed, 436 insertions(+), 360 deletions(-) delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayNotifyDataDTO.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderNotifyRespDTO.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundNotifyDTO.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedRespDTO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayNotifyDataDTO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayOrderNotifyRespDTO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayRefundNotifyDTO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedReqDTO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedRespDTO.java 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 5cde0d5..f933f34 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 @@ -1,7 +1,12 @@ package cn.iocoder.yudao.framework.pay.core.client; -import cn.iocoder.yudao.framework.pay.core.client.dto.*; +import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyDataDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO; /** * 支付客户端,用于对接各支付渠道的 SDK,实现发起支付、退款等功能 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 deleted file mode 100644 index 9642581..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayNotifyDataDTO.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.framework.pay.core.client.dto; - -import lombok.Builder; -import lombok.Data; -import lombok.ToString; - -import java.util.Map; - - -/** - * 支付订单,退款订单回调,渠道的统一通知请求数据 - */ -@Data -@ToString -@Builder -public class PayNotifyDataDTO { - - - /** - * HTTP 回调接口的 request body - */ - private String body; - - /** - * HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数 - */ - private Map params; - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderNotifyRespDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderNotifyRespDTO.java deleted file mode 100644 index 91f3b2a..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderNotifyRespDTO.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.iocoder.yudao.framework.pay.core.client.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.time.LocalDateTime; - -/** - * 支付通知 Response DTO - * - * @author 芋道源码 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayOrderNotifyRespDTO { - - /** - * 支付订单号(支付模块的) - */ - private String orderExtensionNo; - /** - * 支付渠道编号 - */ - private String channelOrderNo; - /** - * 支付渠道用户编号 - */ - private String channelUserId; - /** - * 支付成功时间 - */ - private LocalDateTime successTime; - - /** - * 通知的原始数据 - * - * 主要用于持久化,方便后续修复数据,或者排错 - */ - private String data; - - /** - * TODO @jason 结合其他的渠道定义成枚举, - * alipay - * TRADE_CLOSED,未付款交易超时关闭,或支付完成后全额退款。 - * TRADE_SUCCESS, 交易支付成功 - * TRADE_FINISHED 交易结束,不可退款。 - */ - private String tradeStatus; - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java deleted file mode 100644 index 5314453..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java +++ /dev/null @@ -1,81 +0,0 @@ -package cn.iocoder.yudao.framework.pay.core.client.dto; - -import lombok.Data; -import org.hibernate.validator.constraints.Length; -import org.hibernate.validator.constraints.URL; - -import javax.validation.constraints.DecimalMin; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; -import java.util.Map; - -/** - * 统一下单 Request DTO - * - * @author 芋道源码 - */ -@Data -public class PayOrderUnifiedReqDTO { - - /** - * 用户 IP - */ - @NotEmpty(message = "用户 IP 不能为空") - private String userIp; - - // ========== 商户相关字段 ========== - - /** - * 商户订单编号 - */ - @NotEmpty(message = "商户订单编号不能为空") - private String merchantOrderId; - /** - * 商品标题 - */ - @NotEmpty(message = "商品标题不能为空") - @Length(max = 32, message = "商品标题不能超过 32") - private String subject; - /** - * 商品描述信息 - */ - @NotEmpty(message = "商品描述信息不能为空") - @Length(max = 128, message = "商品描述信息长度不能超过128") - private String body; - /** - * 支付结果的 notify 回调地址 - */ - @NotEmpty(message = "支付结果的回调地址不能为空") - @URL(message = "支付结果的 notify 回调地址必须是 URL 格式") - private String notifyUrl; - /** - * 支付结果的 return 回调地址 - */ - @URL(message = "支付结果的 return 回调地址必须是 URL 格式") - private String returnUrl; - - // ========== 订单相关字段 ========== - - /** - * 支付金额,单位:分 - */ - @NotNull(message = "支付金额不能为空") - @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") - private Integer amount; - - /** - * 支付过期时间 - */ - @NotNull(message = "支付过期时间不能为空") - private LocalDateTime expireTime; - - // ========== 拓展参数 ========== - /** - * 支付渠道的额外参数 - * - * 例如说,微信公众号需要传递 openid 参数 - */ - private Map channelExtras; - -} 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 deleted file mode 100644 index edb593d..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundNotifyDTO.java +++ /dev/null @@ -1,63 +0,0 @@ -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.time.LocalDateTime; - -/** - * 从渠道返回数据中解析得到的支付退款通知的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 LocalDateTime refundSuccessTime; - - -} 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 deleted file mode 100644 index 50c933a..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java +++ /dev/null @@ -1,74 +0,0 @@ -package cn.iocoder.yudao.framework.pay.core.client.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; -import org.hibernate.validator.constraints.URL; - -import javax.validation.constraints.DecimalMin; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -/** - * 统一 退款 Request DTO - * - * @author jason - */ -@Accessors(chain = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Data -public class PayRefundUnifiedReqDTO { - - /** - * 用户 IP - */ - private String userIp; - - // TODO @jason:这个是否为非必传字段呀,只需要传递 payTradeNo 字段即可。尽可能精简 - /** - * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 transaction_id - * https://opendocs.alipay.com/apis alipay.trade.refund 中的 trade_no - * 渠道订单号 - */ - private String channelOrderNo; - - /** - * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_trade_no - * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_trade_no - * 支付交易号 {PayOrderExtensionDO no字段} 和 渠道订单号 不能同时为空 - */ - private String payTradeNo; - - /** - * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no - * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_trade_no - * 退款请求单号 同一退款请求单号多次请求只退一笔。 - * 使用 商户的退款单号。{PayRefundDO 字段 merchantRefundNo} - */ - @NotEmpty(message = "退款请求单号") - private String merchantRefundId; - - /** - * 退款原因 - */ - @NotEmpty(message = "退款原因不能为空") - private String reason; - - /** - * 退款金额,单位:分 - */ - @NotNull(message = "退款金额不能为空") - @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") - private Integer amount; - - /** - * 退款结果 notify 回调地址, 支付宝退款不需要回调地址, 微信需要 - */ - @URL(message = "支付结果的 notify 回调地址必须是 URL 格式") - private String notifyUrl; - -} 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 deleted file mode 100644 index d2e280a..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedRespDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.framework.pay.core.client.dto; - -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRefundRespEnum; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; -/** - * 统一退款 Response DTO - * - * @author jason - */ -@Accessors(chain = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Data -public class PayRefundUnifiedRespDTO { - - /** - * 渠道退款单编号 - */ - private String channelRefundId; -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayNotifyDataDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayNotifyDataDTO.java new file mode 100644 index 0000000..23e20ea --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayNotifyDataDTO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.notify; + +import lombok.Builder; +import lombok.Data; +import lombok.ToString; + +import java.util.Map; + + +/** + * 支付订单,退款订单回调,渠道的统一通知请求数据 + */ +@Data +@ToString +@Builder +public class PayNotifyDataDTO { + + + /** + * HTTP 回调接口的 request body + */ + private String body; + + /** + * HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数 + */ + private Map params; + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayOrderNotifyRespDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayOrderNotifyRespDTO.java new file mode 100644 index 0000000..ad51fa4 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayOrderNotifyRespDTO.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.notify; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 支付通知 Response DTO + * + * @author 芋道源码 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayOrderNotifyRespDTO { + + /** + * 支付订单号(支付模块的) + */ + private String orderExtensionNo; + /** + * 支付渠道编号 + */ + private String channelOrderNo; + /** + * 支付渠道用户编号 + */ + private String channelUserId; + /** + * 支付成功时间 + */ + private LocalDateTime successTime; + + /** + * 通知的原始数据 + * + * 主要用于持久化,方便后续修复数据,或者排错 + */ + private String data; + + /** + * TODO @jason 结合其他的渠道定义成枚举, + * alipay + * TRADE_CLOSED,未付款交易超时关闭,或支付完成后全额退款。 + * TRADE_SUCCESS, 交易支付成功 + * TRADE_FINISHED 交易结束,不可退款。 + */ + private String tradeStatus; + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayRefundNotifyDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayRefundNotifyDTO.java new file mode 100644 index 0000000..487ecc5 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/notify/PayRefundNotifyDTO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.notify; + +import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; +import lombok.Builder; +import lombok.Data; +import lombok.ToString; + +import java.time.LocalDateTime; + +/** + * 从渠道返回数据中解析得到的支付退款通知的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 LocalDateTime refundSuccessTime; + + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java new file mode 100644 index 0000000..89bf3c1 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java @@ -0,0 +1,81 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.order; + +import lombok.Data; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.URL; + +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.Map; + +/** + * 统一下单 Request DTO + * + * @author 芋道源码 + */ +@Data +public class PayOrderUnifiedReqDTO { + + /** + * 用户 IP + */ + @NotEmpty(message = "用户 IP 不能为空") + private String userIp; + + // ========== 商户相关字段 ========== + + /** + * 商户订单编号 + */ + @NotEmpty(message = "商户订单编号不能为空") + private String merchantOrderId; + /** + * 商品标题 + */ + @NotEmpty(message = "商品标题不能为空") + @Length(max = 32, message = "商品标题不能超过 32") + private String subject; + /** + * 商品描述信息 + */ + @NotEmpty(message = "商品描述信息不能为空") + @Length(max = 128, message = "商品描述信息长度不能超过128") + private String body; + /** + * 支付结果的 notify 回调地址 + */ + @NotEmpty(message = "支付结果的回调地址不能为空") + @URL(message = "支付结果的 notify 回调地址必须是 URL 格式") + private String notifyUrl; + /** + * 支付结果的 return 回调地址 + */ + @URL(message = "支付结果的 return 回调地址必须是 URL 格式") + private String returnUrl; + + // ========== 订单相关字段 ========== + + /** + * 支付金额,单位:分 + */ + @NotNull(message = "支付金额不能为空") + @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") + private Integer amount; + + /** + * 支付过期时间 + */ + @NotNull(message = "支付过期时间不能为空") + private LocalDateTime expireTime; + + // ========== 拓展参数 ========== + /** + * 支付渠道的额外参数 + * + * 例如说,微信公众号需要传递 openid 参数 + */ + private Map channelExtras; + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedReqDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedReqDTO.java new file mode 100644 index 0000000..e19a04a --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedReqDTO.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.refund; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.hibernate.validator.constraints.URL; + +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 统一 退款 Request DTO + * + * @author jason + */ +@Accessors(chain = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class PayRefundUnifiedReqDTO { + + /** + * 用户 IP + */ + private String userIp; + + // TODO @jason:这个是否为非必传字段呀,只需要传递 payTradeNo 字段即可。尽可能精简 + /** + * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 transaction_id + * https://opendocs.alipay.com/apis alipay.trade.refund 中的 trade_no + * 渠道订单号 + */ + private String channelOrderNo; + + /** + * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_trade_no + * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_trade_no + * 支付交易号 {PayOrderExtensionDO no字段} 和 渠道订单号 不能同时为空 + */ + private String payTradeNo; + + /** + * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no + * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_trade_no + * 退款请求单号 同一退款请求单号多次请求只退一笔。 + * 使用 商户的退款单号。{PayRefundDO 字段 merchantRefundNo} + */ + @NotEmpty(message = "退款请求单号") + private String merchantRefundId; + + /** + * 退款原因 + */ + @NotEmpty(message = "退款原因不能为空") + private String reason; + + /** + * 退款金额,单位:分 + */ + @NotNull(message = "退款金额不能为空") + @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") + private Integer amount; + + /** + * 退款结果 notify 回调地址, 支付宝退款不需要回调地址, 微信需要 + */ + @URL(message = "支付结果的 notify 回调地址必须是 URL 格式") + private String notifyUrl; + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedRespDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedRespDTO.java new file mode 100644 index 0000000..8a120f7 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedRespDTO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.refund; + +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRefundRespEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +/** + * 统一退款 Response DTO + * + * @author jason + */ +@Accessors(chain = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class PayRefundUnifiedRespDTO { + + /** + * 渠道退款单编号 + */ + 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 2ff978d..7038de6 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 @@ -4,9 +4,9 @@ import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping; import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; -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.client.dto.order.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO; import lombok.extern.slf4j.Slf4j; import javax.validation.Validation; 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 680d80d..7630c94 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 @@ -4,7 +4,11 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.LocalDateTimeUtil; 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.dto.notify.PayNotifyDataDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO; import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; import com.alipay.api.AlipayApiException; @@ -106,11 +110,15 @@ public abstract class AbstractAlipayClient extends AbstractPayClient refundUnifiedResult = client.unifiedRefund(unifiedReqDTO); @@ -173,6 +178,16 @@ public class PayRefundServiceImpl implements PayRefundService { return payRefundDO.getId(); } + /** + * 根据支付渠道的编码,生成支付渠道的回调地址 + * + * @param channel 支付渠道 + * @return 支付渠道的回调地址 配置地址 + "/" + channel id + */ + private String genChannelPayNotifyUrl(PayChannelDO channel) { + return payProperties.getCallbackUrl() + "/" + channel.getId(); + } + @Override @Transactional(rollbackFor = Exception.class) public void notifyPayRefund(Long channelId, PayNotifyDataDTO notifyData) { diff --git a/yudao-ui-admin/src/views/pay/order/submit.vue b/yudao-ui-admin/src/views/pay/order/submit.vue index fddf383..032ff23 100644 --- a/yudao-ui-admin/src/views/pay/order/submit.vue +++ b/yudao-ui-admin/src/views/pay/order/submit.vue @@ -12,8 +12,9 @@ + - + @@ -46,6 +47,10 @@ :close-on-press-escape="false"> + + +
+