mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-23 07:41:53 +08:00
pay: 重构支付客户端,移除 PayCommonResult 累
This commit is contained in:
parent
8e1be01451
commit
2093c3bdb5
@ -1,33 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将 API 的错误码,转换为通用的错误码
|
|
||||||
*
|
|
||||||
* @see PayCommonResult
|
|
||||||
* @see PayFrameworkErrorCodeConstants
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public abstract class AbstractPayCodeMapping {
|
|
||||||
|
|
||||||
public final ErrorCode apply(String apiCode, String apiMsg) {
|
|
||||||
if (apiCode == null) {
|
|
||||||
log.error("[apply][API 错误码为空,请排查]");
|
|
||||||
return PayFrameworkErrorCodeConstants.EXCEPTION;
|
|
||||||
}
|
|
||||||
ErrorCode errorCode = this.apply0(apiCode, apiMsg);
|
|
||||||
if (errorCode == null) {
|
|
||||||
log.error("[apply][API 错误码({}) 错误提示({}) 无法匹配]", apiCode, apiMsg);
|
|
||||||
return PayFrameworkErrorCodeConstants.PAY_UNKNOWN;
|
|
||||||
}
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract ErrorCode apply0(String apiCode, String apiMsg);
|
|
||||||
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyDataDTO;
|
|||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyDTO;
|
||||||
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.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,7 +28,7 @@ public interface PayClient {
|
|||||||
* @param reqDTO 下单信息
|
* @param reqDTO 下单信息
|
||||||
* @return 各支付渠道的返回结果
|
* @return 各支付渠道的返回结果
|
||||||
*/
|
*/
|
||||||
PayCommonResult<?> unifiedOrder(PayOrderUnifiedReqDTO reqDTO);
|
PayOrderUnifiedRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析支付单的通知结果
|
* 解析支付单的通知结果
|
||||||
@ -44,7 +44,7 @@ public interface PayClient {
|
|||||||
* @param reqDTO 统一退款请求信息
|
* @param reqDTO 统一退款请求信息
|
||||||
* @return 各支付渠道的统一返回结果
|
* @return 各支付渠道的统一返回结果
|
||||||
*/
|
*/
|
||||||
PayCommonResult<PayRefundUnifiedRespDTO> unifiedRefund(PayRefundUnifiedReqDTO reqDTO);
|
PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析支付退款通知数据
|
* 解析支付退款通知数据
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client;
|
|
||||||
|
|
||||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
|
||||||
import cn.hutool.core.lang.Assert;
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付的 CommonResult 拓展类
|
|
||||||
*
|
|
||||||
* 考虑到不同的平台,返回的 code 和 msg 是不同的,所以统一额外返回 {@link #apiCode} 和 {@link #apiMsg} 字段
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class PayCommonResult<T> extends CommonResult<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API 返回错误码
|
|
||||||
*
|
|
||||||
* 由于第三方的错误码可能是字符串,所以使用 String 类型
|
|
||||||
*/
|
|
||||||
private String apiCode;
|
|
||||||
/**
|
|
||||||
* API 返回提示
|
|
||||||
*/
|
|
||||||
private String apiMsg;
|
|
||||||
|
|
||||||
private PayCommonResult() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> PayCommonResult<T> build(String apiCode, String apiMsg, T data, AbstractPayCodeMapping codeMapping) {
|
|
||||||
Assert.notNull(codeMapping, "参数 codeMapping 不能为空");
|
|
||||||
PayCommonResult<T> result = new PayCommonResult<T>().setApiCode(apiCode).setApiMsg(apiMsg);
|
|
||||||
result.setData(data);
|
|
||||||
// 翻译错误码
|
|
||||||
if (codeMapping != null) {
|
|
||||||
ErrorCode errorCode = codeMapping.apply(apiCode, apiMsg);
|
|
||||||
result.setCode(errorCode.getCode()).setMsg(errorCode.getMsg());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> PayCommonResult<T> error(Throwable ex) {
|
|
||||||
PayCommonResult<T> result = new PayCommonResult<>();
|
|
||||||
result.setCode(PayFrameworkErrorCodeConstants.EXCEPTION.getCode());
|
|
||||||
result.setMsg(ExceptionUtil.getRootCauseMessage(ex));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,25 +1,22 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl;
|
package cn.iocoder.yudao.framework.pay.core.client.impl;
|
||||||
|
|
||||||
import cn.hutool.core.date.DatePattern;
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
||||||
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.client.dto.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import com.alipay.api.AlipayResponse;import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.validation.Validation;
|
import javax.validation.Validation;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_MS_FORMATTER;
|
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_MS_FORMATTER;
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||||
|
import static cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants.PAY_EXCEPTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付客户端的抽象类,提供模板方法,减少子类的冗余代码
|
* 支付客户端的抽象类,提供模板方法,减少子类的冗余代码
|
||||||
@ -37,19 +34,14 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||||||
* 渠道编码
|
* 渠道编码
|
||||||
*/
|
*/
|
||||||
private final String channelCode;
|
private final String channelCode;
|
||||||
/**
|
|
||||||
* 错误码枚举类
|
|
||||||
*/
|
|
||||||
protected AbstractPayCodeMapping codeMapping;
|
|
||||||
/**
|
/**
|
||||||
* 支付配置
|
* 支付配置
|
||||||
*/
|
*/
|
||||||
protected Config config;
|
protected Config config;
|
||||||
|
|
||||||
public AbstractPayClient(Long channelId, String channelCode, Config config, AbstractPayCodeMapping codeMapping) {
|
public AbstractPayClient(Long channelId, String channelCode, Config config) {
|
||||||
this.channelId = channelId;
|
this.channelId = channelId;
|
||||||
this.channelCode = channelCode;
|
this.channelCode = channelCode;
|
||||||
this.codeMapping = codeMapping;
|
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,41 +75,54 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final PayCommonResult<?> unifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public final PayOrderUnifiedRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
||||||
Validation.buildDefaultValidatorFactory().getValidator().validate(reqDTO);
|
Validation.buildDefaultValidatorFactory().getValidator().validate(reqDTO);
|
||||||
// 执行短信发送
|
// 执行短信发送
|
||||||
PayCommonResult<?> result;
|
PayOrderUnifiedRespDTO result;
|
||||||
try {
|
try {
|
||||||
result = doUnifiedOrder(reqDTO);
|
result = doUnifiedOrder(reqDTO);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
// 打印异常日志
|
// 打印异常日志
|
||||||
log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), ex);
|
log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), ex);
|
||||||
// 封装返回
|
throw buildException(ex);
|
||||||
return PayCommonResult.error(ex);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract PayCommonResult<?> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO)
|
protected abstract PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO)
|
||||||
throws Throwable;
|
throws Throwable;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<PayRefundUnifiedRespDTO> unifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
public PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||||
PayCommonResult<PayRefundUnifiedRespDTO> resp;
|
PayRefundUnifiedRespDTO resp;
|
||||||
try {
|
try {
|
||||||
resp = doUnifiedRefund(reqDTO);
|
resp = doUnifiedRefund(reqDTO);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
// 记录异常日志
|
// 记录异常日志
|
||||||
log.error("[unifiedRefund][request({}) 发起退款失败]", toJsonString(reqDTO), ex);
|
log.error("[unifiedRefund][request({}) 发起退款失败]", toJsonString(reqDTO), ex);
|
||||||
resp = PayCommonResult.error(ex);
|
throw buildException(ex);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
|
protected abstract PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
|
||||||
|
|
||||||
// ========== 各种工具方法 ==========
|
// ========== 各种工具方法 ==========
|
||||||
|
|
||||||
|
private RuntimeException buildException(Throwable ex) {
|
||||||
|
if (ex instanceof RuntimeException) {
|
||||||
|
return (RuntimeException) ex;
|
||||||
|
}
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void validateSuccess(AlipayResponse response) {
|
||||||
|
if (response.isSuccess()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw exception0(PAY_EXCEPTION.getCode(), response.getSubMsg());
|
||||||
|
}
|
||||||
|
|
||||||
protected String formatAmount(Integer amount) {
|
protected String formatAmount(Integer amount) {
|
||||||
return String.valueOf(amount / 100.0);
|
return String.valueOf(amount / 100.0);
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,9 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
||||||
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.PayRefundNotifyDTO;
|
|
||||||
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.notify.PayRefundNotifyDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
||||||
@ -37,9 +35,8 @@ public abstract class AbstractAlipayClient extends AbstractPayClient<AlipayPayCl
|
|||||||
|
|
||||||
protected DefaultAlipayClient client;
|
protected DefaultAlipayClient client;
|
||||||
|
|
||||||
public AbstractAlipayClient(Long channelId, String channelCode,
|
public AbstractAlipayClient(Long channelId, String channelCode, AlipayPayClientConfig config) {
|
||||||
AlipayPayClientConfig config, AbstractPayCodeMapping codeMapping) {
|
super(channelId, channelCode, config);
|
||||||
super(channelId, channelCode, config, codeMapping);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -106,7 +103,7 @@ public abstract class AbstractAlipayClient extends AbstractPayClient<AlipayPayCl
|
|||||||
* @return 退款请求 Response
|
* @return 退款请求 Response
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||||
AlipayTradeRefundModel model=new AlipayTradeRefundModel();
|
AlipayTradeRefundModel model=new AlipayTradeRefundModel();
|
||||||
model.setTradeNo(reqDTO.getChannelOrderNo());
|
model.setTradeNo(reqDTO.getChannelOrderNo());
|
||||||
model.setOutTradeNo(reqDTO.getPayTradeNo());
|
model.setOutTradeNo(reqDTO.getPayTradeNo());
|
||||||
@ -127,19 +124,20 @@ public abstract class AbstractAlipayClient extends AbstractPayClient<AlipayPayCl
|
|||||||
//支付宝不返回退款单号,设置为空
|
//支付宝不返回退款单号,设置为空
|
||||||
PayRefundUnifiedRespDTO respDTO = new PayRefundUnifiedRespDTO();
|
PayRefundUnifiedRespDTO respDTO = new PayRefundUnifiedRespDTO();
|
||||||
respDTO.setChannelRefundId("");
|
respDTO.setChannelRefundId("");
|
||||||
return PayCommonResult.build(response.getCode(), response.getMsg(), respDTO, codeMapping);
|
// return PayCommonResult.build(response.getCode(), response.getMsg(), respDTO, codeMapping); TODO
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
// 失败。需要抛出异常
|
// 失败。需要抛出异常
|
||||||
return PayCommonResult.build(response.getCode(), response.getMsg(), null, codeMapping);
|
// return PayCommonResult.build(response.getCode(), response.getMsg(), null, codeMapping); TODO
|
||||||
|
return null;
|
||||||
} catch (AlipayApiException e) {
|
} catch (AlipayApiException e) {
|
||||||
// TODO 记录异常日志
|
// TODO 记录异常日志
|
||||||
log.error("[doUnifiedRefund][request({}) 发起退款失败,网络读超时,退款状态未知]", toJsonString(reqDTO), e);
|
log.error("[doUnifiedRefund][request({}) 发起退款失败,网络读超时,退款状态未知]", toJsonString(reqDTO), e);
|
||||||
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
|
// return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping); TODO
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝统一回调参数 str 转 map
|
* 支付宝统一回调参数 str 转 map
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
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.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
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;
|
||||||
@ -12,12 +12,14 @@ import com.alipay.api.request.AlipayTradePayRequest;
|
|||||||
import com.alipay.api.response.AlipayTradePayResponse;
|
import com.alipay.api.response.AlipayTradePayResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝【条码支付】的 PayClient 实现类
|
* 支付宝【条码支付】的 PayClient 实现类
|
||||||
*
|
*
|
||||||
* 文档:https://opendocs.alipay.com/open/194/105072
|
* 文档:<a href="https://opendocs.alipay.com/open/194/105072">当面付</a>
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@ -25,12 +27,16 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
|
|||||||
public class AlipayBarPayClient extends AbstractAlipayClient {
|
public class AlipayBarPayClient extends AbstractAlipayClient {
|
||||||
|
|
||||||
public AlipayBarPayClient(Long channelId, AlipayPayClientConfig config) {
|
public AlipayBarPayClient(Long channelId, AlipayPayClientConfig config) {
|
||||||
super(channelId, PayChannelEnum.ALIPAY_BAR.getCode(), config,
|
super(channelId, PayChannelEnum.ALIPAY_BAR.getCode(), config);
|
||||||
new AlipayPayCodeMapping());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
|
||||||
|
String authCode = MapUtil.getStr(reqDTO.getChannelExtras(), "auth_code");
|
||||||
|
if (StrUtil.isEmpty(authCode)) {
|
||||||
|
throw exception0(BAD_REQUEST.getCode(), "条形码不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
// 1.1 构建 AlipayTradePayModel 请求
|
// 1.1 构建 AlipayTradePayModel 请求
|
||||||
AlipayTradePayModel model = new AlipayTradePayModel();
|
AlipayTradePayModel model = new AlipayTradePayModel();
|
||||||
// ① 通用的参数
|
// ① 通用的参数
|
||||||
@ -39,7 +45,8 @@ public class AlipayBarPayClient extends AbstractAlipayClient {
|
|||||||
model.setBody(reqDTO.getBody());
|
model.setBody(reqDTO.getBody());
|
||||||
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
|
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
|
||||||
model.setScene("bar_code"); // 当面付条码支付场景
|
model.setScene("bar_code"); // 当面付条码支付场景
|
||||||
// ② 个性化的参数【无】
|
// ② 个性化的参数
|
||||||
|
model.setAuthCode(authCode);
|
||||||
// ③ 支付宝条码支付只有一种展示
|
// ③ 支付宝条码支付只有一种展示
|
||||||
String displayMode = PayDisplayModeEnum.BAR_CODE.getMode();
|
String displayMode = PayDisplayModeEnum.BAR_CODE.getMode();
|
||||||
|
|
||||||
@ -47,20 +54,13 @@ public class AlipayBarPayClient extends AbstractAlipayClient {
|
|||||||
AlipayTradePayRequest request = new AlipayTradePayRequest();
|
AlipayTradePayRequest request = new AlipayTradePayRequest();
|
||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
||||||
request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
|
request.setReturnUrl(reqDTO.getReturnUrl());
|
||||||
|
|
||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradePayResponse response;
|
AlipayTradePayResponse response = client.execute(request);
|
||||||
try {
|
|
||||||
response = client.execute(request);
|
|
||||||
} catch (AlipayApiException e) {
|
|
||||||
log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), e);
|
|
||||||
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
|
|
||||||
}
|
|
||||||
// 2.2 处理结果
|
// 2.2 处理结果
|
||||||
PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO()
|
validateSuccess(response);
|
||||||
.setDisplayMode(displayMode).setDisplayContent(response.getCode());
|
return new PayOrderUnifiedRespDTO()
|
||||||
return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"),
|
.setDisplayMode(displayMode).setDisplayContent("");
|
||||||
response.getMsg(), respDTO, codeMapping);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝的 PayCodeMapping 实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public class AlipayPayCodeMapping extends AbstractPayCodeMapping {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ErrorCode apply0(String apiCode, String apiMsg) {
|
|
||||||
if (Objects.equals(apiCode, "10000")) {
|
|
||||||
return GlobalErrorCodeConstants.SUCCESS;
|
|
||||||
}
|
|
||||||
// alipay wap api code 返回为null, 暂时定为-9999
|
|
||||||
if (Objects.equals(apiCode, "-9999")) {
|
|
||||||
return GlobalErrorCodeConstants.SUCCESS;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -3,8 +3,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
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.json.JsonUtils;
|
|
||||||
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.client.dto.order.PayOrderUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
||||||
@ -18,9 +16,9 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝【PC 网站支付】的 PayClient 实现类
|
* 支付宝【PC 网站】的 PayClient 实现类
|
||||||
*
|
*
|
||||||
* 文档:https://opendocs.alipay.com/open/270/105898
|
* 文档:<a href="https://opendocs.alipay.com/open/270/105898">电脑网站支付</a>
|
||||||
*
|
*
|
||||||
* @author XGD
|
* @author XGD
|
||||||
*/
|
*/
|
||||||
@ -28,12 +26,11 @@ import java.util.Objects;
|
|||||||
public class AlipayPcPayClient extends AbstractAlipayClient {
|
public class AlipayPcPayClient extends AbstractAlipayClient {
|
||||||
|
|
||||||
public AlipayPcPayClient(Long channelId, AlipayPayClientConfig config) {
|
public AlipayPcPayClient(Long channelId, AlipayPayClientConfig config) {
|
||||||
super(channelId, PayChannelEnum.ALIPAY_PC.getCode(), config,
|
super(channelId, PayChannelEnum.ALIPAY_PC.getCode(), config);
|
||||||
new AlipayPayCodeMapping());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
|
||||||
// 1.1 构建 AlipayTradePagePayModel 请求
|
// 1.1 构建 AlipayTradePagePayModel 请求
|
||||||
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
|
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
|
||||||
// ① 通用的参数
|
// ① 通用的参数
|
||||||
@ -54,26 +51,20 @@ public class AlipayPcPayClient extends AbstractAlipayClient {
|
|||||||
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
|
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
|
||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
||||||
request.setReturnUrl(""); // TODO 芋艿,待搞
|
request.setReturnUrl(reqDTO.getReturnUrl());
|
||||||
|
|
||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradePagePayResponse response;
|
AlipayTradePagePayResponse response;
|
||||||
try {
|
|
||||||
if (Objects.equals(displayMode, PayDisplayModeEnum.FORM.getMode())) {
|
if (Objects.equals(displayMode, PayDisplayModeEnum.FORM.getMode())) {
|
||||||
response = client.pageExecute(request, Method.POST.name()); // 需要特殊使用 POST 请求
|
response = client.pageExecute(request, Method.POST.name()); // 需要特殊使用 POST 请求
|
||||||
} else {
|
} else {
|
||||||
response = client.pageExecute(request, Method.GET.name());
|
response = client.pageExecute(request, Method.GET.name());
|
||||||
}
|
}
|
||||||
} catch (AlipayApiException e) {
|
|
||||||
log.error("[unifiedOrder][request({}) 发起支付失败]", JsonUtils.toJsonString(reqDTO), e);
|
|
||||||
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.2 处理结果
|
// 2.2 处理结果
|
||||||
PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO()
|
validateSuccess(response);
|
||||||
.setDisplayMode(displayMode).setDisplayContent(response.getBody());
|
return new PayOrderUnifiedRespDTO().setDisplayMode(displayMode)
|
||||||
return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"),
|
.setDisplayContent(response.getBody());
|
||||||
response.getMsg(), respDTO, codeMapping);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
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;
|
||||||
@ -13,12 +10,10 @@ import com.alipay.api.request.AlipayTradePrecreateRequest;
|
|||||||
import com.alipay.api.response.AlipayTradePrecreateResponse;
|
import com.alipay.api.response.AlipayTradePrecreateResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝【扫码支付】的 PayClient 实现类
|
* 支付宝【扫码支付】的 PayClient 实现类
|
||||||
*
|
*
|
||||||
* 文档:https://opendocs.alipay.com/apis/02890k
|
* 文档:<a href="https://opendocs.alipay.com/apis/02890k">扫码支付</a>
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@ -26,12 +21,11 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
|
|||||||
public class AlipayQrPayClient extends AbstractAlipayClient {
|
public class AlipayQrPayClient extends AbstractAlipayClient {
|
||||||
|
|
||||||
public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) {
|
public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) {
|
||||||
super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config,
|
super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config);
|
||||||
new AlipayPayCodeMapping());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
|
||||||
// 1.1 构建 AlipayTradePrecreateModel 请求
|
// 1.1 构建 AlipayTradePrecreateModel 请求
|
||||||
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
|
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
|
||||||
// ① 通用的参数
|
// ① 通用的参数
|
||||||
@ -39,7 +33,7 @@ public class AlipayQrPayClient extends AbstractAlipayClient {
|
|||||||
model.setSubject(reqDTO.getSubject());
|
model.setSubject(reqDTO.getSubject());
|
||||||
model.setBody(reqDTO.getBody());
|
model.setBody(reqDTO.getBody());
|
||||||
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
|
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
|
||||||
model.setProductCode("FACE_TO_FACE_PAYMENT"); // 销售产品码. 目前扫码支付场景下仅支持 QUICK_WAP_PAY
|
model.setProductCode("FACE_TO_FACE_PAYMENT"); // 销售产品码. 目前扫码支付场景下仅支持 FACE_TO_FACE_PAYMENT
|
||||||
// ② 个性化的参数【无】
|
// ② 个性化的参数【无】
|
||||||
// ③ 支付宝扫码支付只有一种展示,考虑到前端可能希望二维码扫描后,手机打开
|
// ③ 支付宝扫码支付只有一种展示,考虑到前端可能希望二维码扫描后,手机打开
|
||||||
String displayMode = PayDisplayModeEnum.QR_CODE.getMode();
|
String displayMode = PayDisplayModeEnum.QR_CODE.getMode();
|
||||||
@ -48,20 +42,13 @@ public class AlipayQrPayClient extends AbstractAlipayClient {
|
|||||||
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
|
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
|
||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
||||||
request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
|
request.setReturnUrl(reqDTO.getReturnUrl());
|
||||||
|
|
||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradePrecreateResponse response;
|
AlipayTradePrecreateResponse response = client.execute(request);
|
||||||
try {
|
|
||||||
response = client.execute(request);
|
|
||||||
} catch (AlipayApiException e) {
|
|
||||||
log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), e);
|
|
||||||
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
|
|
||||||
}
|
|
||||||
// 2.2 处理结果
|
// 2.2 处理结果
|
||||||
PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO()
|
validateSuccess(response);
|
||||||
|
return new PayOrderUnifiedRespDTO()
|
||||||
.setDisplayMode(displayMode).setDisplayContent(response.getQrCode());
|
.setDisplayMode(displayMode).setDisplayContent(response.getQrCode());
|
||||||
return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"),
|
|
||||||
response.getMsg(), respDTO, codeMapping);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.http.Method;
|
import cn.hutool.http.Method;
|
||||||
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.client.dto.order.PayOrderUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
||||||
@ -14,12 +12,10 @@ import com.alipay.api.request.AlipayTradeWapPayRequest;
|
|||||||
import com.alipay.api.response.AlipayTradeWapPayResponse;
|
import com.alipay.api.response.AlipayTradeWapPayResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝【手机 网站】的 PayClient 实现类
|
* 支付宝【Wap 网站】的 PayClient 实现类
|
||||||
*
|
*
|
||||||
* 文档:https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay
|
* 文档:<a href="https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay">手机网站支付接口</a>
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@ -27,12 +23,11 @@ import java.util.Objects;
|
|||||||
public class AlipayWapPayClient extends AbstractAlipayClient {
|
public class AlipayWapPayClient extends AbstractAlipayClient {
|
||||||
|
|
||||||
public AlipayWapPayClient(Long channelId, AlipayPayClientConfig config) {
|
public AlipayWapPayClient(Long channelId, AlipayPayClientConfig config) {
|
||||||
super(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config,
|
super(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config);
|
||||||
new AlipayPayCodeMapping());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
|
||||||
// 1.1 构建 AlipayTradeWapPayModel 请求
|
// 1.1 构建 AlipayTradeWapPayModel 请求
|
||||||
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
|
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
|
||||||
// ① 通用的参数
|
// ① 通用的参数
|
||||||
@ -50,23 +45,16 @@ public class AlipayWapPayClient extends AbstractAlipayClient {
|
|||||||
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
|
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
|
||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
||||||
request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
|
request.setReturnUrl(reqDTO.getReturnUrl());
|
||||||
model.setQuitUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞
|
model.setQuitUrl(reqDTO.getReturnUrl());
|
||||||
|
|
||||||
// 2.1 执行请求
|
// 2.1 执行请求
|
||||||
AlipayTradeWapPayResponse response;
|
AlipayTradeWapPayResponse response = client.pageExecute(request, Method.GET.name());
|
||||||
try {
|
|
||||||
response = client.pageExecute(request, Method.GET.name());
|
|
||||||
} catch (AlipayApiException e) {
|
|
||||||
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
|
|
||||||
}
|
|
||||||
System.out.println(response.getBody());
|
|
||||||
|
|
||||||
// 2.2 处理结果
|
// 2.2 处理结果
|
||||||
PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO()
|
validateSuccess(response);
|
||||||
|
return new PayOrderUnifiedRespDTO()
|
||||||
.setDisplayMode(displayMode).setDisplayContent(response.getBody());
|
.setDisplayMode(displayMode).setDisplayContent(response.getBody());
|
||||||
return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"),
|
|
||||||
response.getMsg(), respDTO, codeMapping);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信支付 PayCodeMapping 实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public class WXCodeMapping extends AbstractPayCodeMapping {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 错误码 - 成功
|
|
||||||
* 由于 weixin-java-pay 封装的 Result 未返回 code,所以自己定义下
|
|
||||||
*/
|
|
||||||
public static final String CODE_SUCCESS = "SUCCESS";
|
|
||||||
/**
|
|
||||||
* 错误提示 - 成功
|
|
||||||
*/
|
|
||||||
public static final String MESSAGE_SUCCESS = "成功";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ErrorCode apply0(String apiCode, String apiMsg) {
|
|
||||||
if (Objects.equals(apiCode, CODE_SUCCESS)) {
|
|
||||||
return GlobalErrorCodeConstants.SUCCESS;
|
|
||||||
}
|
|
||||||
if (Objects.equals(apiCode, "FAIL")) {
|
|
||||||
if (Objects.equals(apiMsg, "AppID不存在,请检查后再试")) {
|
|
||||||
return PAY_CONFIG_APP_ID_ERROR;
|
|
||||||
}
|
|
||||||
if (Objects.equals(apiMsg, "签名错误,请检查后再试")
|
|
||||||
|| Objects.equals(apiMsg, "签名错误")) {
|
|
||||||
return PAY_CONFIG_SIGN_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Objects.equals(apiCode, "PARAM_ERROR")) {
|
|
||||||
if (Objects.equals(apiMsg, "无效的openid")) {
|
|
||||||
return PAY_OPENID_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Objects.equals(apiCode, "CustomErrorCode")) {
|
|
||||||
if (StrUtil.contains(apiMsg, "必填字段")) {
|
|
||||||
return PAY_PARAM_MISSING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -7,12 +7,11 @@ import cn.hutool.core.lang.Assert;
|
|||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
||||||
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.PayRefundNotifyDTO;
|
|
||||||
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.notify.PayRefundNotifyDTO;
|
||||||
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.client.dto.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
||||||
@ -35,11 +34,6 @@ import java.time.ZoneId;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
|
||||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.CODE_SUCCESS;
|
|
||||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.MESSAGE_SUCCESS;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信小程序下支付
|
* 微信小程序下支付
|
||||||
*
|
*
|
||||||
@ -51,7 +45,7 @@ public class WXLitePayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
private WxPayService client;
|
private WxPayService client;
|
||||||
|
|
||||||
public WXLitePayClient(Long channelId, WXPayClientConfig config) {
|
public WXLitePayClient(Long channelId, WXPayClientConfig config) {
|
||||||
super(channelId, PayChannelEnum.WX_LITE.getCode(), config, new WXCodeMapping());
|
super(channelId, PayChannelEnum.WX_LITE.getCode(), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -76,28 +70,29 @@ public class WXLitePayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<WxPayMpOrderResult> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
||||||
WxPayMpOrderResult response;
|
throw new UnsupportedOperationException();
|
||||||
try {
|
// WxPayMpOrderResult response;
|
||||||
switch (config.getApiVersion()) {
|
// try {
|
||||||
case WXPayClientConfig.API_VERSION_V2:
|
// switch (config.getApiVersion()) {
|
||||||
response = this.unifiedOrderV2(reqDTO);
|
// case WXPayClientConfig.API_VERSION_V2:
|
||||||
break;
|
// response = this.unifiedOrderV2(reqDTO);
|
||||||
case WXPayClientConfig.API_VERSION_V3:
|
// break;
|
||||||
WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
|
// case WXPayClientConfig.API_VERSION_V3:
|
||||||
// 将 V3 的结果,统一转换成 V2。返回的字段是一致的
|
// WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
|
||||||
response = new WxPayMpOrderResult();
|
// // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
|
||||||
BeanUtil.copyProperties(responseV3, response, true);
|
// response = new WxPayMpOrderResult();
|
||||||
break;
|
// BeanUtil.copyProperties(responseV3, response, true);
|
||||||
default:
|
// break;
|
||||||
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
// default:
|
||||||
}
|
// throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
||||||
} catch (WxPayException e) {
|
// }
|
||||||
log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
|
// } catch (WxPayException e) {
|
||||||
return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
|
// log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
|
||||||
ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()), null, codeMapping);
|
// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
|
||||||
}
|
// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()), null, codeMapping);
|
||||||
return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
|
// }
|
||||||
|
// return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WxPayMpOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
|
private WxPayMpOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
|
||||||
@ -204,7 +199,7 @@ public class WXLitePayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
|
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||||
//TODO 需要实现
|
//TODO 需要实现
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,11 @@ import cn.hutool.core.date.LocalDateTimeUtil;
|
|||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
||||||
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.PayRefundNotifyDTO;
|
|
||||||
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.notify.PayRefundNotifyDTO;
|
||||||
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.client.dto.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
||||||
@ -33,10 +32,6 @@ import java.time.ZoneId;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
|
||||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.CODE_SUCCESS;
|
|
||||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.MESSAGE_SUCCESS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信 App 支付
|
* 微信 App 支付
|
||||||
*
|
*
|
||||||
@ -48,7 +43,7 @@ public class WXNativePayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
private WxPayService client;
|
private WxPayService client;
|
||||||
|
|
||||||
public WXNativePayClient(Long channelId, WXPayClientConfig config) {
|
public WXNativePayClient(Long channelId, WXPayClientConfig config) {
|
||||||
super(channelId, PayChannelEnum.WX_NATIVE.getCode(), config, new WXCodeMapping());
|
super(channelId, PayChannelEnum.WX_NATIVE.getCode(), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -73,27 +68,28 @@ public class WXNativePayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<String> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
||||||
// 这里原生的返回的是支付的 url 所以直接使用string接收
|
throw new UnsupportedOperationException();
|
||||||
// "invokeResponse": "weixin://wxpay/bizpayurl?pr=EGYAem7zz"
|
// // 这里原生的返回的是支付的 url 所以直接使用string接收
|
||||||
String responseV3;
|
// // "invokeResponse": "weixin://wxpay/bizpayurl?pr=EGYAem7zz"
|
||||||
try {
|
// String responseV3;
|
||||||
switch (config.getApiVersion()) {
|
// try {
|
||||||
case WXPayClientConfig.API_VERSION_V2:
|
// switch (config.getApiVersion()) {
|
||||||
responseV3 = unifiedOrderV2(reqDTO).getCodeUrl();
|
// case WXPayClientConfig.API_VERSION_V2:
|
||||||
break;
|
// responseV3 = unifiedOrderV2(reqDTO).getCodeUrl();
|
||||||
case WXPayClientConfig.API_VERSION_V3:
|
// break;
|
||||||
responseV3 = this.unifiedOrderV3(reqDTO);
|
// case WXPayClientConfig.API_VERSION_V3:
|
||||||
break;
|
// responseV3 = this.unifiedOrderV3(reqDTO);
|
||||||
default:
|
// break;
|
||||||
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
// default:
|
||||||
}
|
// throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
||||||
} catch (WxPayException e) {
|
// }
|
||||||
log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
|
// } catch (WxPayException e) {
|
||||||
return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
|
// log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
|
||||||
ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()), null, codeMapping);
|
// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
|
||||||
}
|
// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()), null, codeMapping);
|
||||||
return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, responseV3, codeMapping);
|
// }
|
||||||
|
// return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, responseV3, codeMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WxPayNativeOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
|
private WxPayNativeOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
|
||||||
@ -186,7 +182,7 @@ public class WXNativePayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
|
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||||
// TODO 需要实现
|
// TODO 需要实现
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,11 @@ import cn.hutool.core.lang.Assert;
|
|||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
||||||
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.PayRefundNotifyDTO;
|
|
||||||
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.notify.PayRefundNotifyDTO;
|
||||||
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.client.dto.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
||||||
@ -35,10 +34,6 @@ import java.time.LocalDateTime;
|
|||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
|
||||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.CODE_SUCCESS;
|
|
||||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.MESSAGE_SUCCESS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付(公众号)的 PayClient 实现类
|
* 微信支付(公众号)的 PayClient 实现类
|
||||||
*
|
*
|
||||||
@ -50,7 +45,7 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
private WxPayService client;
|
private WxPayService client;
|
||||||
|
|
||||||
public WXPubPayClient(Long channelId, WXPayClientConfig config) {
|
public WXPubPayClient(Long channelId, WXPayClientConfig config) {
|
||||||
super(channelId, PayChannelEnum.WX_PUB.getCode(), config, new WXCodeMapping());
|
super(channelId, PayChannelEnum.WX_PUB.getCode(), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -75,28 +70,30 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayCommonResult<WxPayMpOrderResult> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
||||||
WxPayMpOrderResult response;
|
throw new UnsupportedOperationException();
|
||||||
try {
|
//
|
||||||
switch (config.getApiVersion()) {
|
// WxPayMpOrderResult response;
|
||||||
case WXPayClientConfig.API_VERSION_V2:
|
// try {
|
||||||
response = this.unifiedOrderV2(reqDTO);
|
// switch (config.getApiVersion()) {
|
||||||
break;
|
// case WXPayClientConfig.API_VERSION_V2:
|
||||||
case WXPayClientConfig.API_VERSION_V3:
|
// response = this.unifiedOrderV2(reqDTO);
|
||||||
WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
|
// break;
|
||||||
// 将 V3 的结果,统一转换成 V2。返回的字段是一致的
|
// case WXPayClientConfig.API_VERSION_V3:
|
||||||
response = new WxPayMpOrderResult();
|
// WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
|
||||||
BeanUtil.copyProperties(responseV3, response, true);
|
// // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
|
||||||
break;
|
// response = new WxPayMpOrderResult();
|
||||||
default:
|
// BeanUtil.copyProperties(responseV3, response, true);
|
||||||
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
// break;
|
||||||
}
|
// default:
|
||||||
} catch (WxPayException e) {
|
// throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
||||||
log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
|
// }
|
||||||
return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
|
// } catch (WxPayException e) {
|
||||||
ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()),null, codeMapping);
|
// log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
|
||||||
}
|
// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
|
||||||
return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
|
// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()),null, codeMapping);
|
||||||
|
// }
|
||||||
|
// return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -196,7 +193,7 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
|
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
|
||||||
// TODO 需要实现
|
// TODO 需要实现
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
|||||||
/**
|
/**
|
||||||
* 支付框架的错误码枚举
|
* 支付框架的错误码枚举
|
||||||
*
|
*
|
||||||
* 短信框架,使用 2-002-000-000 段
|
* 支付框架,使用 2-002-000-000 段
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@ -14,14 +14,16 @@ public interface PayFrameworkErrorCodeConstants {
|
|||||||
ErrorCode PAY_UNKNOWN = new ErrorCode(2002000000, "未知错误,需要解析");
|
ErrorCode PAY_UNKNOWN = new ErrorCode(2002000000, "未知错误,需要解析");
|
||||||
|
|
||||||
// ========== 配置相关相关 2002000100 ==========
|
// ========== 配置相关相关 2002000100 ==========
|
||||||
|
// todo 芋艿:如下的错误码,怎么处理掉
|
||||||
ErrorCode PAY_CONFIG_APP_ID_ERROR = new ErrorCode(2002000100, "支付渠道 AppId 不正确");
|
ErrorCode PAY_CONFIG_APP_ID_ERROR = new ErrorCode(2002000100, "支付渠道 AppId 不正确");
|
||||||
ErrorCode PAY_CONFIG_SIGN_ERROR = new ErrorCode(2002000100, "签名错误"); // 例如说,微信支付,配置错了 mchId 或者 mchKey
|
ErrorCode PAY_CONFIG_SIGN_ERROR = new ErrorCode(2002000100, "签名错误"); // 例如说,微信支付,配置错了 mchId 或者 mchKey
|
||||||
|
|
||||||
|
|
||||||
// ========== 其它相关 2002000900 开头 ==========
|
// ========== 其它相关 2002000900 开头 ==========
|
||||||
|
// todo 芋艿:如下的错误码,怎么处理掉
|
||||||
ErrorCode PAY_OPENID_ERROR = new ErrorCode(2002000900, "无效的 openid"); // 例如说,微信 openid 未授权过
|
ErrorCode PAY_OPENID_ERROR = new ErrorCode(2002000900, "无效的 openid"); // 例如说,微信 openid 未授权过
|
||||||
ErrorCode PAY_PARAM_MISSING = new ErrorCode(2002000901, "请求参数缺失"); // 例如说,支付少传了金额
|
ErrorCode PAY_PARAM_MISSING = new ErrorCode(2002000901, "请求参数缺失"); // 例如说,支付少传了金额
|
||||||
|
|
||||||
ErrorCode EXCEPTION = new ErrorCode(2002000999, "调用异常");
|
ErrorCode PAY_EXCEPTION = new ErrorCode(2002000999, "调用异常");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,8 @@ public class PayClientFactoryImplIntegrationTest {
|
|||||||
PayClient client = payClientFactory.getPayClient(channelId);
|
PayClient client = payClientFactory.getPayClient(channelId);
|
||||||
// 发起支付
|
// 发起支付
|
||||||
PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
|
PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
|
||||||
CommonResult<?> result = client.unifiedOrder(reqDTO);
|
// CommonResult<?> result = client.unifiedOrder(reqDTO);
|
||||||
System.out.println(result);
|
// System.out.println(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,8 +69,8 @@ public class PayClientFactoryImplIntegrationTest {
|
|||||||
PayClient client = payClientFactory.getPayClient(channelId);
|
PayClient client = payClientFactory.getPayClient(channelId);
|
||||||
// 发起支付
|
// 发起支付
|
||||||
PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
|
PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
|
||||||
CommonResult<?> result = client.unifiedOrder(reqDTO);
|
// CommonResult<?> result = client.unifiedOrder(reqDTO);
|
||||||
System.out.println(result);
|
// System.out.println(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,9 +93,9 @@ public class PayClientFactoryImplIntegrationTest {
|
|||||||
// 发起支付
|
// 发起支付
|
||||||
PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
|
PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
|
||||||
reqDTO.setNotifyUrl("http://yunai.natapp1.cc/admin-api/pay/notify/callback/18"); // TODO @tina: 这里改成你的 natapp 回调地址
|
reqDTO.setNotifyUrl("http://yunai.natapp1.cc/admin-api/pay/notify/callback/18"); // TODO @tina: 这里改成你的 natapp 回调地址
|
||||||
CommonResult<AlipayTradePrecreateResponse> result = (CommonResult<AlipayTradePrecreateResponse>) client.unifiedOrder(reqDTO);
|
// CommonResult<AlipayTradePrecreateResponse> result = (CommonResult<AlipayTradePrecreateResponse>) client.unifiedOrder(reqDTO);
|
||||||
System.out.println(JsonUtils.toJsonString(result));
|
// System.out.println(JsonUtils.toJsonString(result));
|
||||||
System.out.println(result.getData().getQrCode());
|
// System.out.println(result.getData().getQrCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,8 +116,8 @@ public class PayClientFactoryImplIntegrationTest {
|
|||||||
PayClient client = payClientFactory.getPayClient(channelId);
|
PayClient client = payClientFactory.getPayClient(channelId);
|
||||||
// 发起支付
|
// 发起支付
|
||||||
PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
|
PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
|
||||||
CommonResult<?> result = client.unifiedOrder(reqDTO);
|
// CommonResult<?> result = client.unifiedOrder(reqDTO);
|
||||||
System.out.println(JsonUtils.toJsonString(result));
|
// System.out.println(JsonUtils.toJsonString(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PayOrderUnifiedReqDTO buildPayOrderUnifiedReqDTO() {
|
private static PayOrderUnifiedReqDTO buildPayOrderUnifiedReqDTO() {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
@ -88,13 +87,13 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
|
|||||||
}))).thenReturn(response);
|
}))).thenReturn(response);
|
||||||
|
|
||||||
|
|
||||||
PayCommonResult<PayOrderUnifiedRespDTO> result = client.doUnifiedOrder(reqDTO);
|
// PayCommonResult<PayOrderUnifiedRespDTO> result = client.doUnifiedOrder(reqDTO);
|
||||||
// 断言
|
// // 断言
|
||||||
assertEquals(response.getCode(), result.getApiCode());
|
// assertEquals(response.getCode(), result.getApiCode());
|
||||||
assertEquals(response.getMsg(), result.getApiMsg());
|
// assertEquals(response.getMsg(), result.getApiMsg());
|
||||||
// TODO @tina:这个断言木有过?
|
// // TODO @tina:这个断言木有过?
|
||||||
assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
|
// assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
|
||||||
assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
|
// assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,14 +150,11 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|||||||
.setReturnUrl(genChannelReturnUrl(channel))
|
.setReturnUrl(genChannelReturnUrl(channel))
|
||||||
// 订单相关字段
|
// 订单相关字段
|
||||||
.setAmount(order.getAmount()).setExpireTime(order.getExpireTime());
|
.setAmount(order.getAmount()).setExpireTime(order.getExpireTime());
|
||||||
CommonResult<?> unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO);
|
PayOrderUnifiedRespDTO unifiedOrderRespDTO = client.unifiedOrder(unifiedOrderReqDTO);
|
||||||
unifiedOrderResult.checkError();
|
|
||||||
|
|
||||||
PayOrderUnifiedRespDTO xx = (PayOrderUnifiedRespDTO) unifiedOrderResult.getData();
|
|
||||||
|
|
||||||
// TODO 轮询三方接口,是否已经支付的任务
|
// TODO 轮询三方接口,是否已经支付的任务
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return PayOrderConvert.INSTANCE.convert(xx);
|
return PayOrderConvert.INSTANCE.convert(unifiedOrderRespDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PayOrderDO validatePayOrderCanSubmit(Long id) {
|
private PayOrderDO validatePayOrderCanSubmit(Long id) {
|
||||||
|
@ -3,14 +3,13 @@ package cn.iocoder.yudao.module.pay.service.refund;
|
|||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.pay.config.PayProperties;
|
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.PayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
||||||
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.PayRefundNotifyDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum;
|
||||||
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO;
|
||||||
@ -22,7 +21,6 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
|
|||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper;
|
import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper;
|
||||||
import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper;
|
import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
|
import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
|
||||||
import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum;
|
import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum;
|
||||||
import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
|
import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
|
||||||
@ -169,11 +167,10 @@ public class PayRefundServiceImpl implements PayRefundService {
|
|||||||
.setNotifyUrl(genChannelPayNotifyUrl(channel)) // TODO 芋艿:优化下 notifyUrl
|
.setNotifyUrl(genChannelPayNotifyUrl(channel)) // TODO 芋艿:优化下 notifyUrl
|
||||||
.setReason(reqDTO.getReason());
|
.setReason(reqDTO.getReason());
|
||||||
// 向渠道发起退款申请
|
// 向渠道发起退款申请
|
||||||
PayCommonResult<PayRefundUnifiedRespDTO> refundUnifiedResult = client.unifiedRefund(unifiedReqDTO);
|
client.unifiedRefund(unifiedReqDTO);
|
||||||
// 检查是否失败,失败抛出业务异常。
|
// 检查是否失败,失败抛出业务异常。
|
||||||
// TODO 渠道的异常记录。
|
// TODO 渠道的异常记录。
|
||||||
// TODO @jason:可以先打个 warn log 哈;
|
// TODO @jason:可以先打个 warn log 哈;
|
||||||
refundUnifiedResult.checkError();
|
|
||||||
// 成功在 退款回调中处理
|
// 成功在 退款回调中处理
|
||||||
return payRefundDO.getId();
|
return payRefundDO.getId();
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,32 @@
|
|||||||
<!-- 展示形式:Form -->
|
<!-- 展示形式:Form -->
|
||||||
<div ref="formRef" v-html="form.value" />
|
<div ref="formRef" v-html="form.value" />
|
||||||
|
|
||||||
|
<!-- 展示形式:BarCode 条形码 -->
|
||||||
|
<el-dialog :title="barCode.title" :visible.sync="barCode.visible" width="500px" append-to-body
|
||||||
|
:close-on-press-escape="false">
|
||||||
|
<el-form ref="form" label-width="80px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="条形码" prop="name">
|
||||||
|
<el-input v-model="barCode.value" placeholder="请输入条形码" required />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<div style="text-align: right">
|
||||||
|
或使用
|
||||||
|
<el-link type="danger" target="_blank"
|
||||||
|
href="https://baike.baidu.com/item/条码支付/10711903">(扫码枪/扫码盒)</el-link>
|
||||||
|
扫码
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submit0(barCode.channelCode)"
|
||||||
|
:disabled="barCode.value.length === 0">确认支付</el-button>
|
||||||
|
<el-button @click="barCode.visible = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -104,6 +130,7 @@ export default {
|
|||||||
html: '',
|
html: '',
|
||||||
},
|
},
|
||||||
barCode: { // 展示形式:条形码
|
barCode: { // 展示形式:条形码
|
||||||
|
channelCode: '',
|
||||||
value: '',
|
value: '',
|
||||||
title: '',
|
title: '',
|
||||||
visible: false,
|
visible: false,
|
||||||
@ -163,7 +190,12 @@ export default {
|
|||||||
submit(channelCode) {
|
submit(channelCode) {
|
||||||
// 条形码支付,需要特殊处理
|
// 条形码支付,需要特殊处理
|
||||||
if (channelCode === PayChannelEnum.ALIPAY_BAR.code) {
|
if (channelCode === PayChannelEnum.ALIPAY_BAR.code) {
|
||||||
|
this.barCode = {
|
||||||
|
channelCode: channelCode,
|
||||||
|
value: '',
|
||||||
|
title: '“支付宝”条码支付',
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +222,9 @@ export default {
|
|||||||
|
|
||||||
// 打开轮询任务
|
// 打开轮询任务
|
||||||
this.createQueryInterval()
|
this.createQueryInterval()
|
||||||
})
|
}).catch(() => {
|
||||||
|
this.submitLoading = false
|
||||||
|
});
|
||||||
},
|
},
|
||||||
/** 构建提交支付的额外参数 */
|
/** 构建提交支付的额外参数 */
|
||||||
buildSubmitParam(channelCode) {
|
buildSubmitParam(channelCode) {
|
||||||
@ -232,12 +266,22 @@ export default {
|
|||||||
// displayMode: PayDisplayModeEnum.FORM.mode
|
// displayMode: PayDisplayModeEnum.FORM.mode
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ② 支付宝 Wap 支付时,引导手机扫码支付
|
// ② 支付宝 Wap 支付时,引导手机扫码支付
|
||||||
if (channelCode === PayChannelEnum.ALIPAY_WAP.code) {
|
if (channelCode === PayChannelEnum.ALIPAY_WAP.code) {
|
||||||
return {
|
return {
|
||||||
displayMode: PayDisplayModeEnum.QR_CODE.mode
|
displayMode: PayDisplayModeEnum.QR_CODE.mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ③ 支付宝 BarCode 支付时,需要传递 authCode 条形码
|
||||||
|
if (channelCode === PayChannelEnum.ALIPAY_BAR.code) {
|
||||||
|
return {
|
||||||
|
"channelExtras": {
|
||||||
|
"auth_code": this.barCode.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
/** 提交支付后,IFrame 内置 URL 的展示形式 */
|
/** 提交支付后,IFrame 内置 URL 的展示形式 */
|
||||||
|
Loading…
Reference in New Issue
Block a user