ref 支付宝支付替换为原生SDK方式

This commit is contained in:
bootx
2024-06-16 17:20:39 +08:00
parent 676c0b3232
commit 72ac03f842
6 changed files with 154 additions and 44 deletions

View File

@@ -13,7 +13,20 @@ import lombok.Setter;
@Setter
public class AliPayParam implements ChannelParam {
/** 授权码(主动扫描用户的付款码) */
/**
* 授权码(主动扫描用户的付款码)
*/
private String authCode;
/**
* 【描述】小程序支付中商户实际经营主体的小程序应用的appid也即最终唤起收银台支付所在的小程序的应用id
* 【注意事项】商户需要先在产品管理中心绑定该小程序appid否则下单会失败
*/
private String opAppId;
/**
* 买家支付宝用户唯一标识
*/
private String openId;
}

View File

@@ -12,7 +12,23 @@ import lombok.Data;
@Schema(title = "支付宝支付参数")
public class AliPayParam implements ChannelParam {
/**
* 授权码(主动扫描用户的付款码)
*/
@Schema(description = "授权码(主动扫描用户的付款码)")
private String authCode;
/**
* 【描述】小程序支付中商户实际经营主体的小程序应用的appid也即最终唤起收银台支付所在的小程序的应用id
* 【注意事项】商户需要先在产品管理中心绑定该小程序appid否则下单会失败
*/
@Schema(description = "商户实际经营主体的小程序应用的appid")
private String opAppId;
/**
* 买家支付宝用户唯一标识
*/
@Schema(description = "买家支付宝用户唯一标识")
private String openId;
}

View File

@@ -28,6 +28,9 @@ public interface AliPayCode {
/** 询余额账户类型 */
String QUERY_ACCOUNT_TYPE = "ACCTRANS_ACCOUNT";
/** jsapi */
String JSAPI_PAY ="JSAPI_PAY";
/** 付款码支付 */
String BAR_CODE = "bar_code";

View File

@@ -8,12 +8,14 @@ import cn.daxpay.single.service.code.AliPayCode;
import cn.daxpay.single.service.code.AliPayWay;
import cn.daxpay.single.service.core.channel.alipay.dao.AliPayConfigManager;
import cn.daxpay.single.service.core.channel.alipay.entity.AliPayConfig;
import cn.daxpay.single.service.core.system.config.service.PayChannelConfigService;
import cn.daxpay.single.service.core.system.config.service.PlatformConfigService;
import cn.daxpay.single.service.param.channel.alipay.AliPayConfigParam;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.CharsetUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.ijpay.alipay.AliPayApiConfig;
import com.ijpay.alipay.AliPayApiConfigKit;
import lombok.RequiredArgsConstructor;
@@ -39,7 +41,6 @@ public class AliPayConfigService {
/** 默认支付宝配置的主键ID */
private final static Long ID = 0L;
private final AliPayConfigManager alipayConfigManager;
private final PayChannelConfigService payChannelConfigService;
private final PlatformConfigService platformConfigService;
/**
@@ -94,6 +95,38 @@ public class AliPayConfigService {
return platformConfigService.getConfig().getWebsiteUrl() + "/return/pay/alipay";
}
/**
* 获取支付宝SDK的配置
*/
public AlipayClient getAlipayClient(){
AliPayConfig aliPayConfig = this.getConfig();
return this.getAlipayClient(aliPayConfig);
}
/**
* 获取支付宝SDK的配置
*/
@SneakyThrows
public AlipayClient getAlipayClient(AliPayConfig aliPayConfig){
AlipayConfig config = new AlipayConfig();
config.setServerUrl(aliPayConfig.getServerUrl());
config.setAppId(aliPayConfig.getAppId());
config.setFormat("json");
config.setCharset("UTF-8");
config.setSignType(aliPayConfig.getSignType());
// 证书
if (Objects.equals(aliPayConfig.getAuthType(), AliPayCode.AUTH_TYPE_CART)){
config.setAppCertContent(aliPayConfig.getAppCert());
config.setRootCertContent(aliPayConfig.getAlipayRootCert());
config.setAlipayPublicCertContent(aliPayConfig.getAlipayCert());
} else {
// 公钥
config.setPrivateKey(aliPayConfig.getPrivateKey());
config.setAlipayPublicKey(aliPayConfig.getAlipayPublicKey());
}
return new DefaultAlipayClient(config);
}
/**
* 初始化IJPay服务
*/

View File

@@ -16,13 +16,14 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Method;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayResponse;
import com.alipay.api.domain.*;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.ijpay.alipay.AliPayApi;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -44,6 +45,8 @@ import static cn.daxpay.single.service.code.AliPayCode.QUICK_MSECURITY_PAY;
@RequiredArgsConstructor
public class AliPayService {
private final AliPayConfigService aliPayConfigService;
/**
* 支付前检查支付方式是否可用
*/
@@ -54,7 +57,7 @@ public class AliPayService {
}
// 发起的支付类型是否在支持的范围内
PayMethodEnum payMethodEnum = Optional.ofNullable(AliPayWay.findByCode(payParam.getMethod()))
.orElseThrow(() -> new PayFailureException("非法的支付宝支付类型"));
.orElseThrow(() -> new PayFailureException("非法的支付宝支付类型"));
if (!alipayConfig.getPayWays().contains(payMethodEnum.getCode())) {
throw new PayFailureException("该支付宝支付方式不可用");
}
@@ -88,6 +91,10 @@ public class AliPayService {
else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.WEB.getCode())) {
payBody = this.webPay(amount, payOrder, alipayConfig);
}
// jsapi支付
else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.JSAPI.getCode())) {
payBody = this.jsapiPay(amount, payOrder, aliPayParam, alipayConfig);
}
// 二维码支付
else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.QRCODE.getCode())) {
payBody = this.qrCodePay(amount, payOrder, alipayConfig);
@@ -103,7 +110,11 @@ public class AliPayService {
/**
* wap支付
*/
@SneakyThrows
public String wapPay(String amount, PayOrder payOrder, AliPayConfig alipayConfig) {
// 获取支付宝客户端
AlipayClient alipayClient = aliPayConfigService.getAlipayClient(alipayConfig);
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setSubject(payOrder.getTitle());
model.setOutTradeNo(payOrder.getOrderNo());
@@ -114,7 +125,7 @@ public class AliPayService {
// 是否分账
if (payOrder.getAllocation()){
ExtendParams extendParams = new ExtendParams();
extendParams.setRoyaltyFreeze("true");
extendParams.setRoyaltyFreeze(Boolean.TRUE.toString());
model.setExtendParams(extendParams);
}
@@ -127,7 +138,7 @@ public class AliPayService {
try {
// 通过GET方式的请求, 返回URL的响应, 默认是POST方式的请求, 返回的是表单响应
AlipayTradeWapPayResponse response = AliPayApi.pageExecute(request, Method.GET.name());
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, Method.GET.name());
return response.getBody();
}
catch (AlipayApiException e) {
@@ -139,9 +150,12 @@ public class AliPayService {
/**
* app支付
*/
@SneakyThrows
public String appPay(String amount, PayOrder payOrder, AliPayConfig alipayConfig) {
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
// 获取支付宝客户端
AlipayClient alipayClient = aliPayConfigService.getAlipayClient(alipayConfig);
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setSubject(payOrder.getTitle());
model.setProductCode(QUICK_MSECURITY_PAY);
model.setOutTradeNo(payOrder.getOrderNo());
@@ -151,13 +165,15 @@ public class AliPayService {
// 是否分账
if (payOrder.getAllocation()){
ExtendParams extendParams = new ExtendParams();
extendParams.setRoyaltyFreeze("true");
extendParams.setRoyaltyFreeze(Boolean.TRUE.toString());
model.setExtendParams(extendParams);
}
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setBizModel(model);
request.setNotifyUrl(alipayConfig.getNotifyUrl());
try {
// 异步回调必须到当前系统中
AlipayTradeAppPayResponse response = AliPayApi.appPayToResponse(model, alipayConfig.getNotifyUrl());
AlipayTradeAppPayResponse response = alipayClient.execute(request);
return response.getBody();
}
catch (AlipayApiException e) {
@@ -169,9 +185,12 @@ public class AliPayService {
/**
* PC支付
*/
@SneakyThrows
public String webPay(String amount, PayOrder payOrder, AliPayConfig alipayConfig) {
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
// 获取支付宝客户端
AlipayClient alipayClient = aliPayConfigService.getAlipayClient(alipayConfig);
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
model.setSubject(payOrder.getTitle());
model.setOutTradeNo(payOrder.getOrderNo());
// 过期时间
@@ -183,7 +202,7 @@ public class AliPayService {
// 是否分账
if (payOrder.getAllocation()){
ExtendParams extendParams = new ExtendParams();
extendParams.setRoyaltyFreeze("true");
extendParams.setRoyaltyFreeze(Boolean.TRUE.toString());
model.setExtendParams(extendParams);
}
@@ -195,7 +214,7 @@ public class AliPayService {
request.setReturnUrl(alipayConfig.getReturnUrl());
try {
// 通过GET方式的请求, 返回URL的响应, 默认是POST方式的请求, 返回的是表单响应
AlipayTradePagePayResponse response = AliPayApi.pageExecute(request, Method.GET.name());
AlipayTradePagePayResponse response = alipayClient.pageExecute(request, Method.GET.name());
return response.getBody();
}
catch (AlipayApiException e) {
@@ -204,10 +223,50 @@ public class AliPayService {
}
}
/**
* jsapi支付
*/
@SneakyThrows
public String jsapiPay(String amount, PayOrder payOrder, AliPayParam aliPayParam, AliPayConfig alipayConfig) {
// 获取支付宝客户端
AlipayClient alipayClient = aliPayConfigService.getAlipayClient(alipayConfig);
// 构造请求参数以调用接口
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
AlipayTradeCreateModel model = new AlipayTradeCreateModel();
model.setOutTradeNo(payOrder.getOrderNo());
model.setProductCode(AliPayCode.JSAPI_PAY);
model.setOpAppId(aliPayParam.getOpAppId());
model.setTotalAmount(amount);
model.setSubject(payOrder.getTitle());
model.setOpBuyerOpenId(aliPayParam.getOpenId());
model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime()));
// 是否分账
if (payOrder.getAllocation()){
ExtendParams extendParams = new ExtendParams();
extendParams.setRoyaltyFreeze(Boolean.TRUE.toString());
model.setExtendParams(extendParams);
}
request.setBizModel(model);
try {
AlipayTradeCreateResponse response = alipayClient.execute(request);
this.verifyErrorMsg(response);
// my.tradePay使用支付宝交易号调起支付
return response.getTradeNo();
} catch (AlipayApiException e) {
log.error("支付宝JsApi支付失败", e);
throw new PayFailureException("支付宝JsApi支付失败");
}
}
/**
* 二维码支付(扫码支付)
*/
@SneakyThrows
public String qrCodePay(String amount, PayOrder payOrder, AliPayConfig alipayConfig) {
// 获取支付宝客户端
AlipayClient alipayClient = aliPayConfigService.getAlipayClient(alipayConfig);
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setSubject(payOrder.getTitle());
model.setOutTradeNo(payOrder.getOrderNo());
@@ -215,14 +274,16 @@ public class AliPayService {
// 是否分账
if (payOrder.getAllocation()){
ExtendParams extendParams = new ExtendParams();
extendParams.setRoyaltyFreeze("true");
extendParams.setRoyaltyFreeze(Boolean.TRUE.toString());
model.setExtendParams(extendParams);
}
// 过期时间
model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime()));
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setBizModel(model);
request.setNotifyUrl(alipayConfig.getNotifyUrl());
try {
AlipayTradePrecreateResponse response = AliPayApi.tradePrecreatePayToResponse(model, alipayConfig.getNotifyUrl());
AlipayTradePrecreateResponse response = alipayClient.execute(request);
this.verifyErrorMsg(response);
return response.getQrCode();
}
@@ -235,9 +296,12 @@ public class AliPayService {
/**
* 付款码支付
*/
@SneakyThrows
public void barCode(String amount, PayOrder payOrder, AliPayParam aliPayParam, AliPayConfig alipayConfig) {
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
// 获取支付宝客户端
AlipayClient alipayClient = aliPayConfigService.getAlipayClient(alipayConfig);
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
AlipayTradePayModel model = new AlipayTradePayModel();
model.setSubject(payOrder.getTitle());
model.setOutTradeNo(payOrder.getOrderNo());
@@ -246,14 +310,17 @@ public class AliPayService {
// 是否分账
if (payOrder.getAllocation()){
ExtendParams extendParams = new ExtendParams();
extendParams.setRoyaltyFreeze("true");
extendParams.setRoyaltyFreeze(Boolean.TRUE.toString());
model.setExtendParams(extendParams);
}
// 过期时间
model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime()));
model.setTotalAmount(amount);
AlipayTradePayRequest request = new AlipayTradePayRequest();
request.setBizModel(model);
request.setNotifyUrl(alipayConfig.getNotifyUrl());
try {
AlipayTradePayResponse response = AliPayApi.tradePayToResponse(model, alipayConfig.getNotifyUrl());
AlipayTradePayResponse response = alipayClient.execute(request);
// 支付成功处理 金额2000以下免密支付, 记录支付完成相关信息
if (Objects.equals(response.getCode(), AliPayCode.SUCCESS)) {
Date gmtPayment = response.getGmtPayment();

View File

@@ -11,8 +11,6 @@ import cn.daxpay.single.service.dto.extra.OpenIdResult;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import lombok.RequiredArgsConstructor;
@@ -93,7 +91,7 @@ public class AliPayAuthService {
@SneakyThrows
public String getOpenId(String authCode) {
// 初始化SDK
AlipayClient alipayClient = new DefaultAlipayClient(this.getAlipayConfig());
AlipayClient alipayClient = aliPayConfigService.getAlipayClient();
// 构造请求参数以调用接口
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
// 设置授权码
@@ -105,26 +103,6 @@ public class AliPayAuthService {
log.warn("获取支付宝OpenId失败,原因:{}", response.getSubMsg());
throw new BizException("获取支付宝OpenId失败");
}
return response.getOpenId();
}
/**
* 获取支付宝SDK的配置
*/
private AlipayConfig getAlipayConfig(){
AliPayConfig aliPayConfig = aliPayConfigService.getConfig();
String privateKey = aliPayConfig.getPrivateKey();
String alipayPublicKey =aliPayConfig.getAlipayPublicKey();
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl(aliPayConfig.getServerUrl());
alipayConfig.setAppId(aliPayConfig.getAppId());
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(alipayPublicKey);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType(aliPayConfig.getSignType());
return alipayConfig;
}
}