reactor:移除 PayClient 获取转账时的 type 字段,只有支付宝会区分,后续通过 channelExtras 区分
This commit is contained in:
parent
5327d3a494
commit
ffee189589
|
@ -44,7 +44,6 @@ public class PayDemoTransferCreateReqVO {
|
|||
@NotBlank(message = "微信 openId 不能为空", groups = {WxPay.class})
|
||||
private String openid;
|
||||
|
||||
|
||||
// ========== 转账到银行卡和钱包相关字段 待补充 ==========
|
||||
|
||||
public void validate(Validator validator) {
|
||||
|
|
|
@ -14,12 +14,11 @@ 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;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
|
||||
import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
|
||||
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
|
||||
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
|
||||
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
||||
import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
|
||||
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
|
||||
|
@ -188,7 +187,7 @@ public class WalletPayClient extends AbstractPayClient<NonePayClientConfig> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) {
|
||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo) {
|
||||
throw new UnsupportedOperationException("待实现");
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClient;
|
|||
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.transfer.PayTransferStatusRespEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO;
|
||||
|
@ -283,8 +282,7 @@ public class PayTransferServiceImpl implements PayTransferService {
|
|||
log.error("[syncTransfer][渠道编号({}) 找不到对应的支付客户端]", transfer.getChannelId());
|
||||
return false;
|
||||
}
|
||||
PayTransferRespDTO resp = payClient.getTransfer(transfer.getNo(),
|
||||
PayTransferTypeEnum.typeOf(transfer.getType()));
|
||||
PayTransferRespDTO resp = payClient.getTransfer(transfer.getNo());
|
||||
|
||||
// 2. 回调转账结果
|
||||
notifyTransfer(transfer.getChannelId(), resp);
|
||||
|
|
|
@ -6,7 +6,6 @@ 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.transfer.PayTransferTypeEnum;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -95,10 +94,9 @@ public interface PayClient {
|
|||
* 获得转账订单信息
|
||||
*
|
||||
* @param outTradeNo 外部订单号
|
||||
* @param type 转账类型
|
||||
* @return 转账信息
|
||||
*/
|
||||
PayTransferRespDTO getTransfer(String outTradeNo, PayTransferTypeEnum type);
|
||||
PayTransferRespDTO getTransfer(String outTradeNo);
|
||||
|
||||
/**
|
||||
* 解析 transfer 回调数据
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
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 jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.*;
|
||||
import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.Alipay;
|
||||
import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.WxPay;
|
||||
|
||||
/**
|
||||
* 统一转账 Request DTO
|
||||
|
@ -23,15 +21,6 @@ import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferType
|
|||
@Data
|
||||
public class PayTransferUnifiedReqDTO {
|
||||
|
||||
/**
|
||||
* 转账类型
|
||||
*
|
||||
* 关联 {@link PayTransferTypeEnum#getType()}
|
||||
*/
|
||||
@NotNull(message = "转账类型不能为空")
|
||||
@InEnum(PayTransferTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
|
@ -55,6 +44,7 @@ public class PayTransferUnifiedReqDTO {
|
|||
@Length(max = 128, message = "转账标题不能超过 128")
|
||||
private String subject;
|
||||
|
||||
// TODO @芋艿:userName、alipayLogonId、openid =》channelExtras;另外:validatePayTransferReqDTO 去掉;
|
||||
/**
|
||||
* 收款人姓名
|
||||
*/
|
||||
|
|
|
@ -188,7 +188,6 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||
|
||||
@Override
|
||||
public final PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||
validatePayTransferReqDTO(reqDTO);
|
||||
PayTransferRespDTO resp;
|
||||
try {
|
||||
resp = doUnifiedTransfer(reqDTO);
|
||||
|
@ -202,22 +201,6 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||
}
|
||||
return resp;
|
||||
}
|
||||
private void validatePayTransferReqDTO(PayTransferUnifiedReqDTO reqDTO) {
|
||||
PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(reqDTO.getType());
|
||||
switch (transferType) {
|
||||
case ALIPAY_BALANCE: {
|
||||
ValidationUtils.validate(reqDTO, PayTransferTypeEnum.Alipay.class);
|
||||
break;
|
||||
}
|
||||
case WX_BALANCE: {
|
||||
ValidationUtils.validate(reqDTO, PayTransferTypeEnum.WxPay.class);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw exception(NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final PayTransferRespDTO parseTransferNotify(Map<String, String> params, String body, Map<String, String> headers) {
|
||||
|
@ -236,14 +219,14 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||
throws Throwable;
|
||||
|
||||
@Override
|
||||
public final PayTransferRespDTO getTransfer(String outTradeNo, PayTransferTypeEnum type) {
|
||||
public final PayTransferRespDTO getTransfer(String outTradeNo) {
|
||||
try {
|
||||
return doGetTransfer(outTradeNo, type);
|
||||
return doGetTransfer(outTradeNo);
|
||||
} catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
log.error("[getTransfer][客户端({}) outTradeNo({}) type({}) 查询转账单异常]",
|
||||
getId(), outTradeNo, type, ex);
|
||||
log.error("[getTransfer][客户端({}) outTradeNo({}) 查询转账单异常]",
|
||||
getId(), outTradeNo, ex);
|
||||
throw buildPayException(ex);
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +234,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||
protected abstract PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO)
|
||||
throws Throwable;
|
||||
|
||||
protected abstract PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type)
|
||||
protected abstract PayTransferRespDTO doGetTransfer(String outTradeNo)
|
||||
throws Throwable;
|
||||
|
||||
// ========== 各种工具方法 ==========
|
||||
|
|
|
@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
|
|||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
|
@ -16,7 +17,6 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDT
|
|||
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 cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||
import com.alipay.api.AlipayApiException;
|
||||
import com.alipay.api.AlipayConfig;
|
||||
import com.alipay.api.AlipayResponse;
|
||||
|
@ -40,8 +40,7 @@ import java.util.Objects;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.ERROR_CONFIGURATION;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
|
||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_PUBLIC_KEY;
|
||||
|
@ -236,11 +235,12 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||
|
||||
@Override
|
||||
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException {
|
||||
// 1.1 校验公钥类型 必须使用公钥证书模式
|
||||
if (!Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||
// 0. 校验公钥类型:必须使用公钥证书模式
|
||||
if (ObjectUtil.notEqual(config.getMode(), MODE_CERTIFICATE)) {
|
||||
throw exception0(ERROR_CONFIGURATION.getCode(), "支付宝单笔转账必须使用公钥证书模式");
|
||||
}
|
||||
// 1.2 构建 AlipayFundTransUniTransferModel
|
||||
|
||||
// 1.1 构建 AlipayFundTransUniTransferModel
|
||||
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
|
||||
// ① 通用的参数
|
||||
model.setTransAmount(formatAmount(reqDTO.getPrice())); // 转账金额
|
||||
|
@ -253,32 +253,16 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||
}
|
||||
// ② 个性化的参数
|
||||
Participant payeeInfo = new Participant();
|
||||
PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(reqDTO.getType());
|
||||
switch (transferType) {
|
||||
// TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦?
|
||||
// @芋艿。 是不是还要考虑转账到银行卡。所以传 transferType 但是转账到银行卡不知道要如何测试??
|
||||
case ALIPAY_BALANCE: {
|
||||
payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
|
||||
payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); // 暂时只考虑转账到支付宝,银行没有权限 https://opendocs.alipay.com/open/02byvc?scene=66dd06f5a923403393b85de68d3c0055
|
||||
payeeInfo.setIdentity(reqDTO.getAlipayLogonId()); // 支付宝登录号
|
||||
payeeInfo.setName(reqDTO.getUserName()); // 支付宝账号姓名
|
||||
model.setPayeeInfo(payeeInfo);
|
||||
break;
|
||||
}
|
||||
case BANK_CARD: {
|
||||
payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
|
||||
// TODO 待实现
|
||||
throw exception(NOT_IMPLEMENTED);
|
||||
}
|
||||
default: {
|
||||
throw exception0(BAD_REQUEST.getCode(), "不正确的转账类型: {}", transferType);
|
||||
}
|
||||
}
|
||||
// 1.3 构建 AlipayFundTransUniTransferRequest
|
||||
// 1.2 构建 AlipayFundTransUniTransferRequest
|
||||
AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
|
||||
request.setBizModel(model);
|
||||
// 执行请求
|
||||
|
||||
// 2.1 执行请求
|
||||
AlipayFundTransUniTransferResponse response = client.certificateExecute(request);
|
||||
// 处理结果
|
||||
if (!response.isSuccess()) {
|
||||
// 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询,或相同 outBizNo 重新发起转账
|
||||
// 发现 outBizNo 相同 两次请求参数相同. 会返回 "PAYMENT_INFO_INCONSISTENCY", 不知道哪里的问题. 暂时返回 WAIT. 后续job 会轮询
|
||||
|
@ -287,7 +271,8 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||
}
|
||||
return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
|
||||
reqDTO.getOutTransferNo(), response);
|
||||
} else {
|
||||
}
|
||||
// 2.2 处理结果
|
||||
if (ObjectUtils.equalsAny(response.getStatus(), "REFUND", "FAIL")) { // 转账到银行卡会出现 "REFUND" "FAIL"
|
||||
return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
|
||||
reqDTO.getOutTransferNo(), response);
|
||||
|
@ -299,13 +284,11 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||
response.getOutBizNo(), response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) throws Throwable {
|
||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo) throws Throwable {
|
||||
// 1.1 构建 AlipayFundTransCommonQueryModel
|
||||
AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel();
|
||||
model.setProductCode(type == PayTransferTypeEnum.BANK_CARD ? "TRANS_BANKCARD_NO_PWD" : "TRANS_ACCOUNT_NO_PWD");
|
||||
model.setProductCode("TRANS_ACCOUNT_NO_PWD");
|
||||
model.setBizScene("DIRECT_TRANSFER"); //业务场景
|
||||
model.setOutBizNo(outTradeNo);
|
||||
// 1.2 构建 AlipayFundTransCommonQueryRequest
|
||||
|
@ -319,8 +302,16 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||
} else {
|
||||
response = client.execute(request);
|
||||
}
|
||||
if (!response.isSuccess()) {
|
||||
// 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询, 或相同 outBizNo 重新发起转账
|
||||
// 当出现 ORDER_NOT_EXIST 可能是转账还在处理中,也可能是转账处理失败. 返回 WAIT 状态. 后续 job 会轮询, 或相同 outBizNo 重新发起转账
|
||||
if (ObjectUtils.equalsAny(response.getSubCode(), "ORDER_NOT_EXIST", "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
|
||||
return PayTransferRespDTO.waitingOf(null, outTradeNo, response);
|
||||
}
|
||||
return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
|
||||
outTradeNo, response);
|
||||
}
|
||||
// 2.2 处理返回结果
|
||||
if (response.isSuccess()) {
|
||||
if (ObjectUtils.equalsAny(response.getStatus(), "REFUND", "FAIL")) { // 转账到银行卡会出现 "REFUND" "FAIL"
|
||||
return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
|
||||
outTradeNo, response);
|
||||
|
@ -330,15 +321,6 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||
}
|
||||
return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getPayDate()),
|
||||
response.getOutBizNo(), response);
|
||||
} else {
|
||||
// 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询, 或相同 outBizNo 重新发起转账
|
||||
// 当出现 ORDER_NOT_EXIST 可能是转账还在处理中,也可能是转账处理失败. 返回 WAIT 状态. 后续 job 会轮询, 或相同 outBizNo 重新发起转账
|
||||
if (ObjectUtils.equalsAny(response.getSubCode(), "ORDER_NOT_EXIST", "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
|
||||
return PayTransferRespDTO.waitingOf(null, outTradeNo, response);
|
||||
}
|
||||
return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
|
||||
outTradeNo, response);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @chihuo:这里是不是也要实现,支付宝的。
|
||||
|
|
|
@ -9,7 +9,6 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifie
|
|||
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;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
@ -78,7 +77,7 @@ public class MockPayClient extends AbstractPayClient<NonePayClientConfig> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) {
|
||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo) {
|
||||
throw new UnsupportedOperationException("待实现");
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifie
|
|||
import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.WxPayTransferPartnerNotifyV3Result;
|
||||
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.transfer.PayTransferTypeEnum;
|
||||
import com.github.binarywang.wxpay.bean.notify.*;
|
||||
import com.github.binarywang.wxpay.bean.request.*;
|
||||
import com.github.binarywang.wxpay.bean.result.*;
|
||||
|
@ -489,7 +488,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
|||
}
|
||||
|
||||
@Override
|
||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) throws WxPayException {
|
||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo) throws WxPayException {
|
||||
QueryTransferBatchesRequest request = QueryTransferBatchesRequest.newBuilder()
|
||||
.outBatchNo(outTradeNo).needQueryDetail(true).offset(0).limit(20).detailStatus("ALL")
|
||||
.build();
|
||||
|
|
|
@ -7,6 +7,7 @@ import lombok.Getter;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
// TODO @芋艿:【转账】这里要不要改成支付平台?
|
||||
/**
|
||||
* 转账类型枚举
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue