Commit 379aeeae16b2c0949f3731c61600d9931424c2c3

Authored by YunaiV
1 parent e6f414b9

pay: 接入支付宝 App 支付

yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java
@@ -116,6 +116,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen @@ -116,6 +116,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
116 116
117 protected abstract PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable; 117 protected abstract PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
118 118
  119 + // ========== 各种工具方法 ==========
119 120
120 protected String formatAmount(Integer amount) { 121 protected String formatAmount(Integer amount) {
121 return String.valueOf(amount / 100.0); 122 return String.valueOf(amount / 100.0);
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
  2 +
  3 +// TODO 芋艿:待实现
  4 +public class AlipayAppPayClient {
  5 +}
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java
1 package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; 1 package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.hutool.core.util.StrUtil;
3 import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; 5 import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
  7 +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
5 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; 8 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  9 +import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
6 import com.alipay.api.AlipayApiException; 10 import com.alipay.api.AlipayApiException;
7 import com.alipay.api.domain.AlipayTradePrecreateModel; 11 import com.alipay.api.domain.AlipayTradePrecreateModel;
8 import com.alipay.api.request.AlipayTradePrecreateRequest; 12 import com.alipay.api.request.AlipayTradePrecreateRequest;
@@ -13,6 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString @@ -13,6 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
13 17
14 /** 18 /**
15 * 支付宝【扫码支付】的 PayClient 实现类 19 * 支付宝【扫码支付】的 PayClient 实现类
  20 + *
16 * 文档:https://opendocs.alipay.com/apis/02890k 21 * 文档:https://opendocs.alipay.com/apis/02890k
17 * 22 *
18 * @author 芋道源码 23 * @author 芋道源码
@@ -21,24 +26,31 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString @@ -21,24 +26,31 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
21 public class AlipayQrPayClient extends AbstractAlipayClient { 26 public class AlipayQrPayClient extends AbstractAlipayClient {
22 27
23 public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) { 28 public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) {
24 - super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config, new AlipayPayCodeMapping()); 29 + super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config,
  30 + new AlipayPayCodeMapping());
25 } 31 }
26 32
27 @Override 33 @Override
28 - public PayCommonResult<AlipayTradePrecreateResponse> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {  
29 - // 构建 AlipayTradePrecreateModel 请求 34 + public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
  35 + // 1.1 构建 AlipayTradePrecreateModel 请求
30 AlipayTradePrecreateModel model = new AlipayTradePrecreateModel(); 36 AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
  37 + // ① 通用的参数
31 model.setOutTradeNo(reqDTO.getMerchantOrderId()); 38 model.setOutTradeNo(reqDTO.getMerchantOrderId());
32 model.setSubject(reqDTO.getSubject()); 39 model.setSubject(reqDTO.getSubject());
33 model.setBody(reqDTO.getBody()); 40 model.setBody(reqDTO.getBody());
34 - model.setTotalAmount(formatAmount(reqDTO.getAmount()).toString()); // 单位:元  
35 - // TODO 芋艿:userIp + expireTime  
36 - // 构建 AlipayTradePrecreateRequest 41 + model.setTotalAmount(formatAmount(reqDTO.getAmount()));
  42 + model.setProductCode("FACE_TO_FACE_PAYMENT"); // 销售产品码. 目前扫码支付场景下仅支持 QUICK_WAP_PAY
  43 + // ② 个性化的参数【无】
  44 + // ③ 支付宝扫码支付只有一种展示,考虑到前端可能希望二维码扫描后,手机打开
  45 + String displayMode = PayDisplayModeEnum.QR_CODE.getMode();
  46 +
  47 + // 1.2 构建 AlipayTradePrecreateRequest 请求
37 AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); 48 AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
38 request.setBizModel(model); 49 request.setBizModel(model);
39 request.setNotifyUrl(reqDTO.getNotifyUrl()); 50 request.setNotifyUrl(reqDTO.getNotifyUrl());
40 - request.setReturnUrl(reqDTO.getReturnUrl());  
41 - // 执行请求 51 + request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
  52 +
  53 + // 2.1 执行请求
42 AlipayTradePrecreateResponse response; 54 AlipayTradePrecreateResponse response;
43 try { 55 try {
44 response = client.execute(request); 56 response = client.execute(request);
@@ -46,7 +58,10 @@ public class AlipayQrPayClient extends AbstractAlipayClient { @@ -46,7 +58,10 @@ public class AlipayQrPayClient extends AbstractAlipayClient {
46 log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), e); 58 log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), e);
47 return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping); 59 return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
48 } 60 }
49 - // TODO 芋艿:sub Code 需要测试下各种失败的情况  
50 - return PayCommonResult.build(response.getCode(), response.getMsg(), response, codeMapping); 61 + // 2.2 处理结果
  62 + PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO()
  63 + .setDisplayMode(displayMode).setDisplayContent(response.getQrCode());
  64 + return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"),
  65 + response.getMsg(), respDTO, codeMapping);
51 } 66 }
52 } 67 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
@@ -53,7 +53,7 @@ public class AlipayWapPayClient extends AbstractAlipayClient { @@ -53,7 +53,7 @@ public class AlipayWapPayClient extends AbstractAlipayClient {
53 request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞 53 request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
54 model.setQuitUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞 54 model.setQuitUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
55 55
56 - // 执行请求 56 + // 2.1 执行请求
57 AlipayTradeWapPayResponse response; 57 AlipayTradeWapPayResponse response;
58 try { 58 try {
59 response = client.pageExecute(request, Method.GET.name()); 59 response = client.pageExecute(request, Method.GET.name());
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/alipay/AlipayQrPayClientTest.java
@@ -3,6 +3,7 @@ import cn.hutool.core.util.ReflectUtil; @@ -3,6 +3,7 @@ import cn.hutool.core.util.ReflectUtil;
3 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; 3 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
4 import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; 4 import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
  6 +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
6 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; 7 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
7 import com.alipay.api.AlipayApiException; 8 import com.alipay.api.AlipayApiException;
8 import com.alipay.api.DefaultAlipayClient; 9 import com.alipay.api.DefaultAlipayClient;
@@ -87,7 +88,7 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { @@ -87,7 +88,7 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
87 }))).thenReturn(response); 88 }))).thenReturn(response);
88 89
89 90
90 - PayCommonResult<AlipayTradePrecreateResponse> result = client.doUnifiedOrder(reqDTO); 91 + PayCommonResult<PayOrderUnifiedRespDTO> result = client.doUnifiedOrder(reqDTO);
91 // 断言 92 // 断言
92 assertEquals(response.getCode(), result.getApiCode()); 93 assertEquals(response.getCode(), result.getApiCode());
93 assertEquals(response.getMsg(), result.getApiMsg()); 94 assertEquals(response.getMsg(), result.getApiMsg());