Commit b34801f303773ec8dcdd9d516f606b8a5701b085
1 parent
df702e8d
pay: 接入支付宝 PC 支付的跳转模式
Showing
17 changed files
with
262 additions
and
158 deletions
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java
| 1 | 1 | package cn.iocoder.yudao.framework.pay.core.client.dto.order; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum; | |
| 3 | 4 | import lombok.Data; |
| 4 | 5 | import org.hibernate.validator.constraints.Length; |
| 5 | 6 | import org.hibernate.validator.constraints.URL; |
| ... | ... | @@ -7,6 +8,7 @@ import org.hibernate.validator.constraints.URL; |
| 7 | 8 | import javax.validation.constraints.DecimalMin; |
| 8 | 9 | import javax.validation.constraints.NotEmpty; |
| 9 | 10 | import javax.validation.constraints.NotNull; |
| 11 | +import java.awt.*; | |
| 10 | 12 | import java.time.LocalDateTime; |
| 11 | 13 | import java.util.Map; |
| 12 | 14 | |
| ... | ... | @@ -78,4 +80,13 @@ public class PayOrderUnifiedReqDTO { |
| 78 | 80 | */ |
| 79 | 81 | private Map<String, String> channelExtras; |
| 80 | 82 | |
| 83 | + /** | |
| 84 | + * 展示模式 | |
| 85 | + * | |
| 86 | + * 如果不传递,则每个支付渠道使用默认的方式 | |
| 87 | + * | |
| 88 | + * 枚举 {@link PayDisplayModeEnum} | |
| 89 | + */ | |
| 90 | + private String displayMode; | |
| 91 | + | |
| 81 | 92 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/bo/PayOrderSubmitRespBO.java renamed to yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedRespDTO.java
| 1 | -package cn.iocoder.yudao.module.pay.service.order.bo; | |
| 1 | +package cn.iocoder.yudao.framework.pay.core.client.dto.order; | |
| 2 | 2 | |
| 3 | +import lombok.AllArgsConstructor; | |
| 3 | 4 | import lombok.Data; |
| 4 | 5 | |
| 5 | -import java.io.Serializable; | |
| 6 | - | |
| 7 | 6 | /** |
| 8 | - * 支付单提交 Response BO | |
| 7 | + * 统一下单 Response DTO | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 9 | 10 | */ |
| 10 | 11 | @Data |
| 11 | -public class PayOrderSubmitRespBO implements Serializable { | |
| 12 | +public class PayOrderUnifiedRespDTO { | |
| 12 | 13 | |
| 13 | 14 | /** |
| 14 | - * 支付拓展单的编号 | |
| 15 | + * 展示模式 | |
| 15 | 16 | */ |
| 16 | - private Long extensionId; | |
| 17 | - | |
| 17 | + private String displayMode; | |
| 18 | 18 | /** |
| 19 | - * 调用支付渠道的响应结果 | |
| 19 | + * 展示内容 | |
| 20 | 20 | */ |
| 21 | - private Object invokeResponse; | |
| 21 | + private String displayContent; | |
| 22 | 22 | |
| 23 | 23 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java
| 1 | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.lang.Pair; | |
| 4 | +import cn.hutool.core.map.MapUtil; | |
| 5 | +import cn.hutool.core.util.ObjectUtil; | |
| 3 | 6 | import cn.hutool.core.util.StrUtil; |
| 4 | 7 | import cn.hutool.http.Method; |
| 8 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 5 | 9 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 6 | 10 | import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; |
| 7 | 11 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; |
| 12 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; | |
| 8 | 13 | import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; |
| 9 | -import com.alibaba.fastjson.JSONObject; | |
| 14 | +import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum; | |
| 10 | 15 | import com.alipay.api.AlipayApiException; |
| 11 | 16 | import com.alipay.api.domain.AlipayTradePagePayModel; |
| 12 | 17 | import com.alipay.api.request.AlipayTradePagePayRequest; |
| 13 | 18 | import com.alipay.api.response.AlipayTradePagePayResponse; |
| 14 | 19 | import lombok.extern.slf4j.Slf4j; |
| 15 | 20 | |
| 21 | +import java.util.HashMap; | |
| 22 | +import java.util.Objects; | |
| 23 | + | |
| 16 | 24 | |
| 17 | 25 | /** |
| 18 | 26 | * 支付宝【PC网站支付】的 PayClient 实现类 |
| ... | ... | @@ -28,35 +36,72 @@ public class AlipayPcPayClient extends AbstractAlipayClient { |
| 28 | 36 | } |
| 29 | 37 | |
| 30 | 38 | @Override |
| 31 | - public PayCommonResult<AlipayTradePagePayResponse> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | |
| 32 | - // 构建 AlipayTradePagePayModel 请求 | |
| 39 | + public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | |
| 40 | + // 1.1 构建 AlipayTradePagePayModel 请求 | |
| 33 | 41 | AlipayTradePagePayModel model = new AlipayTradePagePayModel(); |
| 34 | - // 构建 AlipayTradePagePayRequest | |
| 42 | + // ① 通用的参数 | |
| 43 | + model.setOutTradeNo(reqDTO.getMerchantOrderId()); | |
| 44 | + model.setSubject(reqDTO.getSubject()); | |
| 45 | + model.setTotalAmount(String.valueOf(calculateAmount(reqDTO.getAmount()))); | |
| 46 | + model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 销售产品码. 目前电脑支付场景下仅支持 FAST_INSTANT_TRADE_PAY | |
| 47 | + // ② 个性化的参数 | |
| 48 | + // 参考 https://www.pingxx.com/api/支付渠道 extra 参数说明.html 的 alipay_pc_direct 部分 | |
| 49 | + model.setQrPayMode(MapUtil.getStr(reqDTO.getChannelExtras(), "qr_pay_mode")); | |
| 50 | + model.setQrcodeWidth(MapUtil.getLong(reqDTO.getChannelExtras(), "qr_code_width")); | |
| 51 | + // ③ 支付宝 PC 支付有多种展示模式,因此这里需要计算 | |
| 52 | + String displayMode = getDisplayMode(reqDTO.getDisplayMode(), model.getQrPayMode()); | |
| 53 | + | |
| 54 | + // 1.2 构建 AlipayTradePagePayRequest 请求 | |
| 35 | 55 | AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); |
| 36 | 56 | request.setBizModel(model); |
| 37 | - JSONObject bizContent = new JSONObject(); | |
| 38 | - // 参数说明可查看: https://opendocs.alipay.com/open/028r8t?scene=22 | |
| 39 | - bizContent.put("out_trade_no", reqDTO.getMerchantOrderId()); | |
| 40 | - bizContent.put("subject", reqDTO.getSubject()); | |
| 41 | - bizContent.put("total_amount", calculateAmount(reqDTO.getAmount())); | |
| 42 | - bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); // 销售产品码. 目前电脑支付场景下仅支持 FAST_INSTANT_TRADE_PAY | |
| 43 | - // PC扫码支付的方式:支持前置模式和跳转模式。4: 订单码-可定义宽度的嵌入式二维码 | |
| 44 | -// bizContent.put("qr_pay_mode", "4"); | |
| 45 | - // 自定义二维码宽度 | |
| 46 | -// bizContent.put("qrcode_width", "150"); | |
| 47 | - request.setBizContent(bizContent.toJSONString()); | |
| 48 | 57 | request.setNotifyUrl(reqDTO.getNotifyUrl()); |
| 49 | - request.setReturnUrl(""); | |
| 50 | - // 执行请求 | |
| 58 | + request.setReturnUrl(""); // TODO 芋艿,待搞 | |
| 59 | + | |
| 60 | + // 2.1 执行请求 | |
| 51 | 61 | AlipayTradePagePayResponse response; |
| 52 | 62 | try { |
| 53 | - response = client.pageExecute(request, Method.GET.name()); | |
| 63 | + if (Objects.equals(displayMode, PayDisplayModeEnum.FORM.getMode())) { | |
| 64 | + response = client.pageExecute(request, Method.POST.name()); // 需要特殊使用 POST 请求 | |
| 65 | + } else { | |
| 66 | + response = client.pageExecute(request, Method.GET.name()); | |
| 67 | + } | |
| 54 | 68 | } catch (AlipayApiException e) { |
| 55 | 69 | log.error("[unifiedOrder][request({}) 发起支付失败]", JsonUtils.toJsonString(reqDTO), e); |
| 56 | 70 | return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping); |
| 57 | 71 | } |
| 72 | + // 1. form | |
| 73 | + // 2. url | |
| 74 | + // 3. code | |
| 75 | + // 4. code url | |
| 76 | + | |
| 77 | + // 2.2 处理结果 | |
| 58 | 78 | System.out.println(response.getBody()); |
| 79 | + PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO() | |
| 80 | + .setDisplayMode(displayMode).setDisplayContent(response.getBody()); | |
| 59 | 81 | // 响应为表单格式,前端可嵌入响应的页面或关闭当前支付窗口 |
| 60 | - return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000") ,response.getMsg(), response, codeMapping); | |
| 82 | + return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"), | |
| 83 | + response.getMsg(), respDTO, codeMapping); | |
| 61 | 84 | } |
| 85 | + | |
| 86 | + /** | |
| 87 | + * 获得最终的支付 UI 展示模式 | |
| 88 | + * | |
| 89 | + * @param displayMode 前端传递的 UI 展示模式 | |
| 90 | + * @param qrPayMode 前端传递的二维码模式 | |
| 91 | + * @return 最终的支付 UI 展示模式 | |
| 92 | + */ | |
| 93 | + private String getDisplayMode(String displayMode, String qrPayMode) { | |
| 94 | + // 1.1 支付宝二维码的前置模式 | |
| 95 | + if (StrUtil.equalsAny(qrPayMode, "0", "1", "3", "4")) { | |
| 96 | + return PayDisplayModeEnum.IFRAME.getMode(); | |
| 97 | + } | |
| 98 | + // 1.2 支付宝二维码的跳转模式 | |
| 99 | + if (StrUtil.equals(qrPayMode, "2")) { | |
| 100 | + return PayDisplayModeEnum.URL.getMode(); | |
| 101 | + } | |
| 102 | + // 2. 前端传递了 UI 展示模式 | |
| 103 | + return displayMode != null ? displayMode : | |
| 104 | + PayDisplayModeEnum.URL.getMode(); // 模式使用 URL 跳转 | |
| 105 | + } | |
| 106 | + | |
| 62 | 107 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayDisplayModeEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.pay.core.enums; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * 支付 UI 展示模式 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 10 | + */ | |
| 11 | +@Getter | |
| 12 | +@AllArgsConstructor | |
| 13 | +public enum PayDisplayModeEnum { | |
| 14 | + | |
| 15 | + URL("url"), // Redirect 跳转链接的方式 | |
| 16 | + IFRAME("iframe"), // IFrame 内嵌链接的方式 | |
| 17 | + FORM("form"), // HTML 表单提交 | |
| 18 | + QR_CODE("qr_code"), // 二维码的文字内容 | |
| 19 | + QR_CODE_URL("qr_code_url"), // 二维码的图片链接 | |
| 20 | + ; | |
| 21 | + | |
| 22 | + /** | |
| 23 | + * 展示模式 | |
| 24 | + */ | |
| 25 | + private final String mode; | |
| 26 | + | |
| 27 | +} | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java
| ... | ... | @@ -2,9 +2,13 @@ package cn.iocoder.yudao.module.pay.controller.admin.order; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollectionUtil; |
| 4 | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 7 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 8 | +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | |
| 9 | +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | |
| 10 | +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; | |
| 5 | 11 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; |
| 6 | -import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; | |
| 7 | -import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; | |
| 8 | 12 | import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; |
| 9 | 13 | import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; |
| 10 | 14 | import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; |
| ... | ... | @@ -14,16 +18,9 @@ import cn.iocoder.yudao.module.pay.service.merchant.PayAppService; |
| 14 | 18 | import cn.iocoder.yudao.module.pay.service.merchant.PayMerchantService; |
| 15 | 19 | import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService; |
| 16 | 20 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 17 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 18 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 19 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 20 | -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | |
| 21 | -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | |
| 22 | -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; | |
| 23 | -import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO; | |
| 24 | -import io.swagger.v3.oas.annotations.tags.Tag; | |
| 25 | -import io.swagger.v3.oas.annotations.Parameter; | |
| 26 | 21 | import io.swagger.v3.oas.annotations.Operation; |
| 22 | +import io.swagger.v3.oas.annotations.Parameter; | |
| 23 | +import io.swagger.v3.oas.annotations.tags.Tag; | |
| 27 | 24 | import org.springframework.security.access.prepost.PreAuthorize; |
| 28 | 25 | import org.springframework.validation.annotation.Validated; |
| 29 | 26 | import org.springframework.web.bind.annotation.*; |
| ... | ... | @@ -94,10 +91,9 @@ public class PayOrderController { |
| 94 | 91 | |
| 95 | 92 | @PostMapping("/submit") |
| 96 | 93 | @Operation(summary = "提交支付订单") |
| 97 | - public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) { | |
| 98 | - PayOrderSubmitRespBO respDTO = payOrderService.submitPayOrder( | |
| 99 | - PayOrderConvert.INSTANCE.convert(reqVO, getClientIP())); | |
| 100 | - return success(new AppPayOrderSubmitRespVO(respDTO.getInvokeResponse())); | |
| 94 | + public CommonResult<PayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) { | |
| 95 | + PayOrderSubmitRespVO respVO = payOrderService.submitPayOrder(reqVO, getClientIP()); | |
| 96 | + return success(respVO); | |
| 101 | 97 | } |
| 102 | 98 | |
| 103 | 99 | @GetMapping("/page") | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderSubmitReqVO.java
| ... | ... | @@ -6,11 +6,11 @@ import lombok.experimental.Accessors; |
| 6 | 6 | |
| 7 | 7 | import javax.validation.constraints.NotEmpty; |
| 8 | 8 | import javax.validation.constraints.NotNull; |
| 9 | +import java.awt.*; | |
| 9 | 10 | import java.util.Map; |
| 10 | 11 | |
| 11 | 12 | @Schema(description = "管理后台 - 支付订单提交 Request VO") |
| 12 | 13 | @Data |
| 13 | -@Accessors(chain = true) | |
| 14 | 14 | public class PayOrderSubmitReqVO { |
| 15 | 15 | |
| 16 | 16 | @Schema(description = "支付单编号", required = true, example = "1024") |
| ... | ... | @@ -24,4 +24,6 @@ public class PayOrderSubmitReqVO { |
| 24 | 24 | @Schema(description = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数") |
| 25 | 25 | private Map<String, String> channelExtras; |
| 26 | 26 | |
| 27 | + @Schema(description = "展示模式", example = "url") // 参见 {@link PayDisplayModeEnum} 枚举。如果不传递,则每个支付渠道使用默认的方式 | |
| 28 | + private String displayMode; | |
| 27 | 29 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderSubmitRespVO.java
| ... | ... | @@ -9,15 +9,12 @@ import lombok.experimental.Accessors; |
| 9 | 9 | |
| 10 | 10 | @Schema(description = "管理后台 - 支付订单提交 Response VO") |
| 11 | 11 | @Data |
| 12 | -@Accessors(chain = true) | |
| 13 | -@Builder | |
| 14 | -@NoArgsConstructor | |
| 15 | -@AllArgsConstructor | |
| 16 | 12 | public class PayOrderSubmitRespVO { |
| 17 | 13 | |
| 18 | - /** | |
| 19 | - * 调用支付渠道的响应结果 | |
| 20 | - */ | |
| 21 | - private Object invokeResponse; | |
| 14 | + @Schema(description = "展示模式", required = true, example = "url") // 参见 PayDisplayModeEnum 枚举 | |
| 15 | + private String displayMode; | |
| 16 | + | |
| 17 | + @Schema(description = "展示内容", required = true) | |
| 18 | + private String displayContent; | |
| 22 | 19 | |
| 23 | 20 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.controller.app.order; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; | |
| 4 | 5 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; |
| 6 | 7 | import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; |
| 7 | 8 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 8 | -import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO; | |
| 9 | 9 | import io.swagger.v3.oas.annotations.Operation; |
| 10 | 10 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 11 | 11 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -33,9 +33,8 @@ public class AppPayOrderController { |
| 33 | 33 | @PostMapping("/submit") |
| 34 | 34 | @Operation(summary = "提交支付订单") |
| 35 | 35 | public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) { |
| 36 | - PayOrderSubmitRespBO respDTO = orderService.submitPayOrder( | |
| 37 | - PayOrderConvert.INSTANCE.convert(reqVO, getClientIP())); | |
| 38 | - return success(new AppPayOrderSubmitRespVO(respDTO.getInvokeResponse())); | |
| 36 | + PayOrderSubmitRespVO respVO = orderService.submitPayOrder(reqVO, getClientIP()); | |
| 37 | + return success(PayOrderConvert.INSTANCE.convert3(respVO)); | |
| 39 | 38 | } |
| 40 | 39 | |
| 41 | 40 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.controller.app.order.vo; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO; | |
| 3 | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 5 | import lombok.Data; |
| 5 | 6 | import lombok.experimental.Accessors; |
| ... | ... | @@ -10,18 +11,5 @@ import java.util.Map; |
| 10 | 11 | |
| 11 | 12 | @Schema(description = "用户 APP - 支付订单提交 Request VO") |
| 12 | 13 | @Data |
| 13 | -@Accessors(chain = true) | |
| 14 | -public class AppPayOrderSubmitReqVO { | |
| 15 | - | |
| 16 | - @Schema(description = "支付单编号", required = true, example = "1024") | |
| 17 | - @NotNull(message = "支付单编号不能为空") | |
| 18 | - private Long id; | |
| 19 | - | |
| 20 | - @Schema(description = "支付渠道", required = true, example = "wx_pub") | |
| 21 | - @NotEmpty(message = "支付渠道不能为空") | |
| 22 | - private String channelCode; | |
| 23 | - | |
| 24 | - @Schema(description = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数") | |
| 25 | - private Map<String, String> channelExtras; | |
| 26 | - | |
| 14 | +public class AppPayOrderSubmitReqVO extends PayOrderSubmitReqVO { | |
| 27 | 15 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.controller.app.order.vo; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; | |
| 3 | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 5 | import lombok.AllArgsConstructor; |
| 5 | 6 | import lombok.Builder; |
| ... | ... | @@ -9,15 +10,6 @@ import lombok.experimental.Accessors; |
| 9 | 10 | |
| 10 | 11 | @Schema(description = "用户 APP - 支付订单提交 Response VO") |
| 11 | 12 | @Data |
| 12 | -@Accessors(chain = true) | |
| 13 | -@Builder | |
| 14 | -@NoArgsConstructor | |
| 15 | -@AllArgsConstructor | |
| 16 | -public class AppPayOrderSubmitRespVO { | |
| 17 | - | |
| 18 | - /** | |
| 19 | - * 调用支付渠道的响应结果 | |
| 20 | - */ | |
| 21 | - private Object invokeResponse; | |
| 13 | +public class AppPayOrderSubmitRespVO extends PayOrderSubmitRespVO { | |
| 22 | 14 | |
| 23 | 15 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java
| ... | ... | @@ -2,13 +2,14 @@ package cn.iocoder.yudao.module.pay.convert.order; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; |
| 5 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; | |
| 5 | 6 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; |
| 6 | 7 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; |
| 7 | 8 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; |
| 8 | 9 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; |
| 10 | +import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; | |
| 9 | 11 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 10 | 12 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; |
| 11 | -import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO; | |
| 12 | 13 | import org.mapstruct.Mapper; |
| 13 | 14 | import org.mapstruct.Mapping; |
| 14 | 15 | import org.mapstruct.factory.Mappers; |
| ... | ... | @@ -29,6 +30,8 @@ public interface PayOrderConvert { |
| 29 | 30 | |
| 30 | 31 | PayOrderRespVO convert(PayOrderDO bean); |
| 31 | 32 | |
| 33 | + PayOrderRespDTO convert2(PayOrderDO order); | |
| 34 | + | |
| 32 | 35 | PayOrderDetailsRespVO orderDetailConvert(PayOrderDO bean); |
| 33 | 36 | |
| 34 | 37 | PayOrderDetailsRespVO.PayOrderExtension orderDetailExtensionConvert(PayOrderExtensionDO bean); |
| ... | ... | @@ -86,18 +89,15 @@ public interface PayOrderConvert { |
| 86 | 89 | return payOrderExcelVO; |
| 87 | 90 | } |
| 88 | 91 | |
| 89 | - | |
| 90 | 92 | PayOrderDO convert(PayOrderCreateReqDTO bean); |
| 91 | 93 | |
| 92 | 94 | @Mapping(target = "id", ignore = true) |
| 93 | - PayOrderExtensionDO convert(PayOrderSubmitReqBO bean); | |
| 94 | - | |
| 95 | - PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqBO bean); | |
| 95 | + PayOrderExtensionDO convert(PayOrderSubmitReqVO bean, String userIp); | |
| 96 | 96 | |
| 97 | - PayOrderRespDTO convert2(PayOrderDO bean); | |
| 97 | + PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqVO reqVO); | |
| 98 | 98 | |
| 99 | - PayOrderSubmitReqBO convert(AppPayOrderSubmitReqVO bean, String userIp); | |
| 99 | + PayOrderSubmitRespVO convert(PayOrderUnifiedRespDTO bean); | |
| 100 | 100 | |
| 101 | - PayOrderSubmitReqBO convert(PayOrderSubmitReqVO bean, String userIp); | |
| 101 | + AppPayOrderSubmitRespVO convert3(PayOrderSubmitRespVO bean); | |
| 102 | 102 | |
| 103 | 103 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.service.order; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 3 | 5 | import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyDataDTO; |
| 6 | +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; | |
| 4 | 7 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO; |
| 5 | 8 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO; |
| 6 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 7 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 9 | +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO; | |
| 10 | +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; | |
| 8 | 11 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 9 | -import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; | |
| 10 | -import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO; | |
| 11 | -import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO; | |
| 12 | 12 | |
| 13 | 13 | import javax.validation.Valid; |
| 14 | +import javax.validation.constraints.NotEmpty; | |
| 14 | 15 | import java.util.Collection; |
| 15 | 16 | import java.util.List; |
| 16 | 17 | import java.util.Map; |
| ... | ... | @@ -81,10 +82,12 @@ public interface PayOrderService { |
| 81 | 82 | * 提交支付 |
| 82 | 83 | * 此时,会发起支付渠道的调用 |
| 83 | 84 | * |
| 84 | - * @param reqDTO 提交请求 | |
| 85 | + * @param reqVO 提交请求 | |
| 86 | + * @param userIp 提交 IP | |
| 85 | 87 | * @return 提交结果 |
| 86 | 88 | */ |
| 87 | - PayOrderSubmitRespBO submitPayOrder(@Valid PayOrderSubmitReqBO reqDTO); | |
| 89 | + PayOrderSubmitRespVO submitPayOrder(@Valid PayOrderSubmitReqVO reqVO, | |
| 90 | + @NotEmpty(message = "提交 IP 不能为空") String userIp); | |
| 88 | 91 | |
| 89 | 92 | /** |
| 90 | 93 | * 通知支付单成功 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
| ... | ... | @@ -12,10 +12,13 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 12 | 12 | import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyDataDTO; |
| 13 | 13 | import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO; |
| 14 | 14 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; |
| 15 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; | |
| 15 | 16 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; |
| 16 | 17 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; |
| 17 | 18 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO; |
| 18 | 19 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO; |
| 20 | +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO; | |
| 21 | +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; | |
| 19 | 22 | import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; |
| 20 | 23 | import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; |
| 21 | 24 | import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; |
| ... | ... | @@ -31,8 +34,6 @@ import cn.iocoder.yudao.module.pay.service.merchant.PayAppService; |
| 31 | 34 | import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService; |
| 32 | 35 | import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; |
| 33 | 36 | import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; |
| 34 | -import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO; | |
| 35 | -import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO; | |
| 36 | 37 | import lombok.extern.slf4j.Slf4j; |
| 37 | 38 | import org.springframework.stereotype.Service; |
| 38 | 39 | import org.springframework.transaction.annotation.Transactional; |
| ... | ... | @@ -126,22 +127,22 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 126 | 127 | } |
| 127 | 128 | |
| 128 | 129 | @Override |
| 129 | - public PayOrderSubmitRespBO submitPayOrder(PayOrderSubmitReqBO reqBO) { | |
| 130 | + public PayOrderSubmitRespVO submitPayOrder(PayOrderSubmitReqVO reqVO, String userIp) { | |
| 130 | 131 | // 1. 获得 PayOrderDO ,并校验其是否存在 |
| 131 | - PayOrderDO order = validatePayOrderCanSubmit(reqBO.getId()); | |
| 132 | + PayOrderDO order = validatePayOrderCanSubmit(reqVO.getId()); | |
| 132 | 133 | // 1.2 校验支付渠道是否有效 |
| 133 | - PayChannelDO channel = validatePayChannelCanSubmit(order.getAppId(), reqBO.getChannelCode()); | |
| 134 | + PayChannelDO channel = validatePayChannelCanSubmit(order.getAppId(), reqVO.getChannelCode()); | |
| 134 | 135 | PayClient client = payClientFactory.getPayClient(channel.getId()); |
| 135 | 136 | |
| 136 | 137 | // 2. 插入 PayOrderExtensionDO |
| 137 | - PayOrderExtensionDO orderExtension = PayOrderConvert.INSTANCE.convert(reqBO) | |
| 138 | + PayOrderExtensionDO orderExtension = PayOrderConvert.INSTANCE.convert(reqVO, userIp) | |
| 138 | 139 | .setOrderId(order.getId()).setNo(generateOrderExtensionNo()) |
| 139 | 140 | .setChannelId(channel.getId()).setChannelCode(channel.getCode()) |
| 140 | 141 | .setStatus(PayOrderStatusEnum.WAITING.getStatus()); |
| 141 | 142 | orderExtensionMapper.insert(orderExtension); |
| 142 | 143 | |
| 143 | 144 | // 3. 调用三方接口 |
| 144 | - PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqBO) | |
| 145 | + PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqVO) | |
| 145 | 146 | // 商户相关的字段 |
| 146 | 147 | .setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性! |
| 147 | 148 | .setSubject(order.getSubject()).setBody(order.getBody()) |
| ... | ... | @@ -152,10 +153,11 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 152 | 153 | CommonResult<?> unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO); |
| 153 | 154 | unifiedOrderResult.checkError(); |
| 154 | 155 | |
| 156 | + PayOrderUnifiedRespDTO xx = (PayOrderUnifiedRespDTO) unifiedOrderResult.getData(); | |
| 157 | + | |
| 155 | 158 | // TODO 轮询三方接口,是否已经支付的任务 |
| 156 | 159 | // 返回成功 |
| 157 | - return new PayOrderSubmitRespBO().setExtensionId(orderExtension.getId()) | |
| 158 | - .setInvokeResponse(unifiedOrderResult.getData()); | |
| 160 | + return PayOrderConvert.INSTANCE.convert(xx); | |
| 159 | 161 | } |
| 160 | 162 | |
| 161 | 163 | private PayOrderDO validatePayOrderCanSubmit(Long id) { | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/bo/PayOrderSubmitReqBO.java deleted
| 1 | -package cn.iocoder.yudao.module.pay.service.order.bo; | |
| 2 | - | |
| 3 | -import lombok.Data; | |
| 4 | -import lombok.experimental.Accessors; | |
| 5 | - | |
| 6 | -import javax.validation.constraints.NotEmpty; | |
| 7 | -import javax.validation.constraints.NotNull; | |
| 8 | -import java.io.Serializable; | |
| 9 | -import java.util.Map; | |
| 10 | - | |
| 11 | -/** | |
| 12 | - * 支付单提交 Request BO | |
| 13 | - */ | |
| 14 | -@Data | |
| 15 | -@Accessors(chain = true) | |
| 16 | -public class PayOrderSubmitReqBO implements Serializable { | |
| 17 | - | |
| 18 | - /** | |
| 19 | - * 支付单编号 | |
| 20 | - */ | |
| 21 | - @NotNull(message = "支付单编号不能为空") | |
| 22 | - private Long id; | |
| 23 | - | |
| 24 | - /** | |
| 25 | - * 支付渠道 | |
| 26 | - */ | |
| 27 | - @NotEmpty(message = "支付渠道不能为空") | |
| 28 | - private String channelCode; | |
| 29 | - | |
| 30 | - /** | |
| 31 | - * 用户 IP | |
| 32 | - */ | |
| 33 | - @NotEmpty(message = "用户 IP 不能为空") | |
| 34 | - private String userIp; | |
| 35 | - | |
| 36 | - /** | |
| 37 | - * 支付渠道的额外参数 | |
| 38 | - */ | |
| 39 | - private Map<String, String> channelExtras; | |
| 40 | - | |
| 41 | -} |
yudao-ui-admin/src/utils/constants.js
| ... | ... | @@ -151,6 +151,18 @@ export const PayChannelEnum = { |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | 153 | /** |
| 154 | + * 支付的展示模式每局 | |
| 155 | + */ | |
| 156 | +export const PayDisplayModeEnum = { | |
| 157 | + URL: { | |
| 158 | + "mode": "url", | |
| 159 | + }, | |
| 160 | + IFRAME: { | |
| 161 | + "mode": "iframe", | |
| 162 | + }, | |
| 163 | +} | |
| 164 | + | |
| 165 | +/** | |
| 154 | 166 | * 支付类型枚举 |
| 155 | 167 | */ |
| 156 | 168 | export const PayType = { | ... | ... |
yudao-ui-admin/src/views/pay/order/submit.vue
| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | </el-descriptions> |
| 13 | 13 | </el-card> |
| 14 | 14 | |
| 15 | - | |
| 16 | 15 | <!-- 支付选择框 --> |
| 17 | 16 | <el-card style="margin-top: 10px" v-loading="submitLoading" element-loading-text="提交支付中..."> |
| 18 | 17 | <!-- 支付宝 --> |
| ... | ... | @@ -42,12 +41,18 @@ |
| 42 | 41 | </div> |
| 43 | 42 | </el-card> |
| 44 | 43 | |
| 45 | - <!-- 支付二维码 --> | |
| 44 | + <!-- 展示形式:二维码 --> | |
| 46 | 45 | <el-dialog :title="qrCode.title" :visible.sync="qrCode.visible" width="350px" append-to-body |
| 47 | 46 | :close-on-press-escape="false"> |
| 48 | 47 | <qrcode-vue :value="qrCode.url" size="310" level="H" /> |
| 49 | 48 | </el-dialog> |
| 50 | 49 | |
| 50 | + <!-- 展示形式:iframe --> | |
| 51 | + <el-dialog :title="iframe.title" :visible.sync="iframe.visible" width="800px" height="800px" append-to-body | |
| 52 | + :close-on-press-escape="false"> | |
| 53 | + <iframe :src="iframe.url" width="100%" /> | |
| 54 | + </el-dialog> | |
| 55 | + | |
| 51 | 56 | <!-- 阿里支付 --> |
| 52 | 57 | <div ref="alipayWap" v-html="alipayHtml.value" /> |
| 53 | 58 | |
| ... | ... | @@ -57,7 +62,7 @@ |
| 57 | 62 | import QrcodeVue from 'qrcode.vue' |
| 58 | 63 | import { DICT_TYPE, getDictDatas } from "@/utils/dict"; |
| 59 | 64 | import { getOrder, submitOrder } from '@/api/pay/order'; |
| 60 | -import { PayChannelEnum, PayOrderStatusEnum } from "@/utils/constants"; | |
| 65 | +import {PayChannelEnum, PayDisplayModeEnum, PayOrderStatusEnum} from "@/utils/constants"; | |
| 61 | 66 | |
| 62 | 67 | export default { |
| 63 | 68 | name: "PayOrderSubmit", |
| ... | ... | @@ -83,11 +88,16 @@ export default { |
| 83 | 88 | mock: require("@/assets/images/pay/icon/mock.svg"), |
| 84 | 89 | }, |
| 85 | 90 | submitLoading: false, // 提交支付的 loading |
| 86 | - qrCode: { // 支付二维码 | |
| 91 | + qrCode: { // 展示形式:二维码 | |
| 87 | 92 | url: '', |
| 88 | 93 | title: '', |
| 89 | 94 | visible: false, |
| 90 | 95 | }, |
| 96 | + iframe: { // 展示形式:iframe | |
| 97 | + url: '', | |
| 98 | + title: '', | |
| 99 | + visible: false | |
| 100 | + }, | |
| 91 | 101 | interval: undefined, // 定时任务,轮询是否完成支付 |
| 92 | 102 | alipayHtml: '' // 阿里支付的 HTML |
| 93 | 103 | }; |
| ... | ... | @@ -146,21 +156,65 @@ export default { |
| 146 | 156 | this.submitLoading = true |
| 147 | 157 | submitOrder({ |
| 148 | 158 | id: this.id, |
| 149 | - channelCode: channelCode | |
| 159 | + channelCode: channelCode, | |
| 160 | + ...this.buildSubmitParam(channelCode) | |
| 150 | 161 | }).then(response => { |
| 151 | - const invokeResponse = response.data.invokeResponse | |
| 152 | - // 不同的支付,调用不同的策略 | |
| 153 | - if (channelCode === PayChannelEnum.ALIPAY_QR.code) { | |
| 154 | - this.submitAfterAlipayQr(invokeResponse) | |
| 155 | - } else if (channelCode === PayChannelEnum.ALIPAY_PC.code | |
| 156 | - || channelCode === PayChannelEnum.ALIPAY_WAP.code) { | |
| 157 | - this.submitAfterAlipayPc(invokeResponse) | |
| 162 | + const data = response.data | |
| 163 | + if (data.displayMode === 'iframe') { | |
| 164 | + this.displayIFrame(channelCode, data) | |
| 165 | + } else if (data.displayMode === 'url') { | |
| 166 | + this.displayUrl(channelCode, data) | |
| 158 | 167 | } |
| 168 | + // 不同的支付,调用不同的策略 | |
| 169 | + // if (channelCode === PayChannelEnum.ALIPAY_QR.code) { | |
| 170 | + // this.submitAfterAlipayQr(invokeResponse) | |
| 171 | + // } else if (channelCode === PayChannelEnum.ALIPAY_PC.code | |
| 172 | + // || channelCode === PayChannelEnum.ALIPAY_WAP.code) { | |
| 173 | + // this.submitAfterAlipayPc(invokeResponse) | |
| 174 | + // } | |
| 159 | 175 | |
| 160 | 176 | // 打开轮询任务 |
| 161 | 177 | this.createQueryInterval() |
| 162 | 178 | }) |
| 163 | 179 | }, |
| 180 | + /** 构建提交支付的额外参数 */ | |
| 181 | + buildSubmitParam(channelCode) { | |
| 182 | + // 支付宝网页支付时,有多种展示形态 | |
| 183 | + if (channelCode === PayChannelEnum.ALIPAY_PC.code) { | |
| 184 | + // 情况【前置模式】:将二维码前置到商户的订单确认页的模式。需要商户在自己的页面中以 iframe 方式请求支付宝页面。具体支持的枚举值有以下几种: | |
| 185 | + // 0:订单码-简约前置模式,对应 iframe 宽度不能小于 600px,高度不能小于 300px | |
| 186 | + // return { | |
| 187 | + // "channelExtras": { | |
| 188 | + // "qr_pay_mode": "0" | |
| 189 | + // } | |
| 190 | + // } | |
| 191 | + // 1:订单码-前置模式,对应iframe 宽度不能小于 300px,高度不能小于 600px | |
| 192 | + // return { | |
| 193 | + // "channelExtras": { | |
| 194 | + // "qr_pay_mode": "1" | |
| 195 | + // } | |
| 196 | + // } | |
| 197 | + // 3:订单码-迷你前置模式,对应 iframe 宽度不能小于 75px,高度不能小于 75px | |
| 198 | + // return { | |
| 199 | + // "channelExtras": { | |
| 200 | + // "qr_pay_mode": "3" | |
| 201 | + // } | |
| 202 | + // } | |
| 203 | + // 4:订单码-可定义宽度的嵌入式二维码,商户可根据需要设定二维码的大小 | |
| 204 | + // return { | |
| 205 | + // "channelExtras": { | |
| 206 | + // "qr_pay_mode": "2" | |
| 207 | + // } | |
| 208 | + // } | |
| 209 | + // 情况【跳转模式】:跳转模式下,用户的扫码界面是由支付宝生成的,不在商户的域名下。支持传入的枚举值有 | |
| 210 | + return { | |
| 211 | + "channelExtras": { | |
| 212 | + "qr_pay_mode": "2" | |
| 213 | + } | |
| 214 | + } | |
| 215 | + } | |
| 216 | + return {} | |
| 217 | + }, | |
| 164 | 218 | /** 提交支付后(支付宝扫码支付) */ |
| 165 | 219 | submitAfterAlipayQr(invokeResponse) { |
| 166 | 220 | this.qrCode = { |
| ... | ... | @@ -170,6 +224,19 @@ export default { |
| 170 | 224 | } |
| 171 | 225 | this.submitLoading = false |
| 172 | 226 | }, |
| 227 | + displayIFrame(channelCode, data) { | |
| 228 | + // this.iframe = { | |
| 229 | + // title: '支付窗口', | |
| 230 | + // url: data.displayContent, | |
| 231 | + // visible: true | |
| 232 | + // } | |
| 233 | + window.open(data.displayContent) | |
| 234 | + }, | |
| 235 | + /** 提交支付后,URL 的展示形式 */ | |
| 236 | + displayUrl(channelCode, data) { | |
| 237 | + window.open(data.displayContent) | |
| 238 | + this.submitLoading = false | |
| 239 | + }, | |
| 173 | 240 | /** 提交支付后(支付宝 PC 网站支付) */ |
| 174 | 241 | submitAfterAlipayPc(invokeResponse) { |
| 175 | 242 | // 渲染支付页面 |
| ... | ... | @@ -188,6 +255,9 @@ export default { |
| 188 | 255 | }, |
| 189 | 256 | /** 轮询查询任务 */ |
| 190 | 257 | createQueryInterval() { |
| 258 | + if (!this.interval) { | |
| 259 | + return | |
| 260 | + } | |
| 191 | 261 | this.interval = setInterval(() => { |
| 192 | 262 | getOrder(this.id).then(response => { |
| 193 | 263 | // 已支付 | ... | ... |