mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-31 09:30:05 +08:00
Pay Client 新增转账接口
This commit is contained in:
parent
60f766f35c
commit
0f0e6eb8ba
@ -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.order.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
|
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.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;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -76,4 +78,12 @@ public interface PayClient {
|
|||||||
*/
|
*/
|
||||||
PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo);
|
PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用渠道,进行转账
|
||||||
|
*
|
||||||
|
* @param reqDTO 统一转账请求信息
|
||||||
|
* @return 转账信息
|
||||||
|
*/
|
||||||
|
PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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<String, String> payeeInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付渠道的额外参数
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private Map<String, String> channelExtras;
|
||||||
|
|
||||||
|
}
|
@ -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.order.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
|
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.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 cn.iocoder.yudao.framework.pay.core.client.exception.PayException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@ -181,6 +183,26 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||||||
protected abstract PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo)
|
protected abstract PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo)
|
||||||
throws Throwable;
|
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) {
|
private PayException buildPayException(Throwable ex) {
|
||||||
|
@ -150,6 +150,10 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradeRefundResponse response = client.execute(request);
|
AlipayTradeRefundResponse response = client.execute(request);
|
||||||
if (!response.isSuccess()) {
|
if (!response.isSuccess()) {
|
||||||
|
// 当出现 ACQ.SYSTEM_ERROR, 退款可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
|
||||||
|
if (Objects.equals(response.getSubCode(), "ACQ.SYSTEM_ERROR")) {
|
||||||
|
return PayRefundRespDTO.waitingOf(null, reqDTO.getOutRefundNo(), response);
|
||||||
|
}
|
||||||
return PayRefundRespDTO.failureOf(response.getSubCode(), response.getSubMsg(), reqDTO.getOutRefundNo(), response);
|
return PayRefundRespDTO.failureOf(response.getSubCode(), response.getSubMsg(), reqDTO.getOutRefundNo(), response);
|
||||||
}
|
}
|
||||||
// 2.2 创建返回结果
|
// 2.2 创建返回结果
|
||||||
@ -198,6 +202,8 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||||||
return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
|
return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ========== 各种工具方法 ==========
|
// ========== 各种工具方法 ==========
|
||||||
|
|
||||||
protected String formatAmount(Integer amount) {
|
protected String formatAmount(Integer amount) {
|
||||||
|
@ -2,6 +2,8 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
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.order.PayOrderUnifiedReqDTO;
|
||||||
|
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.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
||||||
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayApiException;
|
||||||
@ -57,4 +59,8 @@ public class AlipayAppPayClient extends AbstractAlipayPayClient {
|
|||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("支付宝【App 支付】不支持转账操作");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import cn.hutool.core.map.MapUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
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.order.PayOrderUnifiedReqDTO;
|
||||||
|
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.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
||||||
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayApiException;
|
||||||
@ -75,4 +77,8 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
|
|||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("支付宝【条码支付】不支持转账操作");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import cn.hutool.core.util.ObjectUtil;
|
|||||||
import cn.hutool.http.Method;
|
import cn.hutool.http.Method;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
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.order.PayOrderUnifiedReqDTO;
|
||||||
|
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.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
||||||
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayApiException;
|
||||||
@ -67,4 +69,8 @@ public class AlipayPcPayClient extends AbstractAlipayPayClient {
|
|||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("支付宝【PC 网站】不支持转账操作");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
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.order.PayOrderUnifiedReqDTO;
|
||||||
|
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.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
||||||
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayApiException;
|
||||||
@ -54,4 +56,8 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
|
|||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("支付宝【扫码支付】不支持转账操作");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,105 @@
|
|||||||
|
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
|
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.enums.channel.PayChannelEnum;
|
||||||
|
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||||
|
import com.alipay.api.AlipayApiException;
|
||||||
|
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
|
||||||
|
import com.alipay.api.domain.Participant;
|
||||||
|
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
|
||||||
|
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝转账的 PayClient 实现类
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class AlipayTransferClient extends AbstractAlipayPayClient {
|
||||||
|
public AlipayTransferClient(Long channelId, AlipayPayClientConfig config) {
|
||||||
|
super(channelId, PayChannelEnum.ALIPAY_TRANSFER.getCode(), config);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("支付宝转账不支持统一下单请求");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("支付宝转账不支持统一退款请求");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException {
|
||||||
|
// 1.1 构建 AlipayFundTransUniTransferModel
|
||||||
|
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
|
||||||
|
// ① 通用的参数
|
||||||
|
model.setTransAmount(formatAmount(reqDTO.getPrice())); // 转账金额
|
||||||
|
model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。
|
||||||
|
model.setOutBizNo(reqDTO.getOutTransferNo());
|
||||||
|
model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD
|
||||||
|
model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER。
|
||||||
|
model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras()));
|
||||||
|
PayTransferTypeEnum transferType = PayTransferTypeEnum.valueOf(reqDTO.getType());
|
||||||
|
switch(transferType){
|
||||||
|
case WX_BALANCE :
|
||||||
|
case WALLET_BALANCE : {
|
||||||
|
log.error("[doUnifiedTransfer],支付宝转账不支持的转账类型{}", transferType);
|
||||||
|
throw new UnsupportedOperationException(String.format("支付宝转账不支持转账类型: %s",transferType.getName()));
|
||||||
|
}
|
||||||
|
case ALIPAY_BALANCE : {
|
||||||
|
// ② 个性化的参数
|
||||||
|
Participant payeeInfo = new Participant();
|
||||||
|
payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
|
||||||
|
String logonId = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_LOGON_ID");
|
||||||
|
if (StrUtil.isEmpty(logonId)) {
|
||||||
|
throw exception0(BAD_REQUEST.getCode(), "支付包登录 ID 不能为空");
|
||||||
|
}
|
||||||
|
String accountName = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_ACCOUNT_NAME");
|
||||||
|
if (StrUtil.isEmpty(accountName)) {
|
||||||
|
throw exception0(BAD_REQUEST.getCode(), "支付包账户名称不能为空");
|
||||||
|
}
|
||||||
|
payeeInfo.setIdentity(logonId); // 支付宝登录号
|
||||||
|
payeeInfo.setName(accountName); // 支付宝账号姓名
|
||||||
|
model.setPayeeInfo(payeeInfo);
|
||||||
|
// 1.2 构建 AlipayFundTransUniTransferRequest
|
||||||
|
AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
|
||||||
|
request.setBizModel(model);
|
||||||
|
// 执行请求
|
||||||
|
AlipayFundTransUniTransferResponse response = client.certificateExecute(request);
|
||||||
|
// 处理结果
|
||||||
|
if (!response.isSuccess()) {
|
||||||
|
// 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
|
||||||
|
if (Objects.equals(response.getSubCode(), "SYSTEM_ERROR")) {
|
||||||
|
return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response);
|
||||||
|
}
|
||||||
|
return PayTransferRespDTO.failureOf(response.getSubCode(), response.getSubMsg(),
|
||||||
|
reqDTO.getOutTransferNo(), response);
|
||||||
|
|
||||||
|
}
|
||||||
|
return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()),
|
||||||
|
response.getOutBizNo(), response);
|
||||||
|
}
|
||||||
|
case BANK_CARD : {
|
||||||
|
Participant payeeInfo = new Participant();
|
||||||
|
payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
|
||||||
|
throw new UnsupportedOperationException("待实现");
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new IllegalStateException("不正确的转账类型: " + transferType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,8 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|||||||
import cn.hutool.http.Method;
|
import cn.hutool.http.Method;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
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.order.PayOrderUnifiedReqDTO;
|
||||||
|
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.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
||||||
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayApiException;
|
||||||
@ -56,4 +58,8 @@ public class AlipayWapPayClient extends AbstractAlipayPayClient {
|
|||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("支付宝【Wap 网站】不支持转账操作");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.order.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
|
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.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.AbstractPayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
@ -64,4 +66,8 @@ public class MockPayClient extends AbstractPayClient<NonePayClientConfig> {
|
|||||||
throw new UnsupportedOperationException("模拟支付无支付回调");
|
throw new UnsupportedOperationException("模拟支付无支付回调");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("待实现");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.order.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
|
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.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.AbstractPayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
|
||||||
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
|
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
|
||||||
@ -425,6 +427,10 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("待实现");
|
||||||
|
}
|
||||||
// ========== 各种工具方法 ==========
|
// ========== 各种工具方法 ==========
|
||||||
|
|
||||||
static String formatDateV2(LocalDateTime time) {
|
static String formatDateV2(LocalDateTime time) {
|
||||||
|
@ -28,6 +28,7 @@ public enum PayChannelEnum {
|
|||||||
ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class),
|
ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class),
|
||||||
ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class),
|
ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class),
|
||||||
ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class),
|
ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class),
|
||||||
|
ALIPAY_TRANSFER("alipay_transfer", "支付宝转账", AlipayPayClientConfig.class),
|
||||||
|
|
||||||
MOCK("mock", "模拟支付", NonePayClientConfig.class),
|
MOCK("mock", "模拟支付", NonePayClientConfig.class),
|
||||||
|
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.framework.pay.core.enums.transfer;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渠道的转账状态枚举
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum PayTransferStatusRespEnum {
|
||||||
|
|
||||||
|
WAITING(0, "等待转账"),
|
||||||
|
SUCCESS(10, "转账成功"),
|
||||||
|
FAILURE(20, "转账失败");
|
||||||
|
|
||||||
|
private final Integer status;
|
||||||
|
private final String name;
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package cn.iocoder.yudao.framework.pay.core.enums.transfer;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账类型枚举
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum PayTransferTypeEnum implements IntArrayValuable {
|
||||||
|
ALIPAY_BALANCE(1, "支付宝余额"),
|
||||||
|
WX_BALANCE(2, "微信余额"),
|
||||||
|
BANK_CARD(3, "银行卡"),
|
||||||
|
WALLET_BALANCE(4, "钱包余额");
|
||||||
|
|
||||||
|
private final Integer type;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PayTransferTypeEnum::getType).toArray();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] array() {
|
||||||
|
return ARRAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PayTransferTypeEnum valueOf(Integer type) {
|
||||||
|
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||||
|
}
|
||||||
|
}
|
@ -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.order.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
|
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.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.AbstractPayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
@ -174,4 +176,8 @@ public class WalletPayClient extends AbstractPayClient<NonePayClientConfig> {
|
|||||||
throw new IllegalStateException(String.format("支付退款单[%s] 状态不正确", outRefundNo));
|
throw new IllegalStateException(String.format("支付退款单[%s] 状态不正确", outRefundNo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||||
|
throw new UnsupportedOperationException("待实现");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user