支付中心:增加模拟支付,方便开发调试

pull/46/head
YunaiV 2023-07-29 11:41:27 +08:00
parent ca886c2791
commit 2b9973d374
5 changed files with 108 additions and 3 deletions

View File

@ -5,6 +5,8 @@ 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.PayClientFactory; import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*;
import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClient;
import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*; import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -68,6 +70,8 @@ public class PayClientFactoryImpl implements PayClientFactory {
case ALIPAY_APP: return (AbstractPayClient<Config>) new AlipayAppPayClient(channelId, (AlipayPayClientConfig) config); case ALIPAY_APP: return (AbstractPayClient<Config>) new AlipayAppPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_PC: return (AbstractPayClient<Config>) new AlipayPcPayClient(channelId, (AlipayPayClientConfig) config); case ALIPAY_PC: return (AbstractPayClient<Config>) new AlipayPcPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_BAR: return (AbstractPayClient<Config>) new AlipayBarPayClient(channelId, (AlipayPayClientConfig) config); case ALIPAY_BAR: return (AbstractPayClient<Config>) new AlipayBarPayClient(channelId, (AlipayPayClientConfig) config);
// 其它支付
case MOCK: return (AbstractPayClient<Config>) new MockPayClient(channelId, (MockPayClientConfig) config);
} }
// 创建失败,错误日志 + 抛出异常 // 创建失败,错误日志 + 抛出异常
log.error("[createPayClient][配置({}) 找不到合适的客户端实现]", config); log.error("[createPayClient][配置({}) 找不到合适的客户端实现]", config);

View File

@ -0,0 +1,66 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.mock;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import java.time.LocalDateTime;
import java.util.Map;
/**
* PayClient
*
* 便
*
* @author jason
*/
public class MockPayClient extends AbstractPayClient<MockPayClientConfig> {
private static final String MOCK_RESP_SUCCESS_DATA = "MOCK_SUCCESS";
public MockPayClient(Long channelId, MockPayClientConfig config) {
super(channelId, PayChannelEnum.MOCK.getCode(), config);
}
@Override
protected void doInit() {
}
@Override
protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
return PayOrderRespDTO.successOf("MOCK-P-" + reqDTO.getOutTradeNo(), "", LocalDateTime.now(),
reqDTO.getOutTradeNo(), MOCK_RESP_SUCCESS_DATA);
}
@Override
protected PayOrderRespDTO doGetOrder(String outTradeNo) {
return PayOrderRespDTO.successOf("MOCK-P-" + outTradeNo, "", LocalDateTime.now(),
outTradeNo, MOCK_RESP_SUCCESS_DATA);
}
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
return PayRefundRespDTO.successOf("MOCK-R-" + reqDTO.getOutRefundNo(), LocalDateTime.now(),
reqDTO.getOutRefundNo(), MOCK_RESP_SUCCESS_DATA);
}
@Override
protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) {
return PayRefundRespDTO.successOf("MOCK-R-" + outRefundNo, LocalDateTime.now(),
outRefundNo, MOCK_RESP_SUCCESS_DATA);
}
@Override
protected PayRefundRespDTO doParseRefundNotify(Map<String, String> params, String body) {
throw new UnsupportedOperationException("模拟支付无退款回调");
}
@Override
protected PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) {
throw new UnsupportedOperationException("模拟支付无支付回调");
}
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.mock;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import lombok.Data;
import javax.validation.Validator;
/**
* PayClientConfig
*
* @author jason
*/
@Data
public class MockPayClientConfig implements PayClientConfig {
/**
*
*
* JsonUtils.parseObject2
*/
private String name;
@Override
public void validate(Validator validator) {
// 模拟支付配置无需校验
}
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.pay.core.enums.channel;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
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.impl.alipay.AlipayPayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -26,7 +27,9 @@ public enum PayChannelEnum {
ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class), ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class),
ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class), ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class),
ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class),
ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class); ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class),
MOCK("mock", "模拟支付", MockPayClientConfig.class);
/** /**
* *

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.pay.controller.admin.notify; package cn.iocoder.yudao.module.pay.controller.admin.notify;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
@ -82,8 +83,8 @@ public class PayNotifyController {
@PermitAll @PermitAll
@OperateLog(enable = false) // 回调地址,无需记录操作日志 @OperateLog(enable = false) // 回调地址,无需记录操作日志
public String notifyRefund(@PathVariable("channelId") Long channelId, public String notifyRefund(@PathVariable("channelId") Long channelId,
@RequestParam(required = false) Map<String, String> params, @RequestParam(required = false) Map<String, String> params,
@RequestBody(required = false) String body) { @RequestBody(required = false) String body) {
log.info("[notifyRefund][channelId({}) 回调数据({}/{})]", channelId, params, body); log.info("[notifyRefund][channelId({}) 回调数据({}/{})]", channelId, params, body);
// 1. 校验支付渠道是否存在 // 1. 校验支付渠道是否存在
PayClient payClient = payClientFactory.getPayClient(channelId); PayClient payClient = payClientFactory.getPayClient(channelId);
@ -118,6 +119,9 @@ public class PayNotifyController {
@PreAuthorize("@ss.hasPermission('pay:notify:query')") @PreAuthorize("@ss.hasPermission('pay:notify:query')")
public CommonResult<PageResult<PayNotifyTaskRespVO>> getNotifyTaskPage(@Valid PayNotifyTaskPageReqVO pageVO) { public CommonResult<PageResult<PayNotifyTaskRespVO>> getNotifyTaskPage(@Valid PayNotifyTaskPageReqVO pageVO) {
PageResult<PayNotifyTaskDO> pageResult = notifyService.getNotifyTaskPage(pageVO); PageResult<PayNotifyTaskDO> pageResult = notifyService.getNotifyTaskPage(pageVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return success(PageResult.empty());
}
// 拼接返回 // 拼接返回
Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTaskDO::getAppId)); Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTaskDO::getAppId));
return success(PayNotifyTaskConvert.INSTANCE.convertPage(pageResult, appMap)); return success(PayNotifyTaskConvert.INSTANCE.convertPage(pageResult, appMap));