pay: 接入支付宝 App 支付

This commit is contained in:
YunaiV 2023-02-18 23:18:10 +08:00
parent e6f414b918
commit 379aeeae16
5 changed files with 34 additions and 12 deletions

View File

@ -116,6 +116,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
protected abstract PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable; protected abstract PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
// ========== 各种工具方法 ==========
protected String formatAmount(Integer amount) { protected String formatAmount(Integer amount) {
return String.valueOf(amount / 100.0); return String.valueOf(amount / 100.0);

View File

@ -0,0 +1,5 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
// TODO 芋艿待实现
public class AlipayAppPayClient {
}

View File

@ -1,8 +1,12 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
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.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradePrecreateModel; import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest; import com.alipay.api.request.AlipayTradePrecreateRequest;
@ -13,6 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
/** /**
* 支付宝扫码支付 PayClient 实现类 * 支付宝扫码支付 PayClient 实现类
*
* 文档https://opendocs.alipay.com/apis/02890k * 文档https://opendocs.alipay.com/apis/02890k
* *
* @author 芋道源码 * @author 芋道源码
@ -21,24 +26,31 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
public class AlipayQrPayClient extends AbstractAlipayClient { public class AlipayQrPayClient extends AbstractAlipayClient {
public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) { public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) {
super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config, new AlipayPayCodeMapping()); super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config,
new AlipayPayCodeMapping());
} }
@Override @Override
public PayCommonResult<AlipayTradePrecreateResponse> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
// 构建 AlipayTradePrecreateModel 请求 // 1.1 构建 AlipayTradePrecreateModel 请求
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel(); AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
// 通用的参数
model.setOutTradeNo(reqDTO.getMerchantOrderId()); model.setOutTradeNo(reqDTO.getMerchantOrderId());
model.setSubject(reqDTO.getSubject()); model.setSubject(reqDTO.getSubject());
model.setBody(reqDTO.getBody()); model.setBody(reqDTO.getBody());
model.setTotalAmount(formatAmount(reqDTO.getAmount()).toString()); // 单位 model.setTotalAmount(formatAmount(reqDTO.getAmount()));
// TODO 芋艿userIp + expireTime model.setProductCode("FACE_TO_FACE_PAYMENT"); // 销售产品码. 目前扫码支付场景下仅支持 QUICK_WAP_PAY
// 构建 AlipayTradePrecreateRequest // 个性化的参数
// 支付宝扫码支付只有一种展示考虑到前端可能希望二维码扫描后手机打开
String displayMode = PayDisplayModeEnum.QR_CODE.getMode();
// 1.2 构建 AlipayTradePrecreateRequest 请求
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setBizModel(model); request.setBizModel(model);
request.setNotifyUrl(reqDTO.getNotifyUrl()); request.setNotifyUrl(reqDTO.getNotifyUrl());
request.setReturnUrl(reqDTO.getReturnUrl()); request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿待搞
// 执行请求
// 2.1 执行请求
AlipayTradePrecreateResponse response; AlipayTradePrecreateResponse response;
try { try {
response = client.execute(request); response = client.execute(request);
@ -46,7 +58,10 @@ public class AlipayQrPayClient extends AbstractAlipayClient {
log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), e); log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), e);
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping); return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
} }
// TODO 芋艿sub Code 需要测试下各种失败的情况 // 2.2 处理结果
return PayCommonResult.build(response.getCode(), response.getMsg(), response, codeMapping); PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO()
.setDisplayMode(displayMode).setDisplayContent(response.getQrCode());
return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"),
response.getMsg(), respDTO, codeMapping);
} }
} }

View File

@ -53,7 +53,7 @@ public class AlipayWapPayClient extends AbstractAlipayClient {
request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿待搞 request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿待搞
model.setQuitUrl(reqDTO.getReturnUrl()); // TODO 芋艿待搞 model.setQuitUrl(reqDTO.getReturnUrl()); // TODO 芋艿待搞
// 执行请求 // 2.1 执行请求
AlipayTradeWapPayResponse response; AlipayTradeWapPayResponse response;
try { try {
response = client.pageExecute(request, Method.GET.name()); response = client.pageExecute(request, Method.GET.name());

View File

@ -3,6 +3,7 @@ import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
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.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient; import com.alipay.api.DefaultAlipayClient;
@ -87,7 +88,7 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
}))).thenReturn(response); }))).thenReturn(response);
PayCommonResult<AlipayTradePrecreateResponse> result = client.doUnifiedOrder(reqDTO); PayCommonResult<PayOrderUnifiedRespDTO> result = client.doUnifiedOrder(reqDTO);
// 断言 // 断言
assertEquals(response.getCode(), result.getApiCode()); assertEquals(response.getCode(), result.getApiCode());
assertEquals(response.getMsg(), result.getApiMsg()); assertEquals(response.getMsg(), result.getApiMsg());