mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-02-21 19:50:32 +08:00
转账 - 支付宝转账修改, 支付宝 Client 支持公钥证书模式
This commit is contained in:
parent
00e18a480f
commit
183206e2d3
@ -50,8 +50,6 @@ public class PayClientFactoryImpl implements PayClientFactory {
|
|||||||
clientClass.put(ALIPAY_APP, AlipayAppPayClient.class);
|
clientClass.put(ALIPAY_APP, AlipayAppPayClient.class);
|
||||||
clientClass.put(ALIPAY_PC, AlipayPcPayClient.class);
|
clientClass.put(ALIPAY_PC, AlipayPcPayClient.class);
|
||||||
clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class);
|
clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class);
|
||||||
// 支付包转账客户端
|
|
||||||
clientClass.put(ALIPAY_TRANSFER, AlipayTransferClient.class);
|
|
||||||
// Mock 支付客户端
|
// Mock 支付客户端
|
||||||
clientClass.put(MOCK, MockPayClient.class);
|
clientClass.put(MOCK, MockPayClient.class);
|
||||||
}
|
}
|
||||||
|
@ -6,24 +6,28 @@ import cn.hutool.core.lang.Assert;
|
|||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||||
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.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 cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||||
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayApiException;
|
||||||
import com.alipay.api.AlipayConfig;
|
import com.alipay.api.AlipayConfig;
|
||||||
import com.alipay.api.AlipayResponse;
|
import com.alipay.api.AlipayResponse;
|
||||||
import com.alipay.api.DefaultAlipayClient;
|
import com.alipay.api.DefaultAlipayClient;
|
||||||
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
|
import com.alipay.api.domain.*;
|
||||||
import com.alipay.api.domain.AlipayTradeQueryModel;
|
|
||||||
import com.alipay.api.domain.AlipayTradeRefundModel;
|
|
||||||
import com.alipay.api.internal.util.AlipaySignature;
|
import com.alipay.api.internal.util.AlipaySignature;
|
||||||
|
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
|
||||||
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
|
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
|
||||||
import com.alipay.api.request.AlipayTradeQueryRequest;
|
import com.alipay.api.request.AlipayTradeQueryRequest;
|
||||||
import com.alipay.api.request.AlipayTradeRefundRequest;
|
import com.alipay.api.request.AlipayTradeRefundRequest;
|
||||||
|
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
|
||||||
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
|
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
|
||||||
import com.alipay.api.response.AlipayTradeQueryResponse;
|
import com.alipay.api.response.AlipayTradeQueryResponse;
|
||||||
import com.alipay.api.response.AlipayTradeRefundResponse;
|
import com.alipay.api.response.AlipayTradeRefundResponse;
|
||||||
@ -39,6 +43,9 @@ import java.util.Objects;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
|
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝抽象类,实现支付宝统一的接口、以及部分实现(退款)
|
* 支付宝抽象类,实现支付宝统一的接口、以及部分实现(退款)
|
||||||
@ -105,16 +112,20 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||||||
// 1.2 构建 AlipayTradeQueryRequest 请求
|
// 1.2 构建 AlipayTradeQueryRequest 请求
|
||||||
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
|
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
|
||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
|
AlipayTradeQueryResponse response;
|
||||||
// 2.1 执行请求
|
if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||||
AlipayTradeQueryResponse response = client.execute(request);
|
// 证书模式
|
||||||
|
response = client.certificateExecute(request);
|
||||||
|
} else {
|
||||||
|
response = client.execute(request);
|
||||||
|
}
|
||||||
if (!response.isSuccess()) { // 不成功,例如说订单不存在
|
if (!response.isSuccess()) { // 不成功,例如说订单不存在
|
||||||
return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
|
return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
|
||||||
outTradeNo, response);
|
outTradeNo, response);
|
||||||
}
|
}
|
||||||
// 2.2 解析订单的状态
|
// 2.2 解析订单的状态
|
||||||
Integer status = parseStatus(response.getTradeStatus());
|
Integer status = parseStatus(response.getTradeStatus());
|
||||||
Assert.notNull(status, (Supplier<Throwable>) () -> {
|
Assert.notNull(status, () -> {
|
||||||
throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody()));
|
throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody()));
|
||||||
});
|
});
|
||||||
return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()),
|
return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()),
|
||||||
@ -148,7 +159,13 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
|
|
||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradeRefundResponse response = client.execute(request);
|
AlipayTradeRefundResponse response;
|
||||||
|
if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||||
|
// 证书模式
|
||||||
|
response = client.certificateExecute(request);
|
||||||
|
} else {
|
||||||
|
response = client.execute(request);
|
||||||
|
}
|
||||||
if (!response.isSuccess()) {
|
if (!response.isSuccess()) {
|
||||||
// 当出现 ACQ.SYSTEM_ERROR, 退款可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
|
// 当出现 ACQ.SYSTEM_ERROR, 退款可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
|
||||||
if (ObjectUtils.equalsAny(response.getSubCode(), "ACQ.SYSTEM_ERROR", "SYSTEM_ERROR")) {
|
if (ObjectUtils.equalsAny(response.getSubCode(), "ACQ.SYSTEM_ERROR", "SYSTEM_ERROR")) {
|
||||||
@ -185,7 +202,13 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
|
|
||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradeFastpayRefundQueryResponse response = client.execute(request);
|
AlipayTradeFastpayRefundQueryResponse response;
|
||||||
|
if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||||
|
// 证书模式
|
||||||
|
response = client.certificateExecute(request);
|
||||||
|
} else {
|
||||||
|
response = client.execute(request);
|
||||||
|
}
|
||||||
if (!response.isSuccess()) {
|
if (!response.isSuccess()) {
|
||||||
// 明确不存在的情况,应该就是失败,可进行关闭
|
// 明确不存在的情况,应该就是失败,可进行关闭
|
||||||
if (ObjectUtils.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) {
|
if (ObjectUtils.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) {
|
||||||
@ -202,7 +225,69 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
|||||||
return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
|
return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException {
|
||||||
|
// 1.1 校验公钥类型 必须使用公钥证书模式
|
||||||
|
if (!Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||||
|
throw new IllegalStateException("支付宝单笔转账必须使用公钥证书模式");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.2 构建 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.typeOf(reqDTO.getType());
|
||||||
|
switch (transferType) {
|
||||||
|
// TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦?
|
||||||
|
// @芋艿。 是不是还要考虑转账到银行卡。所以传 transferType 但是转账到银行卡不知道要如何测试??
|
||||||
|
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.3 构建 AlipayFundTransUniTransferRequest
|
||||||
|
AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
|
||||||
|
request.setBizModel(model);
|
||||||
|
// 执行请求
|
||||||
|
AlipayFundTransUniTransferResponse response = client.certificateExecute(request);
|
||||||
|
// 处理结果
|
||||||
|
if (!response.isSuccess()) {
|
||||||
|
// 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
|
||||||
|
if (ObjectUtils.equalsAny(response.getSubCode(), "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
|
||||||
|
return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response);
|
||||||
|
}
|
||||||
|
return PayTransferRespDTO.closedOf(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");
|
||||||
|
// TODO 待实现
|
||||||
|
throw new UnsupportedOperationException("待实现");
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new IllegalStateException("不正确的转账类型: " + transferType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ========== 各种工具方法 ==========
|
// ========== 各种工具方法 ==========
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ 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;
|
||||||
@ -58,9 +56,4 @@ public class AlipayAppPayClient extends AbstractAlipayPayClient {
|
|||||||
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
|
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
|
||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
|
||||||
throw new UnsupportedOperationException("支付宝【App 支付】不支持转账操作");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ 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;
|
||||||
@ -16,9 +14,11 @@ import com.alipay.api.response.AlipayTradePayResponse;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝【条码支付】的 PayClient 实现类
|
* 支付宝【条码支付】的 PayClient 实现类
|
||||||
@ -61,7 +61,13 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
|
|||||||
request.setReturnUrl(reqDTO.getReturnUrl());
|
request.setReturnUrl(reqDTO.getReturnUrl());
|
||||||
|
|
||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradePayResponse response = client.execute(request);
|
AlipayTradePayResponse response;
|
||||||
|
if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||||
|
// 证书模式
|
||||||
|
response = client.certificateExecute(request);
|
||||||
|
} else {
|
||||||
|
response = client.execute(request);
|
||||||
|
}
|
||||||
// 2.2 处理结果
|
// 2.2 处理结果
|
||||||
if (!response.isSuccess()) {
|
if (!response.isSuccess()) {
|
||||||
return buildClosedPayOrderRespDTO(reqDTO, response);
|
return buildClosedPayOrderRespDTO(reqDTO, response);
|
||||||
@ -76,9 +82,4 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
|
|||||||
return PayOrderRespDTO.waitingOf(displayMode, "",
|
return PayOrderRespDTO.waitingOf(displayMode, "",
|
||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
|
||||||
throw new UnsupportedOperationException("支付宝【条码支付】不支持转账操作");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ 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;
|
||||||
@ -68,9 +66,4 @@ public class AlipayPcPayClient extends AbstractAlipayPayClient {
|
|||||||
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
|
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
|
||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
|
||||||
throw new UnsupportedOperationException("支付宝【PC 网站】不支持转账操作");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ 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;
|
||||||
@ -12,6 +10,10 @@ import com.alipay.api.request.AlipayTradePrecreateRequest;
|
|||||||
import com.alipay.api.response.AlipayTradePrecreateResponse;
|
import com.alipay.api.response.AlipayTradePrecreateResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝【扫码支付】的 PayClient 实现类
|
* 支付宝【扫码支付】的 PayClient 实现类
|
||||||
*
|
*
|
||||||
@ -47,7 +49,13 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
|
|||||||
request.setReturnUrl(reqDTO.getReturnUrl());
|
request.setReturnUrl(reqDTO.getReturnUrl());
|
||||||
|
|
||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradePrecreateResponse response = client.execute(request);
|
AlipayTradePrecreateResponse response;
|
||||||
|
if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||||
|
// 证书模式
|
||||||
|
response = client.certificateExecute(request);
|
||||||
|
} else {
|
||||||
|
response = client.execute(request);
|
||||||
|
}
|
||||||
// 2.2 处理结果
|
// 2.2 处理结果
|
||||||
if (!response.isSuccess()) {
|
if (!response.isSuccess()) {
|
||||||
return buildClosedPayOrderRespDTO(reqDTO, response);
|
return buildClosedPayOrderRespDTO(reqDTO, response);
|
||||||
@ -55,9 +63,4 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
|
|||||||
return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(),
|
return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(),
|
||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
|
||||||
throw new UnsupportedOperationException("支付宝【扫码支付】不支持转账操作");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
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.common.util.object.ObjectUtils;
|
|
||||||
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 static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
|
||||||
|
|
||||||
// TODO @jason:看看能不能融合到 AbstractAlipayPayClient 中。
|
|
||||||
/**
|
|
||||||
* 支付宝转账的 PayClient 实现类
|
|
||||||
*
|
|
||||||
* @author jason
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class AlipayTransferClient extends AbstractAlipayPayClient {
|
|
||||||
// TODO @jason:方法之间,要有空格噢
|
|
||||||
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.ofType(reqDTO.getType());
|
|
||||||
switch(transferType) {
|
|
||||||
case WX_BALANCE:
|
|
||||||
case WALLET_BALANCE: {
|
|
||||||
log.error("[doUnifiedTransfer],支付宝转账不支持的转账类型{}", transferType);
|
|
||||||
throw new UnsupportedOperationException(String.format("支付宝转账不支持转账类型: %s",transferType.getName()));
|
|
||||||
}
|
|
||||||
// TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦?
|
|
||||||
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 (ObjectUtils.equalsAny(response.getSubCode(), "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
|
|
||||||
return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response);
|
|
||||||
}
|
|
||||||
return PayTransferRespDTO.closedOf(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,8 +3,6 @@ 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;
|
||||||
@ -57,9 +55,4 @@ public class AlipayWapPayClient extends AbstractAlipayPayClient {
|
|||||||
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
|
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
|
||||||
reqDTO.getOutTradeNo(), response);
|
reqDTO.getOutTradeNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
|
||||||
throw new UnsupportedOperationException("支付宝【Wap 网站】不支持转账操作");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,6 @@ 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),
|
||||||
// TODO @jason:是不是按照微信聊的,合并回 ALIPAY_PC;因为支付宝、微信都是多种支付方式,选择其中的一种即可;
|
|
||||||
ALIPAY_TRANSFER("alipay_transfer", "支付宝转账", AlipayPayClientConfig.class),
|
|
||||||
|
|
||||||
MOCK("mock", "模拟支付", NonePayClientConfig.class),
|
MOCK("mock", "模拟支付", NonePayClientConfig.class),
|
||||||
|
|
||||||
WALLET("wallet", "钱包支付", NonePayClientConfig.class);
|
WALLET("wallet", "钱包支付", NonePayClientConfig.class);
|
||||||
|
@ -34,8 +34,7 @@ public enum PayTransferTypeEnum implements IntArrayValuable {
|
|||||||
return ARRAYS;
|
return ARRAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @jason:是不是 typeOf 更符合预期哈?
|
public static PayTransferTypeEnum typeOf(Integer type) {
|
||||||
public static PayTransferTypeEnum ofType(Integer type) {
|
|
||||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService {
|
|||||||
|
|
||||||
// TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验
|
// TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验
|
||||||
private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) {
|
private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) {
|
||||||
PayTransferTypeEnum transferTypeEnum = ofType(transferType);
|
PayTransferTypeEnum transferTypeEnum = typeOf(transferType);
|
||||||
switch (transferTypeEnum) {
|
switch (transferTypeEnum) {
|
||||||
case ALIPAY_BALANCE: {
|
case ALIPAY_BALANCE: {
|
||||||
if (StrUtil.isEmpty(MapUtil.getStr(payeeInfo, ALIPAY_LOGON_ID))) {
|
if (StrUtil.isEmpty(MapUtil.getStr(payeeInfo, ALIPAY_LOGON_ID))) {
|
||||||
|
@ -214,11 +214,11 @@ public class PayTransferServiceImpl implements PayTransferService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void validateChannelCodeAndTypeMatch(String channelCode, Integer type) {
|
private void validateChannelCodeAndTypeMatch(String channelCode, Integer type) {
|
||||||
PayTransferTypeEnum transferType = PayTransferTypeEnum.ofType(type);
|
PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(type);
|
||||||
PayChannelEnum payChannel = PayChannelEnum.getByCode(channelCode);
|
PayChannelEnum payChannel = PayChannelEnum.getByCode(channelCode);
|
||||||
switch (transferType) {
|
switch (transferType) {
|
||||||
case ALIPAY_BALANCE: {
|
case ALIPAY_BALANCE: {
|
||||||
if (payChannel != PayChannelEnum.ALIPAY_TRANSFER) {
|
if (!payChannel.getCode().startsWith("alipay")) {
|
||||||
throw exception(PAY_TRANSFER_TYPE_AND_CHANNEL_NOT_MATCH);
|
throw exception(PAY_TRANSFER_TYPE_AND_CHANNEL_NOT_MATCH);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user