Ver código fonte

pay: 接入支付宝 App 支付

YunaiV 2 anos atrás
pai
commit
379aeeae16

+ 1 - 0
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
 
     protected abstract PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
 
+    // ========== 各种工具方法 ==========
 
     protected String formatAmount(Integer amount) {
         return String.valueOf(amount / 100.0);

+ 5 - 0
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java

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

+ 25 - 10
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java

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

+ 1 - 1
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 {
         request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
         model.setQuitUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
 
-        // 执行请求
+        // 2.1 执行请求
         AlipayTradeWapPayResponse response;
         try {
             response = client.pageExecute(request, Method.GET.name());

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