From 0f0e6eb8ba512d6c03af8e0ac033dff74d047514 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 25 Sep 2023 08:34:58 +0800 Subject: [PATCH] =?UTF-8?q?Pay=20Client=20=E6=96=B0=E5=A2=9E=E8=BD=AC?= =?UTF-8?q?=E8=B4=A6=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/pay/core/client/PayClient.java | 10 ++ .../dto/transfer/PayTransferRespDTO.java | 91 +++++++++++++++ .../transfer/PayTransferUnifiedReqDTO.java | 65 +++++++++++ .../core/client/impl/AbstractPayClient.java | 22 ++++ .../impl/alipay/AbstractAlipayPayClient.java | 6 + .../impl/alipay/AlipayAppPayClient.java | 6 + .../impl/alipay/AlipayBarPayClient.java | 6 + .../client/impl/alipay/AlipayPcPayClient.java | 6 + .../client/impl/alipay/AlipayQrPayClient.java | 6 + .../impl/alipay/AlipayTransferClient.java | 105 ++++++++++++++++++ .../impl/alipay/AlipayWapPayClient.java | 6 + .../core/client/impl/mock/MockPayClient.java | 6 + .../impl/weixin/AbstractWxPayClient.java | 6 + .../core/enums/channel/PayChannelEnum.java | 1 + .../transfer/PayTransferStatusRespEnum.java | 21 ++++ .../enums/transfer/PayTransferTypeEnum.java | 36 ++++++ .../framework/pay/wallet/WalletPayClient.java | 6 + 17 files changed, 405 insertions(+) create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayTransferClient.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.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 4d163be55..18ae017d1 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 @@ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import java.util.Map; @@ -76,4 +78,12 @@ public interface PayClient { */ PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo); + /** + * 调用渠道,进行转账 + * + * @param reqDTO 统一转账请求信息 + * @return 转账信息 + */ + PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO); + } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java new file mode 100644 index 000000000..1de0de2fc --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java @@ -0,0 +1,91 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.transfer; + +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 统一转账 Response DTO + * + * @author jason + */ +@Data +public class PayTransferRespDTO { + + private Integer status; + + /** + * 外部转账单号 + * + */ + private String outTransferNo; + + /** + * 支付渠道编号 + */ + private String channelOrderNo; + + /** + * 支付成功时间 + */ + private LocalDateTime successTime; + + /** + * 原始的返回结果 + */ + private Object rawData; + + /** + * 调用渠道的错误码 + */ + private String channelErrorCode; + /** + * 调用渠道报错时,错误信息 + */ + private String channelErrorMsg; + + /** + * 创建【WAITING】状态的转账返回 + */ + public static PayTransferRespDTO waitingOf(String channelOrderNo, + String outTransferNo, Object rawData) { + PayTransferRespDTO respDTO = new PayTransferRespDTO(); + respDTO.status = PayTransferStatusRespEnum.WAITING.getStatus(); + respDTO.channelOrderNo = channelOrderNo; + respDTO.outTransferNo = outTransferNo; + respDTO.rawData = rawData; + return respDTO; + } + + /** + * 创建【FAILURE】状态的转账返回 + */ + public static PayTransferRespDTO failureOf(String channelErrorCode, String channelErrorMsg, + String outTransferNo, Object rawData) { + PayTransferRespDTO respDTO = new PayTransferRespDTO(); + respDTO.status = PayTransferStatusRespEnum.FAILURE.getStatus(); + respDTO.channelErrorCode = channelErrorCode; + respDTO.channelErrorMsg = channelErrorMsg; + // 相对通用的字段 + respDTO.outTransferNo = outTransferNo; + respDTO.rawData = rawData; + return respDTO; + } + + /** + * 创建【SUCCESS】状态的转账返回 + */ + public static PayTransferRespDTO successOf(String channelTransferNo, LocalDateTime successTime, + String outTransferNo, Object rawData) { + PayTransferRespDTO respDTO = new PayTransferRespDTO(); + respDTO.status = PayTransferStatusRespEnum.SUCCESS.getStatus(); + respDTO.channelOrderNo = channelTransferNo; + respDTO.successTime = successTime; + // 相对通用的字段 + respDTO.outTransferNo = outTransferNo; + respDTO.rawData = rawData; + return respDTO; + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java new file mode 100644 index 000000000..6d1ef3998 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.transfer; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Map; + +/** + * 统一转账 Request DTO + * + * @author jason + */ +@Data +public class PayTransferUnifiedReqDTO { + + /** + * 转账类型 + * + * 关联 {@link PayTransferTypeEnum#getType()} + */ + @NotNull(message = "转账类型不能为空") + @InEnum(PayTransferTypeEnum.class) + private Integer type; + + /** + * 用户 IP + */ + @NotEmpty(message = "用户 IP 不能为空") + private String userIp; + + @NotEmpty(message = "外部转账单编号不能为空") + private String outTransferNo; + + /** + * 转账金额,单位:分 + */ + @NotNull(message = "转账金额不能为空") + @Min(value = 1, message = "转账金额必须大于零") + private Integer price; + + /** + * 转账标题 + */ + @NotEmpty(message = "转账标题不能为空") + @Length(max = 128, message = "转账标题不能超过 128") + private String title; + + /** + * 收款方信息,转账类型不同信息不同 + */ + @NotEmpty(message = "收款方信息 不能为空") + private Map payeeInfo; + + /** + * 支付渠道的额外参数 + * + */ + private Map channelExtras; + +} 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 e8f898b2e..66546d784 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 @@ -8,6 +8,8 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.exception.PayException; import lombok.extern.slf4j.Slf4j; @@ -181,6 +183,26 @@ public abstract class AbstractPayClient implemen protected abstract PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws Throwable; + @Override + public final PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { + ValidationUtils.validate(reqDTO); + PayTransferRespDTO resp; + try{ + resp = doUnifiedTransfer(reqDTO); + }catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可 + throw ex; + } catch (Throwable ex) { + // 系统异常,则包装成 PayException 异常抛出 + log.error("[unifiedTransfer][客户端({}) request({}) 发起转账异常]", + getId(), toJsonString(reqDTO), ex); + throw buildPayException(ex); + } + return resp; + } + + protected abstract PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) + throws Throwable; + // ========== 各种工具方法 ========== private PayException buildPayException(Throwable ex) { diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index b1edf87ac..e62120ae5 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -150,6 +150,10 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient { throw new UnsupportedOperationException("模拟支付无支付回调"); } + @Override + protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { + throw new UnsupportedOperationException("待实现"); + } } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index 87b9c4bc2..f4f326a65 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -12,6 +12,8 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; @@ -425,6 +427,10 @@ public abstract class AbstractWxPayClient extends AbstractPayClient item.getType().equals(type), values()); + } +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java index 5591238f6..9bd8a6eec 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java @@ -8,6 +8,8 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; @@ -174,4 +176,8 @@ public class WalletPayClient extends AbstractPayClient { throw new IllegalStateException(String.format("支付退款单[%s] 状态不正确", outRefundNo)); } + @Override + public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { + throw new UnsupportedOperationException("待实现"); + } }