mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-27 01:32:03 +08:00
pay: 接入支付宝 PC 支付的跳转模式
This commit is contained in:
parent
df702e8d24
commit
b34801f303
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.dto.order;
|
package cn.iocoder.yudao.framework.pay.core.client.dto.order;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
import org.hibernate.validator.constraints.URL;
|
import org.hibernate.validator.constraints.URL;
|
||||||
@ -7,6 +8,7 @@ import org.hibernate.validator.constraints.URL;
|
|||||||
import javax.validation.constraints.DecimalMin;
|
import javax.validation.constraints.DecimalMin;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.awt.*;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -78,4 +80,13 @@ public class PayOrderUnifiedReqDTO {
|
|||||||
*/
|
*/
|
||||||
private Map<String, String> channelExtras;
|
private Map<String, String> channelExtras;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 展示模式
|
||||||
|
*
|
||||||
|
* 如果不传递,则每个支付渠道使用默认的方式
|
||||||
|
*
|
||||||
|
* 枚举 {@link PayDisplayModeEnum}
|
||||||
|
*/
|
||||||
|
private String displayMode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.framework.pay.core.client.dto.order;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一下单 Response DTO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PayOrderUnifiedRespDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 展示模式
|
||||||
|
*/
|
||||||
|
private String displayMode;
|
||||||
|
/**
|
||||||
|
* 展示内容
|
||||||
|
*/
|
||||||
|
private String displayContent;
|
||||||
|
|
||||||
|
}
|
@ -69,6 +69,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO 芋艿:后续抽取到工具类里
|
||||||
protected Double calculateAmount(Integer amount) {
|
protected Double calculateAmount(Integer amount) {
|
||||||
return amount / 100.0;
|
return amount / 100.0;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Pair;
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.http.Method;
|
import cn.hutool.http.Method;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
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.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.PayChannelEnum;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
|
||||||
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayApiException;
|
||||||
import com.alipay.api.domain.AlipayTradePagePayModel;
|
import com.alipay.api.domain.AlipayTradePagePayModel;
|
||||||
import com.alipay.api.request.AlipayTradePagePayRequest;
|
import com.alipay.api.request.AlipayTradePagePayRequest;
|
||||||
import com.alipay.api.response.AlipayTradePagePayResponse;
|
import com.alipay.api.response.AlipayTradePagePayResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝【PC网站支付】的 PayClient 实现类
|
* 支付宝【PC网站支付】的 PayClient 实现类
|
||||||
@ -28,35 +36,72 @@ public class AlipayPcPayClient extends AbstractAlipayClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<AlipayTradePagePayResponse> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
||||||
// 构建 AlipayTradePagePayModel 请求
|
// 1.1 构建 AlipayTradePagePayModel 请求
|
||||||
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
|
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
|
||||||
// 构建 AlipayTradePagePayRequest
|
// ① 通用的参数
|
||||||
|
model.setOutTradeNo(reqDTO.getMerchantOrderId());
|
||||||
|
model.setSubject(reqDTO.getSubject());
|
||||||
|
model.setTotalAmount(String.valueOf(calculateAmount(reqDTO.getAmount())));
|
||||||
|
model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 销售产品码. 目前电脑支付场景下仅支持 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());
|
||||||
|
|
||||||
|
// 1.2 构建 AlipayTradePagePayRequest 请求
|
||||||
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
|
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
|
||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
JSONObject bizContent = new JSONObject();
|
|
||||||
// 参数说明可查看: https://opendocs.alipay.com/open/028r8t?scene=22
|
|
||||||
bizContent.put("out_trade_no", reqDTO.getMerchantOrderId());
|
|
||||||
bizContent.put("subject", reqDTO.getSubject());
|
|
||||||
bizContent.put("total_amount", calculateAmount(reqDTO.getAmount()));
|
|
||||||
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); // 销售产品码. 目前电脑支付场景下仅支持 FAST_INSTANT_TRADE_PAY
|
|
||||||
// PC扫码支付的方式:支持前置模式和跳转模式。4: 订单码-可定义宽度的嵌入式二维码
|
|
||||||
// bizContent.put("qr_pay_mode", "4");
|
|
||||||
// 自定义二维码宽度
|
|
||||||
// bizContent.put("qrcode_width", "150");
|
|
||||||
request.setBizContent(bizContent.toJSONString());
|
|
||||||
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
||||||
request.setReturnUrl("");
|
request.setReturnUrl(""); // TODO 芋艿,待搞
|
||||||
// 执行请求
|
|
||||||
|
// 2.1 执行请求
|
||||||
AlipayTradePagePayResponse response;
|
AlipayTradePagePayResponse response;
|
||||||
try {
|
try {
|
||||||
|
if (Objects.equals(displayMode, PayDisplayModeEnum.FORM.getMode())) {
|
||||||
|
response = client.pageExecute(request, Method.POST.name()); // 需要特殊使用 POST 请求
|
||||||
|
} else {
|
||||||
response = client.pageExecute(request, Method.GET.name());
|
response = client.pageExecute(request, Method.GET.name());
|
||||||
|
}
|
||||||
} catch (AlipayApiException e) {
|
} catch (AlipayApiException e) {
|
||||||
log.error("[unifiedOrder][request({}) 发起支付失败]", JsonUtils.toJsonString(reqDTO), e);
|
log.error("[unifiedOrder][request({}) 发起支付失败]", JsonUtils.toJsonString(reqDTO), e);
|
||||||
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
|
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
|
||||||
}
|
}
|
||||||
|
// 1. form
|
||||||
|
// 2. url
|
||||||
|
// 3. code
|
||||||
|
// 4. code url
|
||||||
|
|
||||||
|
// 2.2 处理结果
|
||||||
System.out.println(response.getBody());
|
System.out.println(response.getBody());
|
||||||
|
PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO()
|
||||||
|
.setDisplayMode(displayMode).setDisplayContent(response.getBody());
|
||||||
// 响应为表单格式,前端可嵌入响应的页面或关闭当前支付窗口
|
// 响应为表单格式,前端可嵌入响应的页面或关闭当前支付窗口
|
||||||
return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000") ,response.getMsg(), response, codeMapping);
|
return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"),
|
||||||
|
response.getMsg(), respDTO, codeMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得最终的支付 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 跳转
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package cn.iocoder.yudao.framework.pay.core.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付 UI 展示模式
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum PayDisplayModeEnum {
|
||||||
|
|
||||||
|
URL("url"), // Redirect 跳转链接的方式
|
||||||
|
IFRAME("iframe"), // IFrame 内嵌链接的方式
|
||||||
|
FORM("form"), // HTML 表单提交
|
||||||
|
QR_CODE("qr_code"), // 二维码的文字内容
|
||||||
|
QR_CODE_URL("qr_code_url"), // 二维码的图片链接
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 展示模式
|
||||||
|
*/
|
||||||
|
private final String mode;
|
||||||
|
|
||||||
|
}
|
@ -2,9 +2,13 @@ package cn.iocoder.yudao.module.pay.controller.admin.order;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
|
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||||
@ -14,16 +18,9 @@ import cn.iocoder.yudao.module.pay.service.merchant.PayAppService;
|
|||||||
import cn.iocoder.yudao.module.pay.service.merchant.PayMerchantService;
|
import cn.iocoder.yudao.module.pay.service.merchant.PayMerchantService;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
|
import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
|
||||||
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -94,10 +91,9 @@ public class PayOrderController {
|
|||||||
|
|
||||||
@PostMapping("/submit")
|
@PostMapping("/submit")
|
||||||
@Operation(summary = "提交支付订单")
|
@Operation(summary = "提交支付订单")
|
||||||
public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) {
|
public CommonResult<PayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) {
|
||||||
PayOrderSubmitRespBO respDTO = payOrderService.submitPayOrder(
|
PayOrderSubmitRespVO respVO = payOrderService.submitPayOrder(reqVO, getClientIP());
|
||||||
PayOrderConvert.INSTANCE.convert(reqVO, getClientIP()));
|
return success(respVO);
|
||||||
return success(new AppPayOrderSubmitRespVO(respDTO.getInvokeResponse()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
|
@ -6,11 +6,11 @@ import lombok.experimental.Accessors;
|
|||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.awt.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 支付订单提交 Request VO")
|
@Schema(description = "管理后台 - 支付订单提交 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
|
||||||
public class PayOrderSubmitReqVO {
|
public class PayOrderSubmitReqVO {
|
||||||
|
|
||||||
@Schema(description = "支付单编号", required = true, example = "1024")
|
@Schema(description = "支付单编号", required = true, example = "1024")
|
||||||
@ -24,4 +24,6 @@ public class PayOrderSubmitReqVO {
|
|||||||
@Schema(description = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数")
|
@Schema(description = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数")
|
||||||
private Map<String, String> channelExtras;
|
private Map<String, String> channelExtras;
|
||||||
|
|
||||||
|
@Schema(description = "展示模式", example = "url") // 参见 {@link PayDisplayModeEnum} 枚举。如果不传递,则每个支付渠道使用默认的方式
|
||||||
|
private String displayMode;
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,12 @@ import lombok.experimental.Accessors;
|
|||||||
|
|
||||||
@Schema(description = "管理后台 - 支付订单提交 Response VO")
|
@Schema(description = "管理后台 - 支付订单提交 Response VO")
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class PayOrderSubmitRespVO {
|
public class PayOrderSubmitRespVO {
|
||||||
|
|
||||||
/**
|
@Schema(description = "展示模式", required = true, example = "url") // 参见 PayDisplayModeEnum 枚举
|
||||||
* 调用支付渠道的响应结果
|
private String displayMode;
|
||||||
*/
|
|
||||||
private Object invokeResponse;
|
@Schema(description = "展示内容", required = true)
|
||||||
|
private String displayContent;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.pay.controller.app.order;
|
package cn.iocoder.yudao.module.pay.controller.app.order;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -33,9 +33,8 @@ public class AppPayOrderController {
|
|||||||
@PostMapping("/submit")
|
@PostMapping("/submit")
|
||||||
@Operation(summary = "提交支付订单")
|
@Operation(summary = "提交支付订单")
|
||||||
public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) {
|
public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) {
|
||||||
PayOrderSubmitRespBO respDTO = orderService.submitPayOrder(
|
PayOrderSubmitRespVO respVO = orderService.submitPayOrder(reqVO, getClientIP());
|
||||||
PayOrderConvert.INSTANCE.convert(reqVO, getClientIP()));
|
return success(PayOrderConvert.INSTANCE.convert3(respVO));
|
||||||
return success(new AppPayOrderSubmitRespVO(respDTO.getInvokeResponse()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.pay.controller.app.order.vo;
|
package cn.iocoder.yudao.module.pay.controller.app.order.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
@ -10,18 +11,5 @@ import java.util.Map;
|
|||||||
|
|
||||||
@Schema(description = "用户 APP - 支付订单提交 Request VO")
|
@Schema(description = "用户 APP - 支付订单提交 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
public class AppPayOrderSubmitReqVO extends PayOrderSubmitReqVO {
|
||||||
public class AppPayOrderSubmitReqVO {
|
|
||||||
|
|
||||||
@Schema(description = "支付单编号", required = true, example = "1024")
|
|
||||||
@NotNull(message = "支付单编号不能为空")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@Schema(description = "支付渠道", required = true, example = "wx_pub")
|
|
||||||
@NotEmpty(message = "支付渠道不能为空")
|
|
||||||
private String channelCode;
|
|
||||||
|
|
||||||
@Schema(description = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数")
|
|
||||||
private Map<String, String> channelExtras;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.pay.controller.app.order.vo;
|
package cn.iocoder.yudao.module.pay.controller.app.order.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
@ -9,15 +10,6 @@ import lombok.experimental.Accessors;
|
|||||||
|
|
||||||
@Schema(description = "用户 APP - 支付订单提交 Response VO")
|
@Schema(description = "用户 APP - 支付订单提交 Response VO")
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
public class AppPayOrderSubmitRespVO extends PayOrderSubmitRespVO {
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class AppPayOrderSubmitRespVO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 调用支付渠道的响应结果
|
|
||||||
*/
|
|
||||||
private Object invokeResponse;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,14 @@ package cn.iocoder.yudao.module.pay.convert.order;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
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.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
|
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO;
|
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
@ -29,6 +30,8 @@ public interface PayOrderConvert {
|
|||||||
|
|
||||||
PayOrderRespVO convert(PayOrderDO bean);
|
PayOrderRespVO convert(PayOrderDO bean);
|
||||||
|
|
||||||
|
PayOrderRespDTO convert2(PayOrderDO order);
|
||||||
|
|
||||||
PayOrderDetailsRespVO orderDetailConvert(PayOrderDO bean);
|
PayOrderDetailsRespVO orderDetailConvert(PayOrderDO bean);
|
||||||
|
|
||||||
PayOrderDetailsRespVO.PayOrderExtension orderDetailExtensionConvert(PayOrderExtensionDO bean);
|
PayOrderDetailsRespVO.PayOrderExtension orderDetailExtensionConvert(PayOrderExtensionDO bean);
|
||||||
@ -86,18 +89,15 @@ public interface PayOrderConvert {
|
|||||||
return payOrderExcelVO;
|
return payOrderExcelVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PayOrderDO convert(PayOrderCreateReqDTO bean);
|
PayOrderDO convert(PayOrderCreateReqDTO bean);
|
||||||
|
|
||||||
@Mapping(target = "id", ignore = true)
|
@Mapping(target = "id", ignore = true)
|
||||||
PayOrderExtensionDO convert(PayOrderSubmitReqBO bean);
|
PayOrderExtensionDO convert(PayOrderSubmitReqVO bean, String userIp);
|
||||||
|
|
||||||
PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqBO bean);
|
PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqVO reqVO);
|
||||||
|
|
||||||
PayOrderRespDTO convert2(PayOrderDO bean);
|
PayOrderSubmitRespVO convert(PayOrderUnifiedRespDTO bean);
|
||||||
|
|
||||||
PayOrderSubmitReqBO convert(AppPayOrderSubmitReqVO bean, String userIp);
|
AppPayOrderSubmitRespVO convert3(PayOrderSubmitRespVO bean);
|
||||||
|
|
||||||
PayOrderSubmitReqBO convert(PayOrderSubmitReqVO bean, String userIp);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
package cn.iocoder.yudao.module.pay.service.order;
|
package cn.iocoder.yudao.module.pay.service.order;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyDataDTO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyDataDTO;
|
||||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO;
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO;
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -81,10 +82,12 @@ public interface PayOrderService {
|
|||||||
* 提交支付
|
* 提交支付
|
||||||
* 此时,会发起支付渠道的调用
|
* 此时,会发起支付渠道的调用
|
||||||
*
|
*
|
||||||
* @param reqDTO 提交请求
|
* @param reqVO 提交请求
|
||||||
|
* @param userIp 提交 IP
|
||||||
* @return 提交结果
|
* @return 提交结果
|
||||||
*/
|
*/
|
||||||
PayOrderSubmitRespBO submitPayOrder(@Valid PayOrderSubmitReqBO reqDTO);
|
PayOrderSubmitRespVO submitPayOrder(@Valid PayOrderSubmitReqVO reqVO,
|
||||||
|
@NotEmpty(message = "提交 IP 不能为空") String userIp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知支付单成功
|
* 通知支付单成功
|
||||||
|
@ -12,10 +12,13 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
|||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyDataDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyDataDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
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.tenant.core.util.TenantUtils;
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
|
||||||
@ -31,8 +34,6 @@ import cn.iocoder.yudao.module.pay.service.merchant.PayAppService;
|
|||||||
import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService;
|
import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService;
|
||||||
import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
|
import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
|
||||||
import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO;
|
|
||||||
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -126,22 +127,22 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayOrderSubmitRespBO submitPayOrder(PayOrderSubmitReqBO reqBO) {
|
public PayOrderSubmitRespVO submitPayOrder(PayOrderSubmitReqVO reqVO, String userIp) {
|
||||||
// 1. 获得 PayOrderDO ,并校验其是否存在
|
// 1. 获得 PayOrderDO ,并校验其是否存在
|
||||||
PayOrderDO order = validatePayOrderCanSubmit(reqBO.getId());
|
PayOrderDO order = validatePayOrderCanSubmit(reqVO.getId());
|
||||||
// 1.2 校验支付渠道是否有效
|
// 1.2 校验支付渠道是否有效
|
||||||
PayChannelDO channel = validatePayChannelCanSubmit(order.getAppId(), reqBO.getChannelCode());
|
PayChannelDO channel = validatePayChannelCanSubmit(order.getAppId(), reqVO.getChannelCode());
|
||||||
PayClient client = payClientFactory.getPayClient(channel.getId());
|
PayClient client = payClientFactory.getPayClient(channel.getId());
|
||||||
|
|
||||||
// 2. 插入 PayOrderExtensionDO
|
// 2. 插入 PayOrderExtensionDO
|
||||||
PayOrderExtensionDO orderExtension = PayOrderConvert.INSTANCE.convert(reqBO)
|
PayOrderExtensionDO orderExtension = PayOrderConvert.INSTANCE.convert(reqVO, userIp)
|
||||||
.setOrderId(order.getId()).setNo(generateOrderExtensionNo())
|
.setOrderId(order.getId()).setNo(generateOrderExtensionNo())
|
||||||
.setChannelId(channel.getId()).setChannelCode(channel.getCode())
|
.setChannelId(channel.getId()).setChannelCode(channel.getCode())
|
||||||
.setStatus(PayOrderStatusEnum.WAITING.getStatus());
|
.setStatus(PayOrderStatusEnum.WAITING.getStatus());
|
||||||
orderExtensionMapper.insert(orderExtension);
|
orderExtensionMapper.insert(orderExtension);
|
||||||
|
|
||||||
// 3. 调用三方接口
|
// 3. 调用三方接口
|
||||||
PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqBO)
|
PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqVO)
|
||||||
// 商户相关的字段
|
// 商户相关的字段
|
||||||
.setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性!
|
.setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性!
|
||||||
.setSubject(order.getSubject()).setBody(order.getBody())
|
.setSubject(order.getSubject()).setBody(order.getBody())
|
||||||
@ -152,10 +153,11 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|||||||
CommonResult<?> unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO);
|
CommonResult<?> unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO);
|
||||||
unifiedOrderResult.checkError();
|
unifiedOrderResult.checkError();
|
||||||
|
|
||||||
|
PayOrderUnifiedRespDTO xx = (PayOrderUnifiedRespDTO) unifiedOrderResult.getData();
|
||||||
|
|
||||||
// TODO 轮询三方接口,是否已经支付的任务
|
// TODO 轮询三方接口,是否已经支付的任务
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return new PayOrderSubmitRespBO().setExtensionId(orderExtension.getId())
|
return PayOrderConvert.INSTANCE.convert(xx);
|
||||||
.setInvokeResponse(unifiedOrderResult.getData());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PayOrderDO validatePayOrderCanSubmit(Long id) {
|
private PayOrderDO validatePayOrderCanSubmit(Long id) {
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.pay.service.order.bo;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付单提交 Request BO
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class PayOrderSubmitReqBO implements Serializable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付单编号
|
|
||||||
*/
|
|
||||||
@NotNull(message = "支付单编号不能为空")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付渠道
|
|
||||||
*/
|
|
||||||
@NotEmpty(message = "支付渠道不能为空")
|
|
||||||
private String channelCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户 IP
|
|
||||||
*/
|
|
||||||
@NotEmpty(message = "用户 IP 不能为空")
|
|
||||||
private String userIp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付渠道的额外参数
|
|
||||||
*/
|
|
||||||
private Map<String, String> channelExtras;
|
|
||||||
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.pay.service.order.bo;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付单提交 Response BO
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class PayOrderSubmitRespBO implements Serializable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付拓展单的编号
|
|
||||||
*/
|
|
||||||
private Long extensionId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 调用支付渠道的响应结果
|
|
||||||
*/
|
|
||||||
private Object invokeResponse;
|
|
||||||
|
|
||||||
}
|
|
@ -150,6 +150,18 @@ export const PayChannelEnum = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付的展示模式每局
|
||||||
|
*/
|
||||||
|
export const PayDisplayModeEnum = {
|
||||||
|
URL: {
|
||||||
|
"mode": "url",
|
||||||
|
},
|
||||||
|
IFRAME: {
|
||||||
|
"mode": "iframe",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付类型枚举
|
* 支付类型枚举
|
||||||
*/
|
*/
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
|
||||||
<!-- 支付选择框 -->
|
<!-- 支付选择框 -->
|
||||||
<el-card style="margin-top: 10px" v-loading="submitLoading" element-loading-text="提交支付中...">
|
<el-card style="margin-top: 10px" v-loading="submitLoading" element-loading-text="提交支付中...">
|
||||||
<!-- 支付宝 -->
|
<!-- 支付宝 -->
|
||||||
@ -42,12 +41,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 支付二维码 -->
|
<!-- 展示形式:二维码 -->
|
||||||
<el-dialog :title="qrCode.title" :visible.sync="qrCode.visible" width="350px" append-to-body
|
<el-dialog :title="qrCode.title" :visible.sync="qrCode.visible" width="350px" append-to-body
|
||||||
:close-on-press-escape="false">
|
:close-on-press-escape="false">
|
||||||
<qrcode-vue :value="qrCode.url" size="310" level="H" />
|
<qrcode-vue :value="qrCode.url" size="310" level="H" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 展示形式:iframe -->
|
||||||
|
<el-dialog :title="iframe.title" :visible.sync="iframe.visible" width="800px" height="800px" append-to-body
|
||||||
|
:close-on-press-escape="false">
|
||||||
|
<iframe :src="iframe.url" width="100%" />
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 阿里支付 -->
|
<!-- 阿里支付 -->
|
||||||
<div ref="alipayWap" v-html="alipayHtml.value" />
|
<div ref="alipayWap" v-html="alipayHtml.value" />
|
||||||
|
|
||||||
@ -57,7 +62,7 @@
|
|||||||
import QrcodeVue from 'qrcode.vue'
|
import QrcodeVue from 'qrcode.vue'
|
||||||
import { DICT_TYPE, getDictDatas } from "@/utils/dict";
|
import { DICT_TYPE, getDictDatas } from "@/utils/dict";
|
||||||
import { getOrder, submitOrder } from '@/api/pay/order';
|
import { getOrder, submitOrder } from '@/api/pay/order';
|
||||||
import { PayChannelEnum, PayOrderStatusEnum } from "@/utils/constants";
|
import {PayChannelEnum, PayDisplayModeEnum, PayOrderStatusEnum} from "@/utils/constants";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PayOrderSubmit",
|
name: "PayOrderSubmit",
|
||||||
@ -83,11 +88,16 @@ export default {
|
|||||||
mock: require("@/assets/images/pay/icon/mock.svg"),
|
mock: require("@/assets/images/pay/icon/mock.svg"),
|
||||||
},
|
},
|
||||||
submitLoading: false, // 提交支付的 loading
|
submitLoading: false, // 提交支付的 loading
|
||||||
qrCode: { // 支付二维码
|
qrCode: { // 展示形式:二维码
|
||||||
url: '',
|
url: '',
|
||||||
title: '',
|
title: '',
|
||||||
visible: false,
|
visible: false,
|
||||||
},
|
},
|
||||||
|
iframe: { // 展示形式:iframe
|
||||||
|
url: '',
|
||||||
|
title: '',
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
interval: undefined, // 定时任务,轮询是否完成支付
|
interval: undefined, // 定时任务,轮询是否完成支付
|
||||||
alipayHtml: '' // 阿里支付的 HTML
|
alipayHtml: '' // 阿里支付的 HTML
|
||||||
};
|
};
|
||||||
@ -146,21 +156,65 @@ export default {
|
|||||||
this.submitLoading = true
|
this.submitLoading = true
|
||||||
submitOrder({
|
submitOrder({
|
||||||
id: this.id,
|
id: this.id,
|
||||||
channelCode: channelCode
|
channelCode: channelCode,
|
||||||
|
...this.buildSubmitParam(channelCode)
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
const invokeResponse = response.data.invokeResponse
|
const data = response.data
|
||||||
// 不同的支付,调用不同的策略
|
if (data.displayMode === 'iframe') {
|
||||||
if (channelCode === PayChannelEnum.ALIPAY_QR.code) {
|
this.displayIFrame(channelCode, data)
|
||||||
this.submitAfterAlipayQr(invokeResponse)
|
} else if (data.displayMode === 'url') {
|
||||||
} else if (channelCode === PayChannelEnum.ALIPAY_PC.code
|
this.displayUrl(channelCode, data)
|
||||||
|| channelCode === PayChannelEnum.ALIPAY_WAP.code) {
|
|
||||||
this.submitAfterAlipayPc(invokeResponse)
|
|
||||||
}
|
}
|
||||||
|
// 不同的支付,调用不同的策略
|
||||||
|
// if (channelCode === PayChannelEnum.ALIPAY_QR.code) {
|
||||||
|
// this.submitAfterAlipayQr(invokeResponse)
|
||||||
|
// } else if (channelCode === PayChannelEnum.ALIPAY_PC.code
|
||||||
|
// || channelCode === PayChannelEnum.ALIPAY_WAP.code) {
|
||||||
|
// this.submitAfterAlipayPc(invokeResponse)
|
||||||
|
// }
|
||||||
|
|
||||||
// 打开轮询任务
|
// 打开轮询任务
|
||||||
this.createQueryInterval()
|
this.createQueryInterval()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
/** 构建提交支付的额外参数 */
|
||||||
|
buildSubmitParam(channelCode) {
|
||||||
|
// 支付宝网页支付时,有多种展示形态
|
||||||
|
if (channelCode === PayChannelEnum.ALIPAY_PC.code) {
|
||||||
|
// 情况【前置模式】:将二维码前置到商户的订单确认页的模式。需要商户在自己的页面中以 iframe 方式请求支付宝页面。具体支持的枚举值有以下几种:
|
||||||
|
// 0:订单码-简约前置模式,对应 iframe 宽度不能小于 600px,高度不能小于 300px
|
||||||
|
// return {
|
||||||
|
// "channelExtras": {
|
||||||
|
// "qr_pay_mode": "0"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// 1:订单码-前置模式,对应iframe 宽度不能小于 300px,高度不能小于 600px
|
||||||
|
// return {
|
||||||
|
// "channelExtras": {
|
||||||
|
// "qr_pay_mode": "1"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// 3:订单码-迷你前置模式,对应 iframe 宽度不能小于 75px,高度不能小于 75px
|
||||||
|
// return {
|
||||||
|
// "channelExtras": {
|
||||||
|
// "qr_pay_mode": "3"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// 4:订单码-可定义宽度的嵌入式二维码,商户可根据需要设定二维码的大小
|
||||||
|
// return {
|
||||||
|
// "channelExtras": {
|
||||||
|
// "qr_pay_mode": "2"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// 情况【跳转模式】:跳转模式下,用户的扫码界面是由支付宝生成的,不在商户的域名下。支持传入的枚举值有
|
||||||
|
return {
|
||||||
|
"channelExtras": {
|
||||||
|
"qr_pay_mode": "2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
},
|
||||||
/** 提交支付后(支付宝扫码支付) */
|
/** 提交支付后(支付宝扫码支付) */
|
||||||
submitAfterAlipayQr(invokeResponse) {
|
submitAfterAlipayQr(invokeResponse) {
|
||||||
this.qrCode = {
|
this.qrCode = {
|
||||||
@ -170,6 +224,19 @@ export default {
|
|||||||
}
|
}
|
||||||
this.submitLoading = false
|
this.submitLoading = false
|
||||||
},
|
},
|
||||||
|
displayIFrame(channelCode, data) {
|
||||||
|
// this.iframe = {
|
||||||
|
// title: '支付窗口',
|
||||||
|
// url: data.displayContent,
|
||||||
|
// visible: true
|
||||||
|
// }
|
||||||
|
window.open(data.displayContent)
|
||||||
|
},
|
||||||
|
/** 提交支付后,URL 的展示形式 */
|
||||||
|
displayUrl(channelCode, data) {
|
||||||
|
window.open(data.displayContent)
|
||||||
|
this.submitLoading = false
|
||||||
|
},
|
||||||
/** 提交支付后(支付宝 PC 网站支付) */
|
/** 提交支付后(支付宝 PC 网站支付) */
|
||||||
submitAfterAlipayPc(invokeResponse) {
|
submitAfterAlipayPc(invokeResponse) {
|
||||||
// 渲染支付页面
|
// 渲染支付页面
|
||||||
@ -188,6 +255,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 轮询查询任务 */
|
/** 轮询查询任务 */
|
||||||
createQueryInterval() {
|
createQueryInterval() {
|
||||||
|
if (!this.interval) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.interval = setInterval(() => {
|
this.interval = setInterval(() => {
|
||||||
getOrder(this.id).then(response => {
|
getOrder(this.id).then(response => {
|
||||||
// 已支付
|
// 已支付
|
||||||
|
Loading…
Reference in New Issue
Block a user