Forráskód Böngészése

mall + pay:
1、调整 returnUrl 的实现

YunaiV 1 éve
szülő
commit
20eb0a2a88
13 módosított fájl, 33 hozzáadás és 79 törlés
  1. 0 9
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/PayProperties.java
  2. 6 28
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java
  3. 2 4
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
  4. 4 0
      yudao-module-mall/yudao-module-trade-biz/pom.xml
  5. 3 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java
  6. 6 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
  7. 2 0
      yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java
  8. 0 19
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java
  9. 6 2
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderSubmitReqVO.java
  10. 2 2
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.http
  11. 2 12
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
  12. 0 1
      yudao-server/src/main/resources/application-dev.yaml
  13. 0 1
      yudao-server/src/main/resources/application-local.yaml

+ 0 - 9
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/PayProperties.java

@@ -23,13 +23,4 @@ public class PayProperties {
     @URL(message = "回调地址的格式必须是 URL")
     private String callbackUrl;
 
-    /**
-     * 回跳地址
-     *
-     * 实际上,对应的 PayNotifyController 的 returnCallback 方法的 URL
-     */
-    @URL(message = "回跳地址的格式必须是 URL")
-    @NotEmpty(message = "回跳地址不能为空")
-    private String returnUrl;
-
 }

+ 6 - 28
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java

@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
 
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.http.Method;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
@@ -41,11 +40,11 @@ public class AlipayPcPayClient extends AbstractAlipayClient {
         model.setTimeExpire(formatTime(reqDTO.getExpireTime()));
         model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 销售产品码. 目前 PC 支付场景下仅支持 FAST_INSTANT_TRADE_PAY
         // ② 个性化的参数
-        // 参考 https://www.pingxx.com/api/支付渠道 extra 参数说明.html 的 alipay_pc_direct 部分
-        model.setQrPayMode(MapUtil.getStr(reqDTO.getChannelExtras(), "qr_pay_mode"));
-        model.setQrcodeWidth(MapUtil.getLong(reqDTO.getChannelExtras(), "qr_code_width"));
-        // ③ 支付宝 PC 支付有多种展示模式,因此这里需要计算
-        String displayMode = getDisplayMode(reqDTO.getDisplayMode(), model.getQrPayMode());
+        // 如果想弄更多个性化的参数,可参考 https://www.pingxx.com/api/支付渠道 extra 参数说明.html 的 alipay_pc_direct 部分进行拓展
+        model.setQrPayMode("2"); // 跳转模式 - 订单码,效果参见:https://help.pingxx.com/article/1137360/
+        // ③ 支付宝 PC 支付有两种展示模式:FORM、URL
+        String displayMode = ObjectUtil.defaultIfNull(reqDTO.getDisplayMode(),
+                PayDisplayModeEnum.URL.getMode());
 
         // 1.2 构建 AlipayTradePagePayRequest 请求
         AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
@@ -67,25 +66,4 @@ public class AlipayPcPayClient extends AbstractAlipayClient {
                 .setDisplayContent(response.getBody());
     }
 
-    /**
-     * 获得最终的支付 UI 展示模式
-     *
-     * @param displayMode 前端传递的 UI 展示模式
-     * @param qrPayMode 前端传递的二维码模式
-     * @return 最终的支付 UI 展示模式
-     */
-    private String getDisplayMode(String displayMode, String qrPayMode) {
-        // 1.1 支付宝二维码的前置模式
-        if (StrUtil.equalsAny(qrPayMode, "0", "1", "3", "4")) {
-            return PayDisplayModeEnum.IFRAME.getMode();
-        }
-        // 1.2 支付宝二维码的跳转模式
-        if (StrUtil.equals(qrPayMode, "2")) {
-            return PayDisplayModeEnum.URL.getMode();
-        }
-        // 2. 前端传递了 UI 展示模式
-        return displayMode != null ? displayMode :
-                PayDisplayModeEnum.URL.getMode(); // 模式使用 URL 跳转
-    }
-
 }

+ 2 - 4
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java

@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
 
-import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.http.Method;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
@@ -37,9 +36,8 @@ public class AlipayWapPayClient extends AbstractAlipayClient {
         model.setTotalAmount(formatAmount(reqDTO.getAmount()));
         model.setProductCode("QUICK_WAP_PAY"); // 销售产品码. 目前 Wap 支付场景下仅支持 QUICK_WAP_PAY
         // ② 个性化的参数【无】
-        // ③ 支付宝 Wap 支付只有一种展示,考虑到前端可能希望二维码扫描后,手机打开
-        String displayMode = ObjectUtil.defaultIfNull(reqDTO.getDisplayMode(),
-                PayDisplayModeEnum.URL.getMode());
+        // ③ 支付宝 Wap 支付只有一种展示:URL
+        String displayMode = PayDisplayModeEnum.URL.getMode();
 
         // 1.2 构建 AlipayTradeWapPayRequest 请求
         AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

+ 4 - 0
yudao-module-mall/yudao-module-trade-biz/pom.xml

@@ -93,6 +93,10 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-excel</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 3 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java

@@ -55,8 +55,10 @@ public class AppTradeOrderDetailRespVO {
     @Schema(description = "付款超时时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime payExpireTime;
 
-    @Schema(description = "支付渠道", requiredMode = Schema.RequiredMode.REQUIRED, example = "wx_lite_pay")
+    @Schema(description = "支付渠道", example = "wx_lite_pay")
     private String payChannelCode;
+    @Schema(description = "支付渠道名", example = "微信小程序支付")
+    private String payChannelName;
 
     @Schema(description = "商品原价(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
     private Integer totalPrice;

+ 6 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java

@@ -1,12 +1,15 @@
 package cn.iocoder.yudao.module.trade.convert.order;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
+import cn.iocoder.yudao.module.pay.enums.DictTypeConstants;
 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
@@ -234,6 +237,9 @@ public interface TradeOrderConvert {
                                                 List<ProductPropertyValueDetailRespDTO> propertyValueDetails, TradeOrderProperties tradeOrderProperties) {
         AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems);
         orderVO.setPayExpireTime(addTime(tradeOrderProperties.getExpireTime()));
+        if (StrUtil.isNotEmpty(order.getPayChannelCode())) {
+            orderVO.setPayChannelName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHANNEL_CODE_TYPE, order.getPayChannelCode()));
+        }
         // 处理商品属性
         Map<Long, ProductPropertyValueDetailRespDTO> propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId);
         for (int i = 0; i < orderItems.size(); i++) {

+ 2 - 0
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java

@@ -7,6 +7,8 @@ package cn.iocoder.yudao.module.pay.enums;
  */
 public interface DictTypeConstants {
 
+    String CHANNEL_CODE_TYPE = "pay_channel_code_type"; // 支付-渠道名
+
     String ORDER_STATUS = "pay_order_status"; // 支付-订单-订单状态
     String ORDER_NOTIFY_STATUS = "pay_order_notify_status"; // 支付-订单-订单回调商户状态
 

+ 0 - 19
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java

@@ -6,8 +6,6 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyRespDTO;
-import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
-import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService;
 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
 import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -39,23 +37,6 @@ public class PayNotifyController {
     @Resource
     private PayClientFactory payClientFactory;
 
-    /**
-     * 统一的跳转页面,支付宝跳转参数说明
-     *
-     * <a href="https://opendocs.alipay.com/open/203/105285#前台回跳参数说明">支付宝 - 前台回跳参数说明</a>
-     *
-     * @param channelId 渠道编号
-     * @return 返回跳转页面
-     */
-    @GetMapping(value = "/return/{channelId}")
-    @Operation(summary = "渠道统一的支付成功返回地址")
-    @Deprecated // TODO yunai:如果是 way 的情况,应该是跳转回前端地址
-    public String returnCallback(@PathVariable("channelId") Long channelId,
-                                 @RequestParam Map<String, String> params) {
-        log.info("[returnCallback][app_id({}) 跳转]", params.get("app_id"));
-        return String.format("渠道[%s]支付成功", channelId);
-    }
-
     /**
      * 统一的渠道支付回调,支付宝的退款回调
      *

+ 6 - 2
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderSubmitReqVO.java

@@ -2,11 +2,10 @@ package cn.iocoder.yudao.module.pay.controller.admin.order.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.experimental.Accessors;
+import org.hibernate.validator.constraints.URL;
 
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
-import java.awt.*;
 import java.util.Map;
 
 @Schema(description = "管理后台 - 支付订单提交 Request VO")
@@ -26,4 +25,9 @@ public class PayOrderSubmitReqVO {
 
     @Schema(description = "展示模式", example = "url") // 参见 {@link PayDisplayModeEnum} 枚举。如果不传递,则每个支付渠道使用默认的方式
     private String displayMode;
+
+    @Schema(description = "回跳地址")
+    @URL(message = "回跳地址的格式必须是 URL")
+    private String returnUrl;
+
 }

+ 2 - 2
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.http

@@ -5,6 +5,6 @@ Authorization: Bearer {{appToken}}
 tenant-id: {{appTenentId}}
 
 {
-  "id": 125,
-  "channelCode": "alipay_qr"
+  "id": 174,
+  "channelCode": "alipay_pc"
 }

+ 2 - 12
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java

@@ -4,7 +4,6 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.pay.config.PayProperties;
 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
@@ -44,7 +43,7 @@ import java.util.Collection;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.*;
+import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
 
 /**
  * 支付订单 Service 实现类
@@ -147,7 +146,7 @@ public class PayOrderServiceImpl implements PayOrderService {
                 .setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性!
                 .setSubject(order.getSubject()).setBody(order.getBody())
                 .setNotifyUrl(genChannelPayNotifyUrl(channel))
-                .setReturnUrl(genChannelReturnUrl(channel))
+                .setReturnUrl(reqVO.getReturnUrl())
                 // 订单相关字段
                 .setAmount(order.getAmount()).setExpireTime(order.getExpireTime());
         PayOrderUnifiedRespDTO unifiedOrderRespDTO = client.unifiedOrder(unifiedOrderReqDTO);
@@ -183,15 +182,6 @@ public class PayOrderServiceImpl implements PayOrderService {
         return channel;
     }
 
-    /**
-     * 根据支付渠道的编码,生成支付渠道的返回地址
-     * @param channel 支付渠道
-     * @return 支付成功返回的地址。 配置地址 + "/" + channel id
-     */
-    private String genChannelReturnUrl(PayChannelDO channel) {
-        return payProperties.getReturnUrl() + "/" + channel.getId();
-    }
-
     /**
      * 根据支付渠道的编码,生成支付渠道的回调地址
      *

+ 0 - 1
yudao-server/src/main/resources/application-dev.yaml

@@ -168,7 +168,6 @@ yudao:
       - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
   pay:
     callback-url: http://yunai.natapp1.cc/admin-api/pay/notify/callback
-    return-url: http://yunai.natapp1.cc/admin-api/pay/notify/return
   demo: true # 开启演示模式
 
 justauth:

+ 0 - 1
yudao-server/src/main/resources/application-local.yaml

@@ -195,7 +195,6 @@ yudao:
       - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
   pay:
     callback-url: http://yunai.natapp1.cc/admin-api/pay/notify/callback
-    return-url: http://yunai.natapp1.cc/admin-api/pay/notify/return
   access-log: # 访问日志的配置项
     enable: false
   error-code: # 错误码相关配置项