转账
This commit is contained in:
parent
92be2b3e53
commit
6421f31853
|
@ -74,44 +74,50 @@ public class AliAuthService {
|
|||
return json.getString("mobile");
|
||||
}
|
||||
|
||||
|
||||
private void checkSign(String content, String sign) {
|
||||
//编码格式
|
||||
String charset="utf-8";
|
||||
//支付宝公钥
|
||||
String alipayPublicCertPath= aliConfig.getAlipayCertPath();
|
||||
//签名方式
|
||||
String sign_type="RSA2";
|
||||
//验签方法
|
||||
try {
|
||||
boolean signVerified= AlipaySignature.rsaCertCheck(content, sign, alipayPublicCertPath, charset, sign_type);
|
||||
ServiceUtil.assertion(!signVerified, "验签未通过");
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
* @param response 前端响应(密文)
|
||||
*/
|
||||
private String decrypt(String response) {
|
||||
|
||||
//1. 获取验签和解密所需要的参数
|
||||
Map<String, String> openapiResult = JSON.parseObject(response,new TypeReference<Map<String, String>>() {}, Feature.OrderedField);
|
||||
|
||||
String signType = "RSA2";
|
||||
String charset = "UTF-8";
|
||||
String encryptType = "AES";
|
||||
String sign = openapiResult.get("sign");
|
||||
String content = openapiResult.get("response");
|
||||
//判断是否为加密内容
|
||||
boolean isDataEncrypted = !content.startsWith("{");
|
||||
boolean signCheckPass = false;
|
||||
|
||||
//2. 验签
|
||||
String signContent = content;
|
||||
// 你的小程序对应的支付宝公钥(为扩展考虑建议用appId+signType做密钥存储隔离)
|
||||
String signVeriKey = aliConfig.getAlipayPublicKey();
|
||||
// 你的小程序对应的加解密密钥(为扩展考虑建议用appId+encryptType做密钥存储隔离)
|
||||
String decryptKey = aliConfig.getAesPrivateKey();//如果是加密的报文则需要在密文的前后添加双引号
|
||||
if (isDataEncrypted) {
|
||||
signContent = "\"" + signContent + "\"";
|
||||
} try {
|
||||
signCheckPass = AlipaySignature.rsaCheck(signContent, sign, signVeriKey, charset, signType);
|
||||
} catch (AlipayApiException e) {
|
||||
// 验签异常, 日志
|
||||
} if (!signCheckPass) {
|
||||
//验签不通过(异常或者报文被篡改),终止流程(不需要做解密)
|
||||
throw new ServiceException("验签失败");
|
||||
}
|
||||
this.checkSign(signContent, sign);
|
||||
|
||||
//3. 解密
|
||||
String encryptType = "AES";
|
||||
String plainData = null;
|
||||
if (isDataEncrypted) {
|
||||
try {
|
||||
plainData = AlipayEncrypt.decryptContent(content, encryptType, decryptKey, charset);
|
||||
plainData = AlipayEncrypt.decryptContent(content, encryptType, aliConfig.getAesPrivateKey(), charset);
|
||||
} catch (AlipayApiException e) {
|
||||
//解密异常, 记录日志
|
||||
throw new ServiceException("解密异常:" + e.getMessage());
|
||||
|
|
|
@ -25,13 +25,13 @@ public class AliConfig {
|
|||
@Value("${ali.privateKey}")
|
||||
private String privateKey;
|
||||
|
||||
// 应用公钥
|
||||
@Value("${ali.publicKey}")
|
||||
private String publicKey;
|
||||
|
||||
// 支付宝公钥
|
||||
@Value("${ali.alipayPublicKey}")
|
||||
private String alipayPublicKey;
|
||||
// // 应用公钥
|
||||
// @Value("${ali.publicKey}")
|
||||
// private String publicKey;
|
||||
//
|
||||
// // 支付宝公钥
|
||||
// @Value("${ali.alipayPublicKey}")
|
||||
// private String alipayPublicKey;
|
||||
|
||||
@Value("${ali.aesPrivateKey}")
|
||||
private String aesPrivateKey;
|
||||
|
@ -39,20 +39,53 @@ public class AliConfig {
|
|||
@Value("${ali.notifyUrl}")
|
||||
private String notifyUrl;
|
||||
|
||||
private AlipayConfig getAlipayConfig() {
|
||||
AlipayConfig alipayConfig = new AlipayConfig();
|
||||
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
|
||||
alipayConfig.setAppId(appId);
|
||||
alipayConfig.setPrivateKey(privateKey);
|
||||
alipayConfig.setAlipayPublicKey(alipayPublicKey);
|
||||
alipayConfig.setFormat("json");
|
||||
alipayConfig.setCharset("UTF-8");
|
||||
alipayConfig.setSignType("RSA2");
|
||||
return alipayConfig;
|
||||
}
|
||||
@Value("${ali.transferNotifyUrl}")
|
||||
private String transferNotifyUrl;
|
||||
|
||||
@Value("${ali.appCertPath}")
|
||||
private String appCertPath;
|
||||
|
||||
@Value("${ali.alipayCertPath}")
|
||||
private String alipayCertPath;
|
||||
|
||||
@Value("${ali.alipayRootCertPath}")
|
||||
private String alipayRootCertPath;
|
||||
|
||||
// private AlipayConfig getAlipayConfig() {
|
||||
// AlipayConfig alipayConfig = new AlipayConfig();
|
||||
// alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
|
||||
// alipayConfig.setAppId(appId);
|
||||
// alipayConfig.setPrivateKey(privateKey);
|
||||
// alipayConfig.setAlipayPublicKey(alipayPublicKey);
|
||||
// alipayConfig.setFormat("json");
|
||||
// alipayConfig.setCharset("UTF-8");
|
||||
// alipayConfig.setSignType("RSA2");
|
||||
// return alipayConfig;
|
||||
// }
|
||||
|
||||
// 证书模式
|
||||
@Bean
|
||||
public AlipayClient alipayClient() throws AlipayApiException {
|
||||
return new DefaultAlipayClient(getAlipayConfig());
|
||||
AlipayConfig alipayConfig = new AlipayConfig();
|
||||
//设置网关地址
|
||||
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
|
||||
//设置应用APPID
|
||||
alipayConfig.setAppId(this.getAppId());
|
||||
//设置应用私钥
|
||||
alipayConfig.setPrivateKey(this.getPrivateKey());
|
||||
//设置应用公钥证书路径
|
||||
alipayConfig.setAppCertPath(this.getAppCertPath());
|
||||
//设置支付宝公钥证书路径
|
||||
alipayConfig.setAlipayPublicCertPath(this.getAlipayCertPath());
|
||||
//设置支付宝根证书路径
|
||||
alipayConfig.setRootCertPath(this.alipayRootCertPath);
|
||||
//设置请求格式,固定值json
|
||||
alipayConfig.setFormat("json");
|
||||
//设置字符集
|
||||
alipayConfig.setCharset("UTF-8");
|
||||
//设置签名类型
|
||||
alipayConfig.setSignType("RSA2");
|
||||
|
||||
return new DefaultAlipayClient(alipayConfig);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package com.ruoyi.common.pay;
|
||||
|
||||
import com.alipay.api.domain.MultiStepTransOrderDetailRequest;
|
||||
import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 可批量转账的接口
|
||||
* @author wjh
|
||||
* 2024/8/9
|
||||
*/
|
||||
public interface BatchTransferAble {
|
||||
|
||||
/**
|
||||
* 转账总金额(分)
|
||||
*/
|
||||
Long transferTotalFen();
|
||||
|
||||
/**
|
||||
* 转账总金额(元)
|
||||
* @return
|
||||
*/
|
||||
default BigDecimal transferTotalYuan() {
|
||||
return BigDecimal.valueOf(transferTotalFen()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账外部订单号
|
||||
*/
|
||||
String transferOutBatchNo();
|
||||
|
||||
/**
|
||||
* 转账名称
|
||||
*/
|
||||
String transferBatchName();
|
||||
|
||||
/**
|
||||
* 转账备注
|
||||
*/
|
||||
String transferBatchRemark();
|
||||
|
||||
|
||||
/**
|
||||
* 微信转账明细
|
||||
*/
|
||||
List<TransferDetailInput> wxTransferDetailList();
|
||||
|
||||
/**
|
||||
* 支付宝转账明细
|
||||
*/
|
||||
List<MultiStepTransOrderDetailRequest> aliTransferDetailList();
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.ruoyi.common.pay;
|
||||
|
||||
/**
|
||||
* 转账API
|
||||
* @author wjh
|
||||
* 2024/12/11
|
||||
*/
|
||||
public interface TransferApi {
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.ruoyi.common.pay.ali.enums;
|
||||
|
||||
import com.ruoyi.common.utils.collection.CollectionUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/12/11
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AliTransferStatus {
|
||||
|
||||
SUCCESS("SUCCESS", "成功"),
|
||||
FAIL("FAIL", "失败"),
|
||||
DEALING("DEALING", "处理中"),
|
||||
REFUND("REFUND", "已退票");
|
||||
|
||||
private final String status;
|
||||
private final String msg;
|
||||
|
||||
// 成功的列表
|
||||
public static List<String> successList() {
|
||||
return CollectionUtils.map(AliTransferStatus::getStatus, SUCCESS);
|
||||
}
|
||||
|
||||
// 失败的列表
|
||||
public static List<String> failList() {
|
||||
return CollectionUtils.map(AliTransferStatus::getStatus, FAIL, REFUND);
|
||||
}
|
||||
|
||||
}
|
|
@ -61,7 +61,7 @@ public class AliPayService implements PayApi {
|
|||
request.setNotifyUrl(aliConfig.getNotifyUrl());
|
||||
|
||||
try {
|
||||
AlipayTradeCreateResponse response = alipayClient.execute(request);
|
||||
AlipayTradeCreateResponse response = alipayClient.certificateExecute(request);
|
||||
ServiceUtil.assertion(!response.isSuccess(), response.getMsg());
|
||||
return response.getTradeNo();
|
||||
} catch (Exception e) {
|
||||
|
@ -78,7 +78,7 @@ public class AliPayService implements PayApi {
|
|||
bizContent.put("out_trade_no", outTradeNo);
|
||||
request.setBizContent(bizContent.toString());
|
||||
try {
|
||||
AlipayTradeCloseResponse response = alipayClient.execute(request);
|
||||
AlipayTradeCloseResponse response = alipayClient.certificateExecute(request);
|
||||
ServiceUtil.assertion(!response.isSuccess(), response.getMsg());
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("调用支付宝关闭订单失败:" + e.getMessage());
|
||||
|
@ -96,7 +96,7 @@ public class AliPayService implements PayApi {
|
|||
request.setBizModel(model);
|
||||
|
||||
try {
|
||||
AlipayTradeQueryResponse response = alipayClient.execute(request);
|
||||
AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);
|
||||
ServiceUtil.assertion(!response.isSuccess(), response.getMsg());
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
|
@ -126,7 +126,7 @@ public class AliPayService implements PayApi {
|
|||
request.setBizModel(model);
|
||||
|
||||
try {
|
||||
AlipayTradeRefundResponse response = alipayClient.execute(request);
|
||||
AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
|
||||
ServiceUtil.assertion(!response.isSuccess(), response.getMsg());
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
package com.ruoyi.common.pay.ali.service;
|
||||
|
||||
import com.alipay.api.AlipayClient;
|
||||
import com.alipay.api.domain.*;
|
||||
import com.alipay.api.request.AlipayFundTransCommonQueryRequest;
|
||||
import com.alipay.api.request.AlipayFundTransMultistepTransferRequest;
|
||||
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
|
||||
import com.alipay.api.response.AlipayFundTransCommonQueryResponse;
|
||||
import com.alipay.api.response.AlipayFundTransMultistepTransferResponse;
|
||||
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
|
||||
import com.ruoyi.common.auth.ali.AliConfig;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.pay.BatchTransferAble;
|
||||
import com.ruoyi.common.utils.ServiceUtil;
|
||||
import com.wechat.pay.java.service.transferbatch.model.TransferBatchEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支付宝转账API
|
||||
* @author wjh
|
||||
* 2024/12/11
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AliTransferService {
|
||||
|
||||
@Autowired
|
||||
private AliConfig aliConfig;
|
||||
|
||||
@Autowired
|
||||
private AlipayClient alipayClient;
|
||||
|
||||
/**
|
||||
* 多笔转账
|
||||
*/
|
||||
public boolean batchTransfer(BatchTransferAble batchTransferAble) {
|
||||
|
||||
// 构造请求参数以调用接口
|
||||
AlipayFundTransMultistepTransferRequest request = new AlipayFundTransMultistepTransferRequest();
|
||||
AlipayFundTransMultistepTransferModel model = new AlipayFundTransMultistepTransferModel();
|
||||
|
||||
// 设置外部单号
|
||||
model.setOutBizNo(batchTransferAble.transferOutBatchNo());
|
||||
|
||||
// 设置产品码:BATCH_API_NO_PWD 批量无密
|
||||
model.setProductCode("BATCH_API_NO_PWD");
|
||||
|
||||
// 设置场景码:MULTI_STEP_TRANSFER 多步转账
|
||||
model.setBizScene("MULTI_STEP_TRANSFER");
|
||||
|
||||
// 设置总金额(元)
|
||||
model.setTotalAmount(batchTransferAble.transferTotalYuan().toString());
|
||||
|
||||
// 设置总数量
|
||||
List<MultiStepTransOrderDetailRequest> detailList = batchTransferAble.aliTransferDetailList();
|
||||
model.setTotalCount(String.valueOf(detailList.size()));
|
||||
|
||||
// 设置备注
|
||||
model.setRemark(batchTransferAble.transferBatchRemark());
|
||||
|
||||
// 设置多步转账明细
|
||||
model.setOrderDetails(detailList);
|
||||
|
||||
// TODO 批量设置转账人(官方)
|
||||
MultiStepTransferParticipant payerInfo = new MultiStepTransferParticipant();
|
||||
payerInfo.setIdentity("chuangtewulian@sina.com");
|
||||
payerInfo.setName("福鼎创特物联科技有限公司");
|
||||
payerInfo.setIdentityType("ALIPAY_USER_ID");
|
||||
for (MultiStepTransOrderDetailRequest detail : detailList) {
|
||||
detail.setPayerInfo(payerInfo);
|
||||
}
|
||||
|
||||
request.setBizModel(model);
|
||||
request.setNotifyUrl(aliConfig.getTransferNotifyUrl());
|
||||
|
||||
try {
|
||||
AlipayFundTransMultistepTransferResponse response = alipayClient.certificateExecute(request);
|
||||
log.info("转账结果:{}", response.getBody());
|
||||
ServiceUtil.assertion(!response.isSuccess(), response.getMsg());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("批量转账到支付宝账户失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean transfer(BatchTransferAble batchTransferAble) {
|
||||
|
||||
// 构造请求参数以调用接口
|
||||
AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
|
||||
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
|
||||
|
||||
List<MultiStepTransOrderDetailRequest> detailList = batchTransferAble.aliTransferDetailList();
|
||||
ServiceUtil.assertion(detailList.size() > 1, "当前接口仅适用于单笔转账");
|
||||
MultiStepTransOrderDetailRequest detail = detailList.get(0);
|
||||
|
||||
// 设置商家侧唯一订单号
|
||||
model.setOutBizNo(detail.getOutBizNo());
|
||||
|
||||
// 设置订单总金额
|
||||
model.setTransAmount(detail.getTransAmount());
|
||||
|
||||
// 设置描述特定的业务场景
|
||||
model.setBizScene("DIRECT_TRANSFER");
|
||||
|
||||
// 设置业务产品码
|
||||
model.setProductCode("TRANS_ACCOUNT_NO_PWD");
|
||||
|
||||
// 设置转账业务的标题
|
||||
model.setOrderTitle(detail.getOrderTitle());
|
||||
|
||||
// 设置收款方信息
|
||||
Participant payeeInfo = new Participant();
|
||||
payeeInfo.setIdentity(detail.getPayeeInfo().getIdentity());
|
||||
payeeInfo.setName(detail.getPayeeInfo().getName());
|
||||
payeeInfo.setIdentityType(detail.getPayeeInfo().getIdentityType());
|
||||
model.setPayeeInfo(payeeInfo);
|
||||
|
||||
// 设置业务备注
|
||||
model.setRemark(detail.getRemark());
|
||||
|
||||
request.setBizModel(model);
|
||||
request.setNotifyUrl(aliConfig.getTransferNotifyUrl());
|
||||
|
||||
try {
|
||||
AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
|
||||
ServiceUtil.assertion(!response.isSuccess(), response.getMsg());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("转账到支付宝账户失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public AlipayFundTransCommonQueryResponse getTransferBatchByOutNo(String outTradeNo) {
|
||||
// 构造请求参数以调用接口
|
||||
AlipayFundTransCommonQueryRequest request = new AlipayFundTransCommonQueryRequest();
|
||||
AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel();
|
||||
|
||||
// 设置销售产品码
|
||||
model.setProductCode("TRANS_ACCOUNT_NO_PWD");
|
||||
|
||||
// 设置描述特定的业务场景
|
||||
model.setBizScene("DIRECT_TRANSFER");
|
||||
|
||||
// 设置商户转账唯一订单号
|
||||
model.setOutBizNo(outTradeNo);
|
||||
|
||||
request.setBizModel(model);
|
||||
|
||||
try {
|
||||
AlipayFundTransCommonQueryResponse response = alipayClient.certificateExecute(request);
|
||||
ServiceUtil.assertion(!response.isSuccess(), response.getMsg());
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("查询支付宝转账单{}失败:{}", outTradeNo, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package com.ruoyi.common.pay.wx.domain;
|
||||
|
||||
import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 可批量转账的接口
|
||||
* @author wjh
|
||||
* 2024/8/9
|
||||
*/
|
||||
public interface BatchTransferAble {
|
||||
|
||||
/**
|
||||
* 转账总金额
|
||||
*/
|
||||
Long transferTotalAmount();
|
||||
|
||||
/**
|
||||
* 转账外部订单号
|
||||
*/
|
||||
String transferOutBatchNo();
|
||||
|
||||
/**
|
||||
* 转账名称
|
||||
*/
|
||||
String transferBatchName();
|
||||
|
||||
/**
|
||||
* 转账备注
|
||||
*/
|
||||
String transferBatchRemark();
|
||||
|
||||
|
||||
/**
|
||||
* 转账明细
|
||||
*/
|
||||
List<TransferDetailInput> transferDetailList();
|
||||
}
|
|
@ -1,14 +1,18 @@
|
|||
package com.ruoyi.common.pay.wx.service;
|
||||
|
||||
import com.alipay.api.domain.MultiStepTransferParticipant;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.pay.TransferApi;
|
||||
import com.ruoyi.common.pay.wx.config.WxTransferConfig;
|
||||
import com.ruoyi.common.pay.wx.domain.BatchTransferAble;
|
||||
import com.ruoyi.common.pay.BatchTransferAble;
|
||||
import com.ruoyi.common.pay.wx.domain.request.MyInitiateBatchTransferRequest;
|
||||
import com.wechat.pay.java.service.transferbatch.TransferBatchService;
|
||||
import com.wechat.pay.java.service.transferbatch.model.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/12
|
||||
|
@ -26,14 +30,15 @@ public class WxTransferService {
|
|||
* 转账到零钱
|
||||
*/
|
||||
public InitiateBatchTransferResponse batchTransfer(BatchTransferAble batchTransferAble) {
|
||||
List<TransferDetailInput> detailList = batchTransferAble.wxTransferDetailList();
|
||||
MyInitiateBatchTransferRequest request = new MyInitiateBatchTransferRequest();
|
||||
request.setAppid(config.getAppId());
|
||||
request.setOutBatchNo(batchTransferAble.transferOutBatchNo());
|
||||
request.setBatchName(batchTransferAble.transferBatchName());
|
||||
request.setBatchRemark(batchTransferAble.transferBatchRemark());
|
||||
request.setTotalAmount(batchTransferAble.transferTotalAmount());
|
||||
request.setTotalNum(batchTransferAble.transferDetailList().size());
|
||||
request.setTransferDetailList(batchTransferAble.transferDetailList());
|
||||
request.setTotalAmount(batchTransferAble.transferTotalFen());
|
||||
request.setTotalNum(detailList.size());
|
||||
request.setTransferDetailList(detailList);
|
||||
request.setNotifyUrl(config.getTransferNotifyUrl());
|
||||
try {
|
||||
return transferBatchService.initiateBatchTransfer(request);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.ruoyi.ss.transfer.domain;
|
||||
|
||||
import com.ruoyi.common.pay.wx.domain.BatchTransferAble;
|
||||
import com.alipay.api.domain.MultiStepTransOrderDetailRequest;
|
||||
import com.alipay.api.domain.MultiStepTransferParticipant;
|
||||
import com.ruoyi.common.pay.BatchTransferAble;
|
||||
import com.ruoyi.common.utils.collection.CollectionUtils;
|
||||
import com.ruoyi.ss.transferDetail.domain.TransferDetailVO;
|
||||
import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
|
||||
|
@ -26,7 +28,7 @@ public class TransferVO extends Transfer implements BatchTransferAble {
|
|||
* 转账总金额
|
||||
*/
|
||||
@Override
|
||||
public Long transferTotalAmount() {
|
||||
public Long transferTotalFen() {
|
||||
return new BigDecimal(100).multiply(this.getTotalAmount()).longValue();
|
||||
}
|
||||
|
||||
|
@ -58,10 +60,43 @@ public class TransferVO extends Transfer implements BatchTransferAble {
|
|||
* 转账明细
|
||||
*/
|
||||
@Override
|
||||
public List<TransferDetailInput> transferDetailList() {
|
||||
public List<TransferDetailInput> wxTransferDetailList() {
|
||||
return this.toTransferDetailInput(this.getDetailList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝转账明细
|
||||
*/
|
||||
@Override
|
||||
public List<MultiStepTransOrderDetailRequest> aliTransferDetailList() {
|
||||
if (CollectionUtils.isEmptyElement(detailList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<MultiStepTransOrderDetailRequest> orderDetails = new ArrayList<MultiStepTransOrderDetailRequest>();
|
||||
|
||||
int seq = 1;
|
||||
for (TransferDetailVO detail : detailList) {
|
||||
MultiStepTransOrderDetailRequest orderDetail = new MultiStepTransOrderDetailRequest();
|
||||
orderDetail.setOrderSeq(String.valueOf(seq));
|
||||
orderDetail.setOrderTitle("转账到支付宝");
|
||||
// orderDetail.setBusinessParams("withdraw_timeliness=T0");
|
||||
orderDetail.setRemark(detail.getRemark());
|
||||
orderDetail.setOutBizNo(detail.getDetailNo());
|
||||
orderDetail.setTransAmount(detail.getAmount().toString());
|
||||
MultiStepTransferParticipant payeeInfo = new MultiStepTransferParticipant();
|
||||
payeeInfo.setIdentity(detail.getAccountNo());
|
||||
payeeInfo.setName(detail.getUserName());
|
||||
payeeInfo.setIdentityType("ALIPAY_OPEN_ID");
|
||||
orderDetail.setPayeeInfo(payeeInfo);
|
||||
orderDetails.add(orderDetail);
|
||||
seq ++;
|
||||
}
|
||||
|
||||
|
||||
return orderDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转为明细
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package com.ruoyi.ss.transfer.service.impl;
|
||||
|
||||
import com.alipay.api.response.AlipayFundTransCommonQueryResponse;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.pay.ali.enums.AliTransferStatus;
|
||||
import com.ruoyi.common.pay.ali.service.AliTransferService;
|
||||
import com.ruoyi.common.pay.wx.domain.enums.WxTransferBatchStatus;
|
||||
import com.ruoyi.common.pay.wx.domain.enums.WxTransferDetailStatus;
|
||||
import com.ruoyi.common.pay.wx.service.WxPayService;
|
||||
|
@ -32,6 +35,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -65,6 +69,9 @@ public class TransferServiceImpl implements TransferService
|
|||
@Autowired
|
||||
private WxTransferService wxTransferService;
|
||||
|
||||
@Autowired
|
||||
private AliTransferService aliTransferService;
|
||||
|
||||
/**
|
||||
* 查询转账
|
||||
*
|
||||
|
@ -197,6 +204,8 @@ public class TransferServiceImpl implements TransferService
|
|||
// 发起转账
|
||||
if (AccountType.WECHAT.getType().equals(transfer.getAccountType())) {
|
||||
wxTransferService.batchTransfer(transfer);
|
||||
} else if (AccountType.ALIPAY.getType().equals(transfer.getAccountType())) {
|
||||
aliTransferService.transfer(transfer);
|
||||
} else {
|
||||
throw new ServiceException("暂不支持该方式进行线上转账");
|
||||
}
|
||||
|
@ -225,11 +234,95 @@ public class TransferServiceImpl implements TransferService
|
|||
// 微信
|
||||
if (AccountType.WECHAT.getType().equals(transfer.getAccountType())) {
|
||||
return this.refreshTransferStatusWx(transfer);
|
||||
} else if (AccountType.ALIPAY.getType().equals(transfer.getAccountType())) {
|
||||
return this.refreshTransferStatusAli(transfer);
|
||||
} else {
|
||||
throw new ServiceException("该付款方式不支持刷新操作");
|
||||
}
|
||||
}
|
||||
|
||||
private int refreshTransferStatusAli(TransferVO transfer) {
|
||||
if (transfer == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 待更新的数据
|
||||
Transfer data = new Transfer();
|
||||
List<TransferDetail> detaiList = new ArrayList<>();
|
||||
|
||||
int success = 0;
|
||||
for (TransferDetailVO detail : transfer.getDetailList()) {
|
||||
AlipayFundTransCommonQueryResponse res = aliTransferService.getTransferBatchByOutNo(detail.getDetailNo());
|
||||
|
||||
TransferDetail updateDetail = new TransferDetail();
|
||||
updateDetail.setDetailId(detail.getDetailId());
|
||||
|
||||
// 成功的情况
|
||||
if (res != null && AliTransferStatus.successList().contains(res.getStatus())) {
|
||||
updateDetail.setStatus(TransferDetailStatus.TRANSFER_SUCCESS.getStatus());
|
||||
detaiList.add(updateDetail);
|
||||
success ++;
|
||||
}
|
||||
// 失败的情况
|
||||
else if (res == null || AliTransferStatus.failList().contains(res.getStatus())){
|
||||
updateDetail.setStatus(TransferDetailStatus.TRANSFER_FAIL.getStatus());
|
||||
if (res != null) {
|
||||
updateDetail.setStatus(res.getFailReason());
|
||||
} else {
|
||||
updateDetail.setStatus("未知错误,返回值为空");
|
||||
}
|
||||
detaiList.add(updateDetail);
|
||||
}
|
||||
// 其余情况不处理
|
||||
}
|
||||
|
||||
data.setUpdateTime(DateUtils.getNowDate());
|
||||
// 全部成功
|
||||
if (success == transfer.getDetailList().size()) {
|
||||
data.setStatus(TransferStatus.TRANSFER_SUCCESS.getStatus());
|
||||
}
|
||||
// 全部失败
|
||||
else if (success == 0) {
|
||||
data.setStatus(TransferStatus.TRANSFER_FAIL.getStatus());
|
||||
}
|
||||
// 部分成功
|
||||
else {
|
||||
data.setStatus(TransferStatus.TRANSFER_PART_SUCCESS.getStatus());
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
return this.saveByRefresh(transfer.getBatchId(), data, detaiList);
|
||||
}
|
||||
|
||||
private void operatorBiz(Long batchId) {
|
||||
// 查询最新的转账信息
|
||||
TransferVO dbTransfer = selectTransferByBatchId(batchId);
|
||||
transferAssembler.assembleDetail(Collections.singletonList(dbTransfer));
|
||||
|
||||
TransferBstType bstType = TransferBstType.parse(dbTransfer.getBstType());
|
||||
ServiceUtil.assertion(bstType == null, "业务类型不存在");
|
||||
if (bstType.getAfterTransfer() != null) {
|
||||
// 业务处理器
|
||||
AfterTransfer afterTransfer = SpringUtils.getBean(bstType.getAfterTransfer());
|
||||
|
||||
// 业务返回值
|
||||
int bstResult = 0;
|
||||
// 成功
|
||||
if (TransferStatus.TRANSFER_SUCCESS.getStatus().equals(dbTransfer.getStatus())) {
|
||||
bstResult = afterTransfer.onTransferSuccess(dbTransfer);
|
||||
}
|
||||
// 部分成功
|
||||
else if (TransferStatus.TRANSFER_PART_SUCCESS.getStatus().equals(dbTransfer.getStatus())) {
|
||||
bstResult = afterTransfer.onTransferPartSuccess(dbTransfer);
|
||||
}
|
||||
// 失败
|
||||
else if (TransferStatus.TRANSFER_FAIL.getStatus().equals(dbTransfer.getStatus())) {
|
||||
bstResult = afterTransfer.onTransferFail(dbTransfer);
|
||||
}
|
||||
ServiceUtil.assertion(bstResult == 0, "业务执行失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int refreshTransferStatus(Long batchId) {
|
||||
TransferVO transfer = selectTransferByBatchId(batchId);
|
||||
|
@ -294,11 +387,16 @@ public class TransferServiceImpl implements TransferService
|
|||
}
|
||||
|
||||
// 保存到数据库
|
||||
return this.saveByRefresh(transfer.getBatchId(), data, detaiList);
|
||||
|
||||
}
|
||||
|
||||
private int saveByRefresh(Long batchId, Transfer data, List<TransferDetail> detaiList) {
|
||||
Integer result = transactionTemplate.execute(status -> {
|
||||
// 修改主表信息
|
||||
TransferQuery query = new TransferQuery();
|
||||
query.setStatus(TransferStatus.TRANSFER_ING.getStatus());
|
||||
query.setBatchId(transfer.getBatchId());
|
||||
query.setBatchId(batchId);
|
||||
int update = this.updateByQuery(data, query);
|
||||
ServiceUtil.assertion(update != 1, "修改转账批次失败,状态已发生变化");
|
||||
|
||||
|
@ -311,33 +409,8 @@ public class TransferServiceImpl implements TransferService
|
|||
ServiceUtil.assertion(detailUpdate != 1, "转账明细修改失败,状态已发生变化");
|
||||
}
|
||||
|
||||
// 修改业务信息
|
||||
TransferBstType bstType = TransferBstType.parse(transfer.getBstType());
|
||||
ServiceUtil.assertion(bstType == null, "业务类型不存在");
|
||||
if (bstType.getAfterTransfer() != null) {
|
||||
// 业务处理器
|
||||
AfterTransfer afterTransfer = SpringUtils.getBean(bstType.getAfterTransfer());
|
||||
|
||||
// 查询最新的转账信息
|
||||
TransferVO dbTransfer = selectTransferByBatchId(transfer.getBatchId());
|
||||
transferAssembler.assembleDetail(Collections.singletonList(dbTransfer));
|
||||
|
||||
// 业务返回值
|
||||
int bstResult = 0;
|
||||
// 成功
|
||||
if (TransferStatus.TRANSFER_SUCCESS.getStatus().equals(data.getStatus())) {
|
||||
bstResult = afterTransfer.onTransferSuccess(dbTransfer);
|
||||
}
|
||||
// 部分成功
|
||||
else if (TransferStatus.TRANSFER_PART_SUCCESS.getStatus().equals(data.getStatus())) {
|
||||
bstResult = afterTransfer.onTransferPartSuccess(dbTransfer);
|
||||
}
|
||||
// 失败
|
||||
else if (TransferStatus.TRANSFER_FAIL.getStatus().equals(data.getStatus())) {
|
||||
bstResult = afterTransfer.onTransferFail(dbTransfer);
|
||||
}
|
||||
ServiceUtil.assertion(bstResult == 0, "业务执行失败");
|
||||
}
|
||||
// 操作业务信息
|
||||
this.operatorBiz(batchId);
|
||||
|
||||
return update;
|
||||
});
|
||||
|
|
|
@ -230,4 +230,38 @@ public class AppPayController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
@ApiOperation("支付宝支付通知")
|
||||
@PostMapping("/notify/ali")
|
||||
@Anonymous
|
||||
public ResponseEntity<Boolean> aliPayNotify(HttpServletRequest request) {
|
||||
try {
|
||||
log.info("收到支付宝支付通知{}", request);
|
||||
String body = HttpUtils.getBody(request);
|
||||
log.info("收到支付宝支付通知{}", body);
|
||||
// todo
|
||||
} catch (ValidationException e) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
return ResponseEntity.status(HttpStatus.OK).body(null);
|
||||
}
|
||||
|
||||
@ApiOperation("支付宝转账通知")
|
||||
@PostMapping("/notify/ali/transfer")
|
||||
@Anonymous
|
||||
public ResponseEntity<Boolean> aliPayNotifyTransfer(HttpServletRequest request) {
|
||||
try {
|
||||
log.info("收到支付宝转账通知{}", request);
|
||||
String body = HttpUtils.getBody(request);
|
||||
log.info("收到支付宝转账通知{}", body);
|
||||
// todo
|
||||
} catch (ValidationException e) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
return ResponseEntity.status(HttpStatus.OK).body(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -141,12 +141,16 @@ ali:
|
|||
# 应用ID
|
||||
appId: 2021004193649611
|
||||
# 应用私钥
|
||||
privateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCLmoyeJgMCIh5xeYOzg1mnRTTPplkBTJAeXozAV/dTCu6vaKNPPRXjDwYILFzpYGAVhe9NNw6mcVq9WU4WEh4k05unDQIFNg0gXFQ9RNmcrV7uokVYAbTpPzmJHHF0oNXddsj9J37fFymP9GJCVuVGEkTHGP2DA6Odgq0xuHPiqQeyDzSldzpSwiRiYW71U534aJGz1MZQx3aI8KlANr2Z0c4WPdmYKmd0x137zHFU5yclsginrZL2tE34nBS5OJHqZQ/WLZIKhv8nGSvcILHhxktU6ggNhhGyf2OdlO9dr0z1exIZPrTMtAUQTEh/X/KqV8DgwNMFtNtT2LC47F+pAgMBAAECggEAAoSRELEi0MEIx4cnhu9RiKDI6Q3ZARr+Zm3SIA32GftSfrtmZqF1aZj1xOP38QWZ9glqXXwmuX3F4zBfJirBfGyMnCCx7qIg7np70ncRba/6zFcE5Sdyudo4EW7/5NiZwtrHmTlDIobqavw/YW7rx63Aq86Zk+lW5BpdQU5QWMAot4aFEPq91eo10a7EVigZKs9vkxKuW7OX/mI/BixkK9YBuq1xS6lefKjQfPPMPCRis3QQtkJWOw2myKXn7qcmCsecQwc3XdrV+6iFpYLOR2V4V3ALVFrDuGFb/2PBThWTiijPAypxQdb/Onu86Z3ObWDXYnPNspBODVxCWBWM2QKBgQDqJ31c37ZXUIfavFMBKp86evF9J+6cjGUOoU4iOd7NWW5QkLvNGAjw138ZQo7OKZ26LtzM2+4bbRVgNjdkVmj4ebdF0kijs7ruF+UhFneodFbwGCBXkMc3yLDLlYjZdeI9B/npGrwFuZAnmM1z+La6z0TlZoQnWe+WED5EUiKbJwKBgQCYoNOOPjb2ysXS/CEM/wX4TUDZ9Ykn85wVLOOhW17LYiMLBJq+uZj8BdN/rzdQ4YO4XqBaDA/t7GhiphaYAfsyy7f1oGEp4jtsyHz21uOPOz4ITnbJ9SUPz5VVmFgsCBjyh6KxckiMXEovcoV1Xqd535BPSQg5q1Y/RbOcaIswrwKBgBtqHjJWeunEIvPIIsu7KsNVC5sEptorUdWhqx00u1I9iz3hhCtiCgHwqQ/TDBc1JiNbQzy07y7E2cDW+CtGNqoIzh1dnmWUMGmZ4Ji8IaxWWqtnl7nI2Jo+Y/yh+FDFjYRpv6e8GpFtBWStbjiKwRIkHEPjecuFqxhdtHyZRTX3AoGAYbogm6SUdwMxFb4gv3yPawS0MJs6Hh2q5BghDJE/qkSFIanqF5MpNL3aRZiAd8ZeG/BjBiVREcvcrsWgE+a43DZ67MirTjEwUaAx+69ud6i8OH9dKkVQXMZS3UK1ukPZDXnxn2MItu7lBWpzr8pSvAN9GHcv0BU4HT1ZGx4JebsCgYEAjIbfv7CwfTwyRbevwVscmjEnvH1r336rU3GfC1C8tvPHVdjzVOEezRHwliT/uPLcUWmTLVtwnEGCcwqoz8PUpgvWeriHXlEqBX3pPixYa2kMLm+5se4qDO32QG1EQXeLPs5UWgqfItgqNEsdeFdsE27LEIqjmRzHoPTEKaylUVs=
|
||||
# 应用公钥
|
||||
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi5qMniYDAiIecXmDs4NZp0U0z6ZZAUyQHl6MwFf3Uwrur2ijTz0V4w8GCCxc6WBgFYXvTTcOpnFavVlOFhIeJNObpw0CBTYNIFxUPUTZnK1e7qJFWAG06T85iRxxdKDV3XbI/Sd+3xcpj/RiQlblRhJExxj9gwOjnYKtMbhz4qkHsg80pXc6UsIkYmFu9VOd+GiRs9TGUMd2iPCpQDa9mdHOFj3ZmCpndMdd+8xxVOcnJbIIp62S9rRN+JwUuTiR6mUP1i2SCob/Jxkr3CCx4cZLVOoIDYYRsn9jnZTvXa9M9XsSGT60zLQFEExIf1/yqlfA4MDTBbTbU9iwuOxfqQIDAQAB
|
||||
# 支付宝公钥
|
||||
alipayPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1vuaEyUkCgagVodfOJp/rk1gwVzs8f/QzEXAEUwZZne+VE8be0rUv9SLY0uOjixanw0yhG9LinHJlePCvuK0Y31Cxx0BXgOt27nGTSqm4oINFYd5WL1vNMPzPE2gat+7ohO3h6FRlmsxsq9W5ZRkko+04Be4lEGZ+Ter/b2v3m4I3CzX6kr42e39QlDRUpD9l9ixpkmfEatdDf01Xp++Tvr/3EZcYoG3oPGztI7B8Kw8KV/6he3ZBlGROWz8ywZSBtR294Y1PRDv+3QXC3nr7J6OrTbnvj+MAtKmwjdkFHiFVr3gfenzeI87LnXrDPahda7Mn6ToQ1NU9tsWCcJgQIDAQAB
|
||||
privateKey: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCYZr1VQ3FAD3PwcFMTC0sYWRRrxMu3bweEnXU2uK/o+3wxzrnax5l/SUvQJ3CeWUPC7X0cCNMhCVn0NYL08zIMyI9E5x42ry1qvKBRLhBUkctC9XTnIdTjuMbj5XqWuowLlVTP5EdGt4byyEUIh0wGa6WnS9yGn117jfFBii+E7MP+gDXe0HTmxafh8W+VOnAonaBIOLxV5h+AkkK5XKxn/S9EbiVsy/ce7QPkPLBBd1LvjxdHwJ267G9iH0aBhHIxfMKLcfG547Hug+gTcQRkp5Akk05jPiCPBPHYGETE5fAwSiQHsnCUa9AibqcbD1+9Dw1UkSoudeVqbgnB7KzhAgMBAAECggEAZho28J+9iQCRWV23moOvbQGJN+Zh4WQmckeXlvDHEd0iyK/KPnQJN4jgnPU/cyc0yayYbCbRZEnClWUgdoFUX9IigjQhPtvAHsl+0sR8tlvzBMoz5wH4ghRyU46TwdX7K2uBpcI3qn4ckB1yepNCcO6/zcR6W0r7s2JWZuVwjqmR++ixdV8jqg06kxWu39II68ormgflCvkOlJWhPbEeEDUqgRJUDx2r+iJZORlNIj0cT8BgCo4qfeyQWNpANhTBDpC3zXeBBmg5iG8JQTTokEeqwV8Ph1/JR6dOXT3Fn5Ok0tRndhS++XUB8Zqgc3q6F9Fe/za7225TBhV7TnOvvQKBgQDkMttCWNpZWSyQvjK/KMtd3c80XCC8ch0E3ReA1sZRSnsFfOwHb8+pdHeY54DgBtFohP9bmkb+tRtGwgpgWawSWD1iErX8FD78lqPHzJjUiQ+a1vJIkvfp1fJX4HlDTy3PuVW/OZgDL0udCSeTVmr/zBr1nLRdDkYlj9+Ra3bWAwKBgQCq9+NaX354pc6Qawtst4CNhV4NxSMiqefSXx8XV0hlzPnmb4PoBjj/lzdSKgcc7pxunLMmGK9pxDBDqi6y219ciPf5bZKlxoUo7GGHtt1yiMsRduAEHUaitQjXUAo5QXh0kqF4eu+JrXiGCjnNA6s3aQM2VK5szgicx+bbtpf+SwKBgB2Cgh4rVVk2ke/J2NAlm17xHyl7PHSCIUSOvspXe9/pTM1h4Tf4+pbES+8HCQBvgUcN4+PZqJKpovRchXD+R6U7qfxzxPrrN1X8uQNObvkVHGJ+p2hBMTQZCbTZf3T32UnCgtcuwHyw8gtFsst34nBf2aCneh+KiAG1gEjS59Q3AoGAH3oYL7FZNZlBWLF8nv2B+4xMbriW6XDir4a30LJPL/73G4f4fyV2JQiQNN5sBNWhk3PiP+dXlF98i1iv1FozSnQlQ5T65O6R4aDzq+rtBoNM7+A1Ckzhjl9KS2n/F9+H7953QBlSNMTtZbBISAie40rAPqaEnp+oUkUzqcwKW9UCgYAp+2aBq+lumJWGugoxkm8G3hJPO9B2Q/Ogn0+DrCL8GQFoiSYmF+x1d0K2fGglq8CjIK/HnzP7k3qn5ZQlkyn6UzVD0UbibWU2WSdh3100tJ9vpgngGkPaxx5+ZxDxzH8ljIwJZPWKK+xsbW+kX+DFIGBJ038zXwZ5TWKLPIasrw==
|
||||
# 应用公钥证书地址
|
||||
appCertPath: D:\project\证书\alipay\appCertPublicKey_2021004193649611.crt
|
||||
# 支付宝公钥证书地址
|
||||
alipayCertPath: D:\project\证书\alipay\alipayCertPublicKey_RSA2.crt
|
||||
# 支付宝根证书地址
|
||||
alipayRootCertPath: D:\project\证书\alipay\alipayRootCert.crt
|
||||
# AES秘钥
|
||||
aesPrivateKey: FGhCgOURrXkhGs36PUTHfg==
|
||||
# 通知地址
|
||||
notifyUrl: http://124.221.246.124:2290/app/pay/notify/ali
|
||||
# 转账回调地址
|
||||
transferNotifyUrl: http://124.221.246.124:2290/app/pay/notify/ali/transfer
|
||||
|
|
|
@ -150,3 +150,5 @@ ali:
|
|||
aesPrivateKey: FGhCgOURrXkhGs36PUTHfg==
|
||||
# 通知地址
|
||||
notifyUrl: https://kg.chuangtewl.com/prod-api/app/pay/notify/ali
|
||||
# 转账回调地址
|
||||
transferNotifyUrl: https://kg.chuangtewl.com/prod-api/app/pay/notify/ali/transfer
|
||||
|
|
Loading…
Reference in New Issue
Block a user