Commit 379aeeae16b2c0949f3731c61600d9931424c2c3
1 parent
e6f414b9
pay: 接入支付宝 App 支付
Showing
5 changed files
with
34 additions
and
12 deletions
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
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()); |