params, String body)
- throws Throwable;
-
- @Override
- public final PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo) {
- try {
- return doGetRefund(outTradeNo, outRefundNo);
- } catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
- throw ex;
- } catch (Throwable ex) {
- log.error("[getRefund][客户端({}) outTradeNo({}) outRefundNo({}) 查询退款单异常]",
- getId(), outTradeNo, outRefundNo, ex);
- throw buildPayException(ex);
- }
- }
-
- protected abstract PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo)
- throws Throwable;
-
- @Override
- public final PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
- validatePayTransferReqDTO(reqDTO);
- PayTransferRespDTO resp;
- try {
- resp = doUnifiedTransfer(reqDTO);
- } catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
- throw ex;
- } catch (Throwable ex) {
- // 系统异常,则包装成 PayException 异常抛出
- log.error("[unifiedTransfer][客户端({}) request({}) 发起转账异常]",
- getId(), toJsonString(reqDTO), ex);
- throw buildPayException(ex);
- }
- return resp;
- }
- private void validatePayTransferReqDTO(PayTransferUnifiedReqDTO reqDTO) {
- PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(reqDTO.getType());
- switch (transferType) {
- case ALIPAY_BALANCE: {
- ValidationUtils.validate(reqDTO, PayTransferTypeEnum.Alipay.class);
- break;
- }
- case WX_BALANCE: {
- ValidationUtils.validate(reqDTO, PayTransferTypeEnum.WxPay.class);
- break;
- }
- default: {
- throw exception(NOT_IMPLEMENTED);
- }
- }
- }
-
- @Override
- public final PayTransferRespDTO getTransfer(String outTradeNo, PayTransferTypeEnum type) {
- try {
- return doGetTransfer(outTradeNo, type);
- } catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
- throw ex;
- } catch (Throwable ex) {
- log.error("[getTransfer][客户端({}) outTradeNo({}) type({}) 查询转账单异常]",
- getId(), outTradeNo, type, ex);
- throw buildPayException(ex);
- }
- }
-
- protected abstract PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO)
- throws Throwable;
-
- protected abstract PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type)
- throws Throwable;
-
- // ========== 各种工具方法 ==========
-
- private PayException buildPayException(Throwable ex) {
- if (ex instanceof PayException) {
- return (PayException) ex;
- }
- throw new PayException(ex);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java
deleted file mode 100644
index 80581f3049..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl;
-
-import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
-import lombok.Data;
-
-import jakarta.validation.Validator;
-
-/**
- * 无需任何配置 PayClientConfig 实现类
- *
- * @author jason
- */
-@Data
-public class NonePayClientConfig implements PayClientConfig {
-
- /**
- * 配置名称
- *
- * 如果不加任何属性,JsonUtils.parseObject2 解析会报错,所以暂时加个名称
- */
- private String name;
-
- public NonePayClientConfig(){
- this.name = "none-config";
- }
-
- @Override
- public void validate(Validator validator) {
- // 无任何配置不需要校验
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
deleted file mode 100644
index 0b39587abb..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl;
-
-import cn.hutool.core.lang.Assert;
-import cn.hutool.core.util.ReflectUtil;
-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.PayClientFactory;
-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.weixin.*;
-import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import static cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum.*;
-
-/**
- * 支付客户端的工厂实现类
- *
- * @author 芋道源码
- */
-@Slf4j
-public class PayClientFactoryImpl implements PayClientFactory {
-
- /**
- * 支付客户端 Map
- *
- * key:渠道编号
- */
- private final ConcurrentMap> clients = new ConcurrentHashMap<>();
-
- /**
- * 支付客户端 Class Map
- */
- private final Map> clientClass = new ConcurrentHashMap<>();
-
- public PayClientFactoryImpl() {
- // 微信支付客户端
- clientClass.put(WX_PUB, WxPubPayClient.class);
- clientClass.put(WX_LITE, WxLitePayClient.class);
- clientClass.put(WX_APP, WxAppPayClient.class);
- clientClass.put(WX_BAR, WxBarPayClient.class);
- clientClass.put(WX_NATIVE, WxNativePayClient.class);
- // 支付包支付客户端
- clientClass.put(ALIPAY_WAP, AlipayWapPayClient.class);
- clientClass.put(ALIPAY_QR, AlipayQrPayClient.class);
- clientClass.put(ALIPAY_APP, AlipayAppPayClient.class);
- clientClass.put(ALIPAY_PC, AlipayPcPayClient.class);
- clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class);
- // Mock 支付客户端
- clientClass.put(MOCK, MockPayClient.class);
- }
-
- @Override
- public void registerPayClientClass(PayChannelEnum channel, Class> payClientClass) {
- clientClass.put(channel, payClientClass);
- }
-
- @Override
- public PayClient getPayClient(Long channelId) {
- AbstractPayClient> client = clients.get(channelId);
- if (client == null) {
- log.error("[getPayClient][渠道编号({}) 找不到客户端]", channelId);
- }
- return client;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public void createOrUpdatePayClient(Long channelId, String channelCode,
- Config config) {
- AbstractPayClient client = (AbstractPayClient) clients.get(channelId);
- if (client == null) {
- client = this.createPayClient(channelId, channelCode, config);
- client.init();
- clients.put(client.getId(), client);
- } else {
- client.refresh(config);
- }
- }
-
- @SuppressWarnings("unchecked")
- private AbstractPayClient createPayClient(Long channelId, String channelCode,
- Config config) {
- PayChannelEnum channelEnum = PayChannelEnum.getByCode(channelCode);
- Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelCode));
- Class> payClientClass = clientClass.get(channelEnum);
- Assert.notNull(payClientClass, String.format("支付渠道(%s) Class 为空", channelCode));
- return (AbstractPayClient) ReflectUtil.newInstance(payClientClass, channelId, config);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
deleted file mode 100644
index 4dcf236755..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
+++ /dev/null
@@ -1,342 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.date.LocalDateTimeUtil;
-import cn.hutool.core.lang.Assert;
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.HttpUtil;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-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.dto.transfer.PayTransferRespDTO;
-import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
-import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.AlipayConfig;
-import com.alipay.api.AlipayResponse;
-import com.alipay.api.DefaultAlipayClient;
-import com.alipay.api.domain.*;
-import com.alipay.api.internal.util.AlipaySignature;
-import com.alipay.api.request.*;
-import com.alipay.api.response.*;
-import lombok.Getter;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-
-import java.nio.charset.StandardCharsets;
-import java.time.LocalDateTime;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Supplier;
-
-import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
-import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.*;
-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.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
-
-/**
- * 支付宝抽象类,实现支付宝统一的接口、以及部分实现(退款)
- *
- * @author jason
- */
-@Slf4j
-public abstract class AbstractAlipayPayClient extends AbstractPayClient {
-
- @Getter // 仅用于单测场景
- protected DefaultAlipayClient client;
-
- public AbstractAlipayPayClient(Long channelId, String channelCode, AlipayPayClientConfig config) {
- super(channelId, channelCode, config);
- }
-
- @Override
- @SneakyThrows
- protected void doInit() {
- AlipayConfig alipayConfig = new AlipayConfig();
- BeanUtil.copyProperties(config, alipayConfig, false);
- this.client = new DefaultAlipayClient(alipayConfig);
- }
-
- // ============ 支付相关 ==========
-
- /**
- * 构造支付关闭的 {@link PayOrderRespDTO} 对象
- *
- * @return 支付关闭的 {@link PayOrderRespDTO} 对象
- */
- protected PayOrderRespDTO buildClosedPayOrderRespDTO(PayOrderUnifiedReqDTO reqDTO, AlipayResponse response) {
- Assert.isFalse(response.isSuccess());
- return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
- reqDTO.getOutTradeNo(), response);
- }
-
- @Override
- public PayOrderRespDTO doParseOrderNotify(Map params, String body) throws Throwable {
- // 1. 校验回调数据
- Map bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8);
- AlipaySignature.rsaCheckV1(bodyObj, config.getAlipayPublicKey(),
- StandardCharsets.UTF_8.name(), config.getSignType());
-
- // 2. 解析订单的状态
- // 额外说明:支付宝不仅仅支付成功会回调,再各种触发支付单数据变化时,都会进行回调,所以这里 status 的解析会写的比较复杂
- Integer status = parseStatus(bodyObj.get("trade_status"));
- // 特殊逻辑: 支付宝没有退款成功的状态,所以,如果有退款金额,我们认为是退款成功
- if (MapUtil.getDouble(bodyObj, "refund_fee", 0D) > 0) {
- status = PayOrderStatusRespEnum.REFUND.getStatus();
- }
- Assert.notNull(status, (Supplier) () -> {
- throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", body));
- });
- return PayOrderRespDTO.of(status, bodyObj.get("trade_no"), bodyObj.get("seller_id"), parseTime(params.get("gmt_payment")),
- bodyObj.get("out_trade_no"), body);
- }
-
- @Override
- protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable {
- // 1.1 构建 AlipayTradeRefundModel 请求
- AlipayTradeQueryModel model = new AlipayTradeQueryModel();
- model.setOutTradeNo(outTradeNo);
- // 1.2 构建 AlipayTradeQueryRequest 请求
- AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
- request.setBizModel(model);
- AlipayTradeQueryResponse response;
- if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
- // 证书模式
- response = client.certificateExecute(request);
- } else {
- response = client.execute(request);
- }
- if (!response.isSuccess()) { // 不成功,例如说订单不存在
- return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
- outTradeNo, response);
- }
- // 2.2 解析订单的状态
- Integer status = parseStatus(response.getTradeStatus());
- Assert.notNull(status, () -> {
- throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody()));
- });
- return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()),
- outTradeNo, response);
- }
-
- private static Integer parseStatus(String tradeStatus) {
- return Objects.equals("WAIT_BUYER_PAY", tradeStatus) ? PayOrderStatusRespEnum.WAITING.getStatus()
- : ObjectUtils.equalsAny(tradeStatus, "TRADE_FINISHED", "TRADE_SUCCESS") ? PayOrderStatusRespEnum.SUCCESS.getStatus()
- : Objects.equals("TRADE_CLOSED", tradeStatus) ? PayOrderStatusRespEnum.CLOSED.getStatus() : null;
- }
-
- // ============ 退款相关 ==========
-
- /**
- * 支付宝统一的退款接口 alipay.trade.refund
- *
- * @param reqDTO 退款请求 request DTO
- * @return 退款请求 Response
- */
- @Override
- protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws AlipayApiException {
- // 1.1 构建 AlipayTradeRefundModel 请求
- AlipayTradeRefundModel model = new AlipayTradeRefundModel();
- model.setOutTradeNo(reqDTO.getOutTradeNo());
- model.setOutRequestNo(reqDTO.getOutRefundNo());
- model.setRefundAmount(formatAmount(reqDTO.getRefundPrice()));
- model.setRefundReason(reqDTO.getReason());
- // 1.2 构建 AlipayTradePayRequest 请求
- AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
- request.setBizModel(model);
-
- // 2.1 执行请求
- AlipayTradeRefundResponse response;
- if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) { // 证书模式
- response = client.certificateExecute(request);
- } else {
- response = client.execute(request);
- }
- if (!response.isSuccess()) {
- // 当出现 ACQ.SYSTEM_ERROR, 退款可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
- if (ObjectUtils.equalsAny(response.getSubCode(), "ACQ.SYSTEM_ERROR", "SYSTEM_ERROR")) {
- return PayRefundRespDTO.waitingOf(null, reqDTO.getOutRefundNo(), response);
- }
- return PayRefundRespDTO.failureOf(response.getSubCode(), response.getSubMsg(), reqDTO.getOutRefundNo(), response);
- }
- // 2.2 创建返回结果
- // 支付宝只要退款调用返回 success,就认为退款成功,不需要回调。具体可见 parseNotify 方法的说明。
- // 另外,支付宝没有退款单号,所以不用设置
- return PayRefundRespDTO.successOf(null, LocalDateTimeUtil.of(response.getGmtRefundPay()),
- reqDTO.getOutRefundNo(), response);
- }
-
- @Override
- public PayRefundRespDTO doParseRefundNotify(Map params, String body) {
- // 补充说明:支付宝退款时,没有回调,这点和微信支付是不同的。并且,退款分成部分退款、和全部退款。
- // ① 部分退款:是会有回调,但是它回调的是订单状态的同步回调,不是退款订单的回调
- // ② 全部退款:Wap 支付有订单状态的同步回调,但是 PC/扫码又没有
- // 所以,这里在解析时,即使是退款导致的订单状态同步,我们也忽略不做为“退款同步”,而是订单的回调。
- // 实际上,支付宝退款只要发起成功,就可以认为退款成功,不需要等待回调。
- throw new UnsupportedOperationException("支付宝无退款回调");
- }
-
- @Override
- protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws AlipayApiException {
- // 1.1 构建 AlipayTradeFastpayRefundQueryModel 请求
- AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
- model.setOutTradeNo(outTradeNo);
- model.setOutRequestNo(outRefundNo);
- model.setQueryOptions(Collections.singletonList("gmt_refund_pay"));
- // 1.2 构建 AlipayTradeFastpayRefundQueryRequest 请求
- AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
- request.setBizModel(model);
-
- // 2.1 执行请求
- AlipayTradeFastpayRefundQueryResponse response;
- if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) { // 证书模式
- response = client.certificateExecute(request);
- } else {
- response = client.execute(request);
- }
- if (!response.isSuccess()) {
- // 明确不存在的情况,应该就是失败,可进行关闭
- if (ObjectUtils.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) {
- return PayRefundRespDTO.failureOf(outRefundNo, response);
- }
- // 可能存在“ACQ.SYSTEM_ERROR”系统错误等情况,所以返回 WAIT 继续等待
- return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
- }
- // 2.2 创建返回结果
- if (Objects.equals(response.getRefundStatus(), "REFUND_SUCCESS")) {
- return PayRefundRespDTO.successOf(null, LocalDateTimeUtil.of(response.getGmtRefundPay()),
- outRefundNo, response);
- }
- return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
- }
-
- @Override
- protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException {
- // 1.1 校验公钥类型 必须使用公钥证书模式
- if (!Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
- throw exception0(ERROR_CONFIGURATION.getCode(), "支付宝单笔转账必须使用公钥证书模式");
- }
- // 1.2 构建 AlipayFundTransUniTransferModel
- AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
- // ① 通用的参数
- model.setTransAmount(formatAmount(reqDTO.getPrice())); // 转账金额
- model.setOrderTitle(reqDTO.getSubject()); // 转账业务的标题,用于在支付宝用户的账单里显示。
- model.setOutBizNo(reqDTO.getOutTransferNo());
- model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD
- model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER
- if (reqDTO.getChannelExtras() != null) {
- model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras()));
- }
- // ② 个性化的参数
- Participant payeeInfo = new Participant();
- PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(reqDTO.getType());
- switch (transferType) {
- // TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦?
- // @芋艿。 是不是还要考虑转账到银行卡。所以传 transferType 但是转账到银行卡不知道要如何测试??
- case ALIPAY_BALANCE: {
- payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
- payeeInfo.setIdentity(reqDTO.getAlipayLogonId()); // 支付宝登录号
- payeeInfo.setName(reqDTO.getUserName()); // 支付宝账号姓名
- model.setPayeeInfo(payeeInfo);
- break;
- }
- case BANK_CARD: {
- payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
- // TODO 待实现
- throw exception(NOT_IMPLEMENTED);
- }
- default: {
- throw exception0(BAD_REQUEST.getCode(), "不正确的转账类型: {}", transferType);
- }
- }
- // 1.3 构建 AlipayFundTransUniTransferRequest
- AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
- request.setBizModel(model);
- // 执行请求
- AlipayFundTransUniTransferResponse response = client.certificateExecute(request);
- // 处理结果
- if (!response.isSuccess()) {
- // 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询,或相同 outBizNo 重新发起转账
- // 发现 outBizNo 相同 两次请求参数相同. 会返回 "PAYMENT_INFO_INCONSISTENCY", 不知道哪里的问题. 暂时返回 WAIT. 后续job 会轮询
- if (ObjectUtils.equalsAny(response.getSubCode(),"PAYMENT_INFO_INCONSISTENCY", "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
- return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response);
- }
- return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
- reqDTO.getOutTransferNo(), response);
- } else {
- if (ObjectUtils.equalsAny(response.getStatus(), "REFUND", "FAIL")) { // 转账到银行卡会出现 "REFUND" "FAIL"
- return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
- reqDTO.getOutTransferNo(), response);
- }
- if (Objects.equals(response.getStatus(), "DEALING")) { // 转账到银行卡会出现 "DEALING" 处理中
- return PayTransferRespDTO.dealingOf(response.getOrderId(), reqDTO.getOutTransferNo(), response);
- }
- return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()),
- response.getOutBizNo(), response);
- }
-
- }
-
- @Override
- protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) throws Throwable {
- // 1.1 构建 AlipayFundTransCommonQueryModel
- AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel();
- model.setProductCode(type == PayTransferTypeEnum.BANK_CARD ? "TRANS_BANKCARD_NO_PWD" : "TRANS_ACCOUNT_NO_PWD");
- model.setBizScene("DIRECT_TRANSFER"); //业务场景
- model.setOutBizNo(outTradeNo);
- // 1.2 构建 AlipayFundTransCommonQueryRequest
- AlipayFundTransCommonQueryRequest request = new AlipayFundTransCommonQueryRequest();
- request.setBizModel(model);
-
- // 2.1 执行请求
- AlipayFundTransCommonQueryResponse response;
- if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) { // 证书模式
- response = client.certificateExecute(request);
- } else {
- response = client.execute(request);
- }
- // 2.2 处理返回结果
- if (response.isSuccess()) {
- if (ObjectUtils.equalsAny(response.getStatus(), "REFUND", "FAIL")) { // 转账到银行卡会出现 "REFUND" "FAIL"
- return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
- outTradeNo, response);
- }
- if (Objects.equals(response.getStatus(), "DEALING")) { // 转账到银行卡会出现 "DEALING" 处理中
- return PayTransferRespDTO.dealingOf(response.getOrderId(), outTradeNo, response);
- }
- return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getPayDate()),
- response.getOutBizNo(), response);
- } else {
- // 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询, 或相同 outBizNo 重新发起转账
- // 当出现 ORDER_NOT_EXIST 可能是转账还在处理中,也可能是转账处理失败. 返回 WAIT 状态. 后续 job 会轮询, 或相同 outBizNo 重新发起转账
- if (ObjectUtils.equalsAny(response.getSubCode(), "ORDER_NOT_EXIST", "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
- return PayTransferRespDTO.waitingOf(null, outTradeNo, response);
- }
- return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
- outTradeNo, response);
- }
- }
-
- // ========== 各种工具方法 ==========
-
- protected String formatAmount(Integer amount) {
- return String.valueOf(amount / 100.0);
- }
-
- protected String formatTime(LocalDateTime time) {
- return LocalDateTimeUtil.format(time, NORM_DATETIME_FORMATTER);
- }
-
- protected LocalDateTime parseTime(String str) {
- return LocalDateTimeUtil.parse(str, NORM_DATETIME_FORMATTER);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java
deleted file mode 100644
index 4e5a37e9de..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-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.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.domain.AlipayTradeAppPayModel;
-import com.alipay.api.request.AlipayTradeAppPayRequest;
-import com.alipay.api.response.AlipayTradeAppPayResponse;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 支付宝【App 支付】的 PayClient 实现类
- *
- * 文档:App 支付
- *
- * // TODO 芋艿:未详细测试,因为手头没 App
- *
- * @author 芋道源码
- */
-@Slf4j
-public class AlipayAppPayClient extends AbstractAlipayPayClient {
-
- public AlipayAppPayClient(Long channelId, AlipayPayClientConfig config) {
- super(channelId, PayChannelEnum.ALIPAY_APP.getCode(), config);
- }
-
- @Override
- public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
- // 1.1 构建 AlipayTradeAppPayModel 请求
- AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
- // ① 通用的参数
- model.setOutTradeNo(reqDTO.getOutTradeNo());
- model.setSubject(reqDTO.getSubject());
- model.setBody(reqDTO.getBody() + "test");
- model.setTotalAmount(formatAmount(reqDTO.getPrice()));
- model.setTimeExpire(formatTime(reqDTO.getExpireTime()));
- model.setProductCode("QUICK_MSECURITY_PAY"); // 销售产品码:无线快捷支付产品
- // ② 个性化的参数【无】
- // ③ 支付宝扫码支付只有一种展示
- String displayMode = PayOrderDisplayModeEnum.APP.getMode();
-
- // 1.2 构建 AlipayTradePrecreateRequest 请求
- AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
- request.setBizModel(model);
- request.setNotifyUrl(reqDTO.getNotifyUrl());
- request.setReturnUrl(reqDTO.getReturnUrl());
-
- // 2.1 执行请求
- AlipayTradeAppPayResponse response = client.sdkExecute(request);
- // 2.2 处理结果
- if (!response.isSuccess()) {
- return buildClosedPayOrderRespDTO(reqDTO, response);
- }
- return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
- reqDTO.getOutTradeNo(), response);
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java
deleted file mode 100644
index 1f90d6b58e..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.hutool.core.date.LocalDateTimeUtil;
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.StrUtil;
-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.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.domain.AlipayTradePayModel;
-import com.alipay.api.request.AlipayTradePayRequest;
-import com.alipay.api.response.AlipayTradePayResponse;
-import lombok.extern.slf4j.Slf4j;
-
-import java.time.LocalDateTime;
-import java.util.Objects;
-
-import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
-import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
-
-/**
- * 支付宝【条码支付】的 PayClient 实现类
- *
- * 文档:当面付
- *
- * @author 芋道源码
- */
-@Slf4j
-public class AlipayBarPayClient extends AbstractAlipayPayClient {
-
- public AlipayBarPayClient(Long channelId, AlipayPayClientConfig config) {
- super(channelId, PayChannelEnum.ALIPAY_BAR.getCode(), config);
- }
-
- @Override
- public PayOrderRespDTO 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 请求
- AlipayTradePayModel model = new AlipayTradePayModel();
- // ① 通用的参数
- model.setOutTradeNo(reqDTO.getOutTradeNo());
- model.setSubject(reqDTO.getSubject());
- model.setBody(reqDTO.getBody());
- model.setTotalAmount(formatAmount(reqDTO.getPrice()));
- model.setScene("bar_code"); // 当面付条码支付场景
- // ② 个性化的参数
- model.setAuthCode(authCode);
- // ③ 支付宝条码支付只有一种展示
- String displayMode = PayOrderDisplayModeEnum.BAR_CODE.getMode();
-
- // 1.2 构建 AlipayTradePayRequest 请求
- AlipayTradePayRequest request = new AlipayTradePayRequest();
- request.setBizModel(model);
- request.setNotifyUrl(reqDTO.getNotifyUrl());
- request.setReturnUrl(reqDTO.getReturnUrl());
-
- // 2.1 执行请求
- AlipayTradePayResponse response;
- if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
- // 证书模式
- response = client.certificateExecute(request);
- } else {
- response = client.execute(request);
- }
- // 2.2 处理结果
- if (!response.isSuccess()) {
- return buildClosedPayOrderRespDTO(reqDTO, response);
- }
- if ("10000".equals(response.getCode())) { // 免密支付
- LocalDateTime successTime = LocalDateTimeUtil.of(response.getGmtPayment());
- return PayOrderRespDTO.successOf(response.getTradeNo(), response.getBuyerUserId(), successTime,
- response.getOutTradeNo(), response)
- .setDisplayMode(displayMode).setDisplayContent("");
- }
- // 大额支付,需要用户输入密码,所以返回 waiting。此时,前端一般会进行轮询
- return PayOrderRespDTO.waitingOf(displayMode, "",
- reqDTO.getOutTradeNo(), response);
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java
deleted file mode 100644
index 13f2885d40..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
-import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
-import lombok.Data;
-
-import jakarta.validation.Validator;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-
-/**
- * 支付宝的 PayClientConfig 实现类
- * 属性主要来自 {@link com.alipay.api.AlipayConfig} 的必要属性
- *
- * @author 芋道源码
- */
-@Data
-public class AlipayPayClientConfig implements PayClientConfig {
-
- /**
- * 公钥类型 - 公钥模式
- */
- public static final Integer MODE_PUBLIC_KEY = 1;
- /**
- * 公钥类型 - 证书模式
- */
- public static final Integer MODE_CERTIFICATE = 2;
-
- /**
- * 签名算法类型 - RSA
- */
- public static final String SIGN_TYPE_DEFAULT = "RSA2";
-
- /**
- * 网关地址
- *
- * 1. 生产环境
- * 2. 沙箱环境
- */
- @NotBlank(message = "网关地址不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
- private String serverUrl;
-
- /**
- * 开放平台上创建的应用的 ID
- */
- @NotBlank(message = "开放平台上创建的应用的 ID不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
- private String appId;
-
- /**
- * 签名算法类型,推荐:RSA2
- *
- * {@link #SIGN_TYPE_DEFAULT}
- */
- @NotBlank(message = "签名算法类型不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
- private String signType;
-
- /**
- * 公钥类型
- * 1. {@link #MODE_PUBLIC_KEY} 情况,privateKey + alipayPublicKey
- * 2. {@link #MODE_CERTIFICATE} 情况,appCertContent + alipayPublicCertContent + rootCertContent
- */
- @NotNull(message = "公钥类型不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
- private Integer mode;
-
- // ========== 公钥模式 ==========
- /**
- * 商户私钥
- */
- @NotBlank(message = "商户私钥不能为空", groups = {ModePublicKey.class})
- private String privateKey;
-
- /**
- * 支付宝公钥字符串
- */
- @NotBlank(message = "支付宝公钥字符串不能为空", groups = {ModePublicKey.class})
- private String alipayPublicKey;
-
- // ========== 证书模式 ==========
- /**
- * 指定商户公钥应用证书内容字符串
- */
- @NotBlank(message = "指定商户公钥应用证书内容不能为空", groups = {ModeCertificate.class})
- private String appCertContent;
- /**
- * 指定支付宝公钥证书内容字符串
- */
- @NotBlank(message = "指定支付宝公钥证书内容不能为空", groups = {ModeCertificate.class})
- private String alipayPublicCertContent;
- /**
- * 指定根证书内容字符串
- */
- @NotBlank(message = "指定根证书内容字符串不能为空", groups = {ModeCertificate.class})
- private String rootCertContent;
-
- public interface ModePublicKey {
- }
-
- public interface ModeCertificate {
- }
-
- @Override
- public void validate(Validator validator) {
- ValidationUtils.validate(validator, this,
- MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java
deleted file mode 100644
index 6dbd19bef3..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.http.Method;
-import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
-import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
-import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.domain.AlipayTradePagePayModel;
-import com.alipay.api.request.AlipayTradePagePayRequest;
-import com.alipay.api.response.AlipayTradePagePayResponse;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.Objects;
-
-/**
- * 支付宝【PC 网站】的 PayClient 实现类
- *
- * 文档:电脑网站支付
- *
- * @author XGD
- */
-@Slf4j
-public class AlipayPcPayClient extends AbstractAlipayPayClient {
-
- public AlipayPcPayClient(Long channelId, AlipayPayClientConfig config) {
- super(channelId, PayChannelEnum.ALIPAY_PC.getCode(), config);
- }
-
- @Override
- public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
- // 1.1 构建 AlipayTradePagePayModel 请求
- AlipayTradePagePayModel model = new AlipayTradePagePayModel();
- // ① 通用的参数
- model.setOutTradeNo(reqDTO.getOutTradeNo());
- model.setSubject(reqDTO.getSubject());
- model.setBody(reqDTO.getBody());
- model.setTotalAmount(formatAmount(reqDTO.getPrice()));
- model.setTimeExpire(formatTime(reqDTO.getExpireTime()));
- model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 销售产品码. 目前 PC 支付场景下仅支持 FAST_INSTANT_TRADE_PAY
- // ② 个性化的参数
- // 如果想弄更多个性化的参数,可参考 https://www.pingxx.com/api/支付渠道 extra 参数说明.html 的 alipay_pc_direct 部分进行拓展
- model.setQrPayMode("2"); // 跳转模式 - 订单码,效果参见:https://help.pingxx.com/article/1137360/
- // ③ 支付宝 PC 支付有两种展示模式:FORM、URL
- String displayMode = ObjectUtil.defaultIfNull(reqDTO.getDisplayMode(),
- PayOrderDisplayModeEnum.URL.getMode());
-
- // 1.2 构建 AlipayTradePagePayRequest 请求
- AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
- request.setBizModel(model);
- request.setNotifyUrl(reqDTO.getNotifyUrl());
- request.setReturnUrl(reqDTO.getReturnUrl());
-
- // 2.1 执行请求
- AlipayTradePagePayResponse response;
- if (Objects.equals(displayMode, PayOrderDisplayModeEnum.FORM.getMode())) {
- response = client.pageExecute(request, Method.POST.name()); // 需要特殊使用 POST 请求
- } else {
- response = client.pageExecute(request, Method.GET.name());
- }
- // 2.2 处理结果
- if (!response.isSuccess()) {
- return buildClosedPayOrderRespDTO(reqDTO, response);
- }
- return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
- reqDTO.getOutTradeNo(), response);
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java
deleted file mode 100644
index bb3ad17713..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-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.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.domain.AlipayTradePrecreateModel;
-import com.alipay.api.request.AlipayTradePrecreateRequest;
-import com.alipay.api.response.AlipayTradePrecreateResponse;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.Objects;
-
-import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
-
-/**
- * 支付宝【扫码支付】的 PayClient 实现类
- *
- * 文档:扫码支付
- *
- * @author 芋道源码
- */
-@Slf4j
-public class AlipayQrPayClient extends AbstractAlipayPayClient {
-
- public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) {
- super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config);
- }
-
- @Override
- public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
- // 1.1 构建 AlipayTradePrecreateModel 请求
- AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
- // ① 通用的参数
- model.setOutTradeNo(reqDTO.getOutTradeNo());
- model.setSubject(reqDTO.getSubject());
- model.setBody(reqDTO.getBody());
- model.setTotalAmount(formatAmount(reqDTO.getPrice()));
- model.setProductCode("FACE_TO_FACE_PAYMENT"); // 销售产品码. 目前扫码支付场景下仅支持 FACE_TO_FACE_PAYMENT
- // ② 个性化的参数【无】
- // ③ 支付宝扫码支付只有一种展示,考虑到前端可能希望二维码扫描后,手机打开
- String displayMode = PayOrderDisplayModeEnum.QR_CODE.getMode();
-
- // 1.2 构建 AlipayTradePrecreateRequest 请求
- AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
- request.setBizModel(model);
- request.setNotifyUrl(reqDTO.getNotifyUrl());
- request.setReturnUrl(reqDTO.getReturnUrl());
-
- // 2.1 执行请求
- AlipayTradePrecreateResponse response;
- if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
- // 证书模式
- response = client.certificateExecute(request);
- } else {
- response = client.execute(request);
- }
- // 2.2 处理结果
- if (!response.isSuccess()) {
- return buildClosedPayOrderRespDTO(reqDTO, response);
- }
- return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(),
- reqDTO.getOutTradeNo(), response);
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
deleted file mode 100644
index f9dccf5a7e..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.hutool.http.Method;
-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.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.domain.AlipayTradeWapPayModel;
-import com.alipay.api.request.AlipayTradeWapPayRequest;
-import com.alipay.api.response.AlipayTradeWapPayResponse;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 支付宝【Wap 网站】的 PayClient 实现类
- *
- * 文档:手机网站支付接口
- *
- * @author 芋道源码
- */
-@Slf4j
-public class AlipayWapPayClient extends AbstractAlipayPayClient {
-
- public AlipayWapPayClient(Long channelId, AlipayPayClientConfig config) {
- super(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config);
- }
-
- @Override
- public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
- // 1.1 构建 AlipayTradeWapPayModel 请求
- AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
- // ① 通用的参数
- model.setOutTradeNo(reqDTO.getOutTradeNo());
- model.setSubject(reqDTO.getSubject());
- model.setBody(reqDTO.getBody());
- model.setTotalAmount(formatAmount(reqDTO.getPrice()));
- model.setProductCode("QUICK_WAP_PAY"); // 销售产品码. 目前 Wap 支付场景下仅支持 QUICK_WAP_PAY
- // ② 个性化的参数【无】
- // ③ 支付宝 Wap 支付只有一种展示:URL
- String displayMode = PayOrderDisplayModeEnum.URL.getMode();
-
- // 1.2 构建 AlipayTradeWapPayRequest 请求
- AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
- request.setBizModel(model);
- request.setNotifyUrl(reqDTO.getNotifyUrl());
- request.setReturnUrl(reqDTO.getReturnUrl());
- model.setQuitUrl(reqDTO.getReturnUrl());
-
- // 2.1 执行请求
- AlipayTradeWapPayResponse response = client.pageExecute(request, Method.GET.name());
- // 2.2 处理结果
- if (!response.isSuccess()) {
- return buildClosedPayOrderRespDTO(reqDTO, response);
- }
- return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
- reqDTO.getOutTradeNo(), response);
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
deleted file mode 100644
index 1ad1ad7134..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
+++ /dev/null
@@ -1,80 +0,0 @@
-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.dto.transfer.PayTransferRespDTO;
-import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
-import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
-import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
-import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
-
-import java.time.LocalDateTime;
-import java.util.Map;
-
-/**
- * 模拟支付的 PayClient 实现类
- *
- * 模拟支付返回结果都是成功,方便大家日常流畅
- *
- * @author jason
- */
-public class MockPayClient extends AbstractPayClient {
-
- private static final String MOCK_RESP_SUCCESS_DATA = "MOCK_SUCCESS";
-
- public MockPayClient(Long channelId, NonePayClientConfig 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 params, String body) {
- throw new UnsupportedOperationException("模拟支付无退款回调");
- }
-
- @Override
- protected PayOrderRespDTO doParseOrderNotify(Map params, String body) {
- throw new UnsupportedOperationException("模拟支付无支付回调");
- }
-
- @Override
- protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
- throw new UnsupportedOperationException("待实现");
- }
-
- @Override
- protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) {
- throw new UnsupportedOperationException("待实现");
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
deleted file mode 100644
index ada1f42e6e..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
+++ /dev/null
@@ -1,483 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.codec.Base64;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.date.LocalDateTimeUtil;
-import cn.hutool.core.date.TemporalAccessorUtil;
-import cn.hutool.core.util.StrUtil;
-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.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.dto.transfer.PayTransferRespDTO;
-import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
-import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
-import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
-import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
-import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
-import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
-import com.github.binarywang.wxpay.bean.request.*;
-import com.github.binarywang.wxpay.bean.result.*;
-import com.github.binarywang.wxpay.config.WxPayConfig;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import com.github.binarywang.wxpay.service.WxPayService;
-import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
-import lombok.extern.slf4j.Slf4j;
-
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.Map;
-import java.util.Objects;
-
-import static cn.hutool.core.date.DatePattern.*;
-import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig.API_VERSION_V2;
-
-/**
- * 微信支付抽象类,实现微信统一的接口、以及部分实现(退款)
- *
- * @author 遇到源码
- */
-@Slf4j
-public abstract class AbstractWxPayClient extends AbstractPayClient {
-
- protected WxPayService client;
-
- public AbstractWxPayClient(Long channelId, String channelCode, WxPayClientConfig config) {
- super(channelId, channelCode, config);
- }
-
- /**
- * 初始化 client 客户端
- *
- * @param tradeType 交易类型
- */
- protected void doInit(String tradeType) {
- // 创建 config 配置
- WxPayConfig payConfig = new WxPayConfig();
- BeanUtil.copyProperties(config, payConfig, "keyContent", "privateKeyContent", "privateCertContent");
- payConfig.setTradeType(tradeType);
- // weixin-pay-java 无法设置内容,只允许读取文件,所以这里要创建临时文件来解决
- if (Base64.isBase64(config.getKeyContent())) {
- payConfig.setKeyPath(FileUtils.createTempFile(Base64.decode(config.getKeyContent())).getPath());
- }
- if (StrUtil.isNotEmpty(config.getPrivateKeyContent())) {
- payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
- }
- if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
- payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
- }
-
- // 创建 client 客户端
- client = new WxPayServiceImpl();
- client.setConfig(payConfig);
- }
-
- // ============ 支付相关 ==========
-
- @Override
- protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Exception {
- try {
- switch (config.getApiVersion()) {
- case API_VERSION_V2:
- return doUnifiedOrderV2(reqDTO);
- case WxPayClientConfig.API_VERSION_V3:
- return doUnifiedOrderV3(reqDTO);
- default:
- throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
- }
- } catch (WxPayException e) {
- String errorCode = getErrorCode(e);
- String errorMessage = getErrorMessage(e);
- return PayOrderRespDTO.closedOf(errorCode, errorMessage,
- reqDTO.getOutTradeNo(), e.getXmlString());
- }
- }
-
- /**
- * 【V2】调用支付渠道,统一下单
- *
- * @param reqDTO 下单信息
- * @return 各支付渠道的返回结果
- */
- protected abstract PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO)
- throws Exception;
-
- /**
- * 【V3】调用支付渠道,统一下单
- *
- * @param reqDTO 下单信息
- * @return 各支付渠道的返回结果
- */
- protected abstract PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO)
- throws WxPayException;
-
- /**
- * 【V2】创建微信下单请求
- *
- * @param reqDTO 下信息
- * @return 下单请求
- */
- protected WxPayUnifiedOrderRequest buildPayUnifiedOrderRequestV2(PayOrderUnifiedReqDTO reqDTO) {
- return WxPayUnifiedOrderRequest.newBuilder()
- .outTradeNo(reqDTO.getOutTradeNo())
- .body(reqDTO.getSubject())
- .detail(reqDTO.getBody())
- .totalFee(reqDTO.getPrice()) // 单位分
- .timeExpire(formatDateV2(reqDTO.getExpireTime()))
- .spbillCreateIp(reqDTO.getUserIp())
- .notifyUrl(reqDTO.getNotifyUrl())
- .build();
- }
-
- /**
- * 【V3】创建微信下单请求
- *
- * @param reqDTO 下信息
- * @return 下单请求
- */
- protected WxPayUnifiedOrderV3Request buildPayUnifiedOrderRequestV3(PayOrderUnifiedReqDTO reqDTO) {
- WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
- request.setOutTradeNo(reqDTO.getOutTradeNo());
- request.setDescription(reqDTO.getSubject());
- request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getPrice())); // 单位分
- request.setTimeExpire(formatDateV3(reqDTO.getExpireTime()));
- request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
- request.setNotifyUrl(reqDTO.getNotifyUrl());
- return request;
- }
-
- @Override
- public PayOrderRespDTO doParseOrderNotify(Map params, String body) throws WxPayException {
- switch (config.getApiVersion()) {
- case API_VERSION_V2:
- return doParseOrderNotifyV2(body);
- case WxPayClientConfig.API_VERSION_V3:
- return doParseOrderNotifyV3(body);
- default:
- throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
- }
- }
-
- private PayOrderRespDTO doParseOrderNotifyV2(String body) throws WxPayException {
- // 1. 解析回调
- WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body);
- // 2. 构建结果
- // V2 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂
- Integer status = Objects.equals(response.getResultCode(), "SUCCESS") ?
- PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus();
- return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
- response.getOutTradeNo(), body);
- }
-
- private PayOrderRespDTO doParseOrderNotifyV3(String body) throws WxPayException {
- // 1. 解析回调
- WxPayNotifyV3Result response = client.parseOrderNotifyV3Result(body, null);
- WxPayNotifyV3Result.DecryptNotifyResult result = response.getResult();
- // 2. 构建结果
- Integer status = parseStatus(result.getTradeState());
- String openid = result.getPayer() != null ? result.getPayer().getOpenid() : null;
- return PayOrderRespDTO.of(status, result.getTransactionId(), openid, parseDateV3(result.getSuccessTime()),
- result.getOutTradeNo(), body);
- }
-
- @Override
- protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable {
- try {
- switch (config.getApiVersion()) {
- case API_VERSION_V2:
- return doGetOrderV2(outTradeNo);
- case WxPayClientConfig.API_VERSION_V3:
- return doGetOrderV3(outTradeNo);
- default:
- throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
- }
- } catch (WxPayException e) {
- if (ObjectUtils.equalsAny(e.getErrCode(), "ORDERNOTEXIST", "ORDER_NOT_EXIST")) {
- String errorCode = getErrorCode(e);
- String errorMessage = getErrorMessage(e);
- return PayOrderRespDTO.closedOf(errorCode, errorMessage,
- outTradeNo, e.getXmlString());
- }
- throw e;
- }
- }
-
- private PayOrderRespDTO doGetOrderV2(String outTradeNo) throws WxPayException {
- // 构建 WxPayUnifiedOrderRequest 对象
- WxPayOrderQueryRequest request = WxPayOrderQueryRequest.newBuilder()
- .outTradeNo(outTradeNo).build();
- // 执行请求
- WxPayOrderQueryResult response = client.queryOrder(request);
-
- // 转换结果
- Integer status = parseStatus(response.getTradeState());
- return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
- outTradeNo, response);
- }
-
- private PayOrderRespDTO doGetOrderV3(String outTradeNo) throws WxPayException {
- // 构建 WxPayUnifiedOrderRequest 对象
- WxPayOrderQueryV3Request request = new WxPayOrderQueryV3Request()
- .setOutTradeNo(outTradeNo);
- // 执行请求
- WxPayOrderQueryV3Result response = client.queryOrderV3(request);
-
- // 转换结果
- Integer status = parseStatus(response.getTradeState());
- String openid = response.getPayer() != null ? response.getPayer().getOpenid() : null;
- return PayOrderRespDTO.of(status, response.getTransactionId(), openid, parseDateV3(response.getSuccessTime()),
- outTradeNo, response);
- }
-
- private static Integer parseStatus(String tradeState) {
- switch (tradeState) {
- case "NOTPAY":
- case "USERPAYING": // 支付中,等待用户输入密码(条码支付独有)
- return PayOrderStatusRespEnum.WAITING.getStatus();
- case "SUCCESS":
- return PayOrderStatusRespEnum.SUCCESS.getStatus();
- case "REFUND":
- return PayOrderStatusRespEnum.REFUND.getStatus();
- case "CLOSED":
- case "REVOKED": // 已撤销(刷卡支付独有)
- case "PAYERROR": // 支付失败(其它原因,如银行返回失败)
- return PayOrderStatusRespEnum.CLOSED.getStatus();
- default:
- throw new IllegalArgumentException(StrUtil.format("未知的支付状态({})", tradeState));
- }
- }
-
- // ============ 退款相关 ==========
-
- @Override
- protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
- try {
- switch (config.getApiVersion()) {
- case API_VERSION_V2:
- return doUnifiedRefundV2(reqDTO);
- case WxPayClientConfig.API_VERSION_V3:
- return doUnifiedRefundV3(reqDTO);
- default:
- throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
- }
- } catch (WxPayException e) {
- String errorCode = getErrorCode(e);
- String errorMessage = getErrorMessage(e);
- return PayRefundRespDTO.failureOf(errorCode, errorMessage,
- reqDTO.getOutTradeNo(), e.getXmlString());
- }
- }
-
- private PayRefundRespDTO doUnifiedRefundV2(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
- // 1. 构建 WxPayRefundRequest 请求
- WxPayRefundRequest request = new WxPayRefundRequest()
- .setOutTradeNo(reqDTO.getOutTradeNo())
- .setOutRefundNo(reqDTO.getOutRefundNo())
- .setRefundFee(reqDTO.getRefundPrice())
- .setRefundDesc(reqDTO.getReason())
- .setTotalFee(reqDTO.getPayPrice())
- .setNotifyUrl(reqDTO.getNotifyUrl());
- // 2.1 执行请求
- WxPayRefundResult response = client.refundV2(request);
- // 2.2 创建返回结果
- if (Objects.equals("SUCCESS", response.getResultCode())) { // V2 情况下,不直接返回退款成功,而是等待异步通知
- return PayRefundRespDTO.waitingOf(response.getRefundId(),
- reqDTO.getOutRefundNo(), response);
- }
- return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
- }
-
- private PayRefundRespDTO doUnifiedRefundV3(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
- // 1. 构建 WxPayRefundRequest 请求
- WxPayRefundV3Request request = new WxPayRefundV3Request()
- .setOutTradeNo(reqDTO.getOutTradeNo())
- .setOutRefundNo(reqDTO.getOutRefundNo())
- .setAmount(new WxPayRefundV3Request.Amount().setRefund(reqDTO.getRefundPrice())
- .setTotal(reqDTO.getPayPrice()).setCurrency("CNY"))
- .setReason(reqDTO.getReason())
- .setNotifyUrl(reqDTO.getNotifyUrl());
- // 2.1 执行请求
- WxPayRefundV3Result response = client.refundV3(request);
- // 2.2 创建返回结果
- if (Objects.equals("SUCCESS", response.getStatus())) {
- return PayRefundRespDTO.successOf(response.getRefundId(), parseDateV3(response.getSuccessTime()),
- reqDTO.getOutRefundNo(), response);
- }
- if (Objects.equals("PROCESSING", response.getStatus())) {
- return PayRefundRespDTO.waitingOf(response.getRefundId(),
- reqDTO.getOutRefundNo(), response);
- }
- return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
- }
-
- @Override
- public PayRefundRespDTO doParseRefundNotify(Map params, String body) throws WxPayException {
- switch (config.getApiVersion()) {
- case API_VERSION_V2:
- return doParseRefundNotifyV2(body);
- case WxPayClientConfig.API_VERSION_V3:
- return parseRefundNotifyV3(body);
- default:
- throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
- }
- }
-
- private PayRefundRespDTO doParseRefundNotifyV2(String body) throws WxPayException {
- // 1. 解析回调
- WxPayRefundNotifyResult response = client.parseRefundNotifyResult(body);
- WxPayRefundNotifyResult.ReqInfo result = response.getReqInfo();
- // 2. 构建结果
- if (Objects.equals("SUCCESS", result.getRefundStatus())) {
- return PayRefundRespDTO.successOf(result.getRefundId(), parseDateV2B(result.getSuccessTime()),
- result.getOutRefundNo(), response);
- }
- return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response);
- }
-
- private PayRefundRespDTO parseRefundNotifyV3(String body) throws WxPayException {
- // 1. 解析回调
- WxPayRefundNotifyV3Result response = client.parseRefundNotifyV3Result(body, null);
- WxPayRefundNotifyV3Result.DecryptNotifyResult result = response.getResult();
- // 2. 构建结果
- if (Objects.equals("SUCCESS", result.getRefundStatus())) {
- return PayRefundRespDTO.successOf(result.getRefundId(), parseDateV3(result.getSuccessTime()),
- result.getOutRefundNo(), response);
- }
- return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response);
- }
-
- @Override
- protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws WxPayException {
- try {
- switch (config.getApiVersion()) {
- case API_VERSION_V2:
- return doGetRefundV2(outTradeNo, outRefundNo);
- case WxPayClientConfig.API_VERSION_V3:
- return doGetRefundV3(outTradeNo, outRefundNo);
- default:
- throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
- }
- } catch (WxPayException e) {
- if (ObjectUtils.equalsAny(e.getErrCode(), "REFUNDNOTEXIST", "RESOURCE_NOT_EXISTS")) {
- String errorCode = getErrorCode(e);
- String errorMessage = getErrorMessage(e);
- return PayRefundRespDTO.failureOf(errorCode, errorMessage,
- outRefundNo, e.getXmlString());
- }
- throw e;
- }
- }
-
- private PayRefundRespDTO doGetRefundV2(String outTradeNo, String outRefundNo) throws WxPayException {
- // 1. 构建 WxPayRefundRequest 请求
- WxPayRefundQueryRequest request = WxPayRefundQueryRequest.newBuilder()
- .outTradeNo(outTradeNo)
- .outRefundNo(outRefundNo)
- .build();
- // 2.1 执行请求
- WxPayRefundQueryResult response = client.refundQuery(request);
- // 2.2 创建返回结果
- if (!Objects.equals("SUCCESS", response.getResultCode())) {
- return PayRefundRespDTO.waitingOf(null,
- outRefundNo, response);
- }
- WxPayRefundQueryResult.RefundRecord refund = CollUtil.findOne(response.getRefundRecords(),
- record -> record.getOutRefundNo().equals(outRefundNo));
- if (refund == null) {
- return PayRefundRespDTO.failureOf(outRefundNo, response);
- }
- switch (refund.getRefundStatus()) {
- case "SUCCESS":
- return PayRefundRespDTO.successOf(refund.getRefundId(), parseDateV2B(refund.getRefundSuccessTime()),
- outRefundNo, response);
- case "PROCESSING":
- return PayRefundRespDTO.waitingOf(refund.getRefundId(),
- outRefundNo, response);
- case "CHANGE": // 退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转账的方式进行退款
- case "FAIL":
- return PayRefundRespDTO.failureOf(outRefundNo, response);
- default:
- throw new IllegalArgumentException(String.format("未知的退款状态(%s)", refund.getRefundStatus()));
- }
- }
-
- private PayRefundRespDTO doGetRefundV3(String outTradeNo, String outRefundNo) throws WxPayException {
- // 1. 构建 WxPayRefundRequest 请求
- WxPayRefundQueryV3Request request = new WxPayRefundQueryV3Request();
- request.setOutRefundNo(outRefundNo);
- // 2.1 执行请求
- WxPayRefundQueryV3Result response = client.refundQueryV3(request);
- // 2.2 创建返回结果
- switch (response.getStatus()) {
- case "SUCCESS":
- return PayRefundRespDTO.successOf(response.getRefundId(), parseDateV3(response.getSuccessTime()),
- outRefundNo, response);
- case "PROCESSING":
- return PayRefundRespDTO.waitingOf(response.getRefundId(),
- outRefundNo, response);
- case "ABNORMAL": // 退款异常
- case "CLOSED":
- return PayRefundRespDTO.failureOf(outRefundNo, response);
- default:
- throw new IllegalArgumentException(String.format("未知的退款状态(%s)", response.getStatus()));
- }
- }
-
- @Override
- protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
- throw new UnsupportedOperationException("待实现");
- }
-
- @Override
- protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) {
- throw new UnsupportedOperationException("待实现");
- }
-
- // ========== 各种工具方法 ==========
-
- static String formatDateV2(LocalDateTime time) {
- return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), PURE_DATETIME_PATTERN);
- }
-
- static LocalDateTime parseDateV2(String time) {
- return LocalDateTimeUtil.parse(time, PURE_DATETIME_PATTERN);
- }
-
- static LocalDateTime parseDateV2B(String time) {
- return LocalDateTimeUtil.parse(time, NORM_DATETIME_PATTERN);
- }
-
- static String formatDateV3(LocalDateTime time) {
- return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), UTC_WITH_XXX_OFFSET_PATTERN);
- }
-
- static LocalDateTime parseDateV3(String time) {
- return LocalDateTimeUtil.parse(time, UTC_WITH_XXX_OFFSET_PATTERN);
- }
-
- static String getErrorCode(WxPayException e) {
- if (StrUtil.isNotEmpty(e.getErrCode())) {
- return e.getErrCode();
- }
- if (StrUtil.isNotEmpty(e.getCustomErrorMsg())) {
- return "CUSTOM_ERROR";
- }
- return e.getReturnCode();
- }
-
- static String getErrorMessage(WxPayException e) {
- if (StrUtil.isNotEmpty(e.getErrCode())) {
- return e.getErrCodeDes();
- }
- if (StrUtil.isNotEmpty(e.getCustomErrorMsg())) {
- return e.getCustomErrorMsg();
- }
- return e.getReturnMsg();
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxAppPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxAppPayClient.java
deleted file mode 100644
index 396694a75b..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxAppPayClient.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-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.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
-import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
-import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
-import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
-import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
-import com.github.binarywang.wxpay.constant.WxPayConstants;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import lombok.extern.slf4j.Slf4j;
-
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
-
-/**
- * 微信支付【App 支付】的 PayClient 实现类
- *
- * 文档:App 支付
- *
- * // TODO 芋艿:未详细测试,因为手头没 App
- *
- * @author 芋道源码
- */
-@Slf4j
-public class WxAppPayClient extends AbstractWxPayClient {
-
- public WxAppPayClient(Long channelId, WxPayClientConfig config) {
- super(channelId, PayChannelEnum.WX_APP.getCode(), config);
- }
-
- @Override
- protected void doInit() {
- super.doInit(WxPayConstants.TradeType.APP);
- }
-
- @Override
- protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
- // 构建 WxPayUnifiedOrderRequest 对象
- WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO);
- // 执行请求
- WxPayMpOrderResult response = client.createOrder(request);
-
- // 转换结果
- return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
- reqDTO.getOutTradeNo(), response);
- }
-
- @Override
- protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
- // 构建 WxPayUnifiedOrderV3Request 对象
- WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO);
- // 执行请求
- WxPayUnifiedOrderV3Result.AppResult response = client.createOrderV3(TradeTypeEnum.APP, request);
-
- // 转换结果
- return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
- reqDTO.getOutTradeNo(), response);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClient.java
deleted file mode 100644
index d01b504050..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClient.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.thread.ThreadUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
-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.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
-import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
-import com.github.binarywang.wxpay.constant.WxPayConstants;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import lombok.extern.slf4j.Slf4j;
-
-import java.time.Duration;
-import java.time.LocalDateTime;
-import java.util.concurrent.TimeUnit;
-
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
-
-/**
- * 微信支付【付款码支付】的 PayClient 实现类
- *
- * 文档:付款码支付
- *
- * @author 芋道源码
- */
-@Slf4j
-public class WxBarPayClient extends AbstractWxPayClient {
-
- /**
- * 微信付款码的过期时间
- */
- private static final Duration AUTH_CODE_EXPIRE = Duration.ofMinutes(3);
-
- public WxBarPayClient(Long channelId, WxPayClientConfig config) {
- super(channelId, PayChannelEnum.WX_BAR.getCode(), config);
- }
-
- @Override
- protected void doInit() {
- super.doInit(WxPayConstants.TradeType.MICROPAY);
- }
-
- @Override
- protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
- // 由于付款码需要不断轮询,所以需要在较短的时间完成支付
- LocalDateTime expireTime = LocalDateTimeUtils.addTime(AUTH_CODE_EXPIRE);
- if (expireTime.isAfter(reqDTO.getExpireTime())) {
- expireTime = reqDTO.getExpireTime();
- }
- // 构建 WxPayMicropayRequest 对象
- WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
- .outTradeNo(reqDTO.getOutTradeNo())
- .body(reqDTO.getSubject())
- .detail(reqDTO.getBody())
- .totalFee(reqDTO.getPrice()) // 单位分
- .timeExpire(formatDateV2(expireTime))
- .spbillCreateIp(reqDTO.getUserIp())
- .authCode(getAuthCode(reqDTO))
- .build();
- // 执行请求,重试直到失败(过期),或者成功
- WxPayException lastWxPayException = null;
- for (int i = 1; i < Byte.MAX_VALUE; i++) {
- try {
- WxPayMicropayResult response = client.micropay(request);
- // 支付成功,例如说:1)用户输入了密码;2)用户免密支付
- return PayOrderRespDTO.successOf(response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
- response.getOutTradeNo(), response)
- .setDisplayMode(PayOrderDisplayModeEnum.BAR_CODE.getMode());
- } catch (WxPayException ex) {
- lastWxPayException = ex;
- // 如果不满足这 3 种任一的,则直接抛出 WxPayException 异常,不仅需处理
- // 1. SYSTEMERROR:接口返回错误:请立即调用被扫订单结果查询API,查询当前订单状态,并根据订单的状态决定下一步的操作。
- // 2. USERPAYING:用户支付中,需要输入密码:等待 5 秒,然后调用被扫订单结果查询 API,查询当前订单的不同状态,决定下一步的操作。
- // 3. BANKERROR:银行系统异常:请立即调用被扫订单结果查询 API,查询当前订单的不同状态,决定下一步的操作。
- if (!StrUtil.equalsAny(ex.getErrCode(), "SYSTEMERROR", "USERPAYING", "BANKERROR")) {
- throw ex;
- }
- // 等待 5 秒,继续下一轮重新发起支付
- log.info("[doUnifiedOrderV2][发起微信 Bar 支付第({})失败,等待下一轮重试,请求({}),响应({})]", i,
- toJsonString(request), ex.getMessage());
- ThreadUtil.sleep(5, TimeUnit.SECONDS);
- }
- }
- throw lastWxPayException;
- }
-
- @Override
- protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
- return doUnifiedOrderV2(reqDTO);
- }
-
- // ========== 各种工具方法 ==========
-
- static String getAuthCode(PayOrderUnifiedReqDTO reqDTO) {
- String authCode = MapUtil.getStr(reqDTO.getChannelExtras(), "authCode");
- if (StrUtil.isEmpty(authCode)) {
- throw invalidParamException("支付请求的 authCode 不能为空!");
- }
- return authCode;
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxLitePayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxLitePayClient.java
deleted file mode 100644
index 9929955ae2..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxLitePayClient.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 微信支付【小程序】的 PayClient 实现类
- *
- * 由于公众号和小程序的微信支付逻辑一致,所以直接进行继承
- *
- * 文档:JSAPI 下单>
- *
- * @author zwy
- */
-@Slf4j
-public class WxLitePayClient extends WxPubPayClient {
-
- public WxLitePayClient(Long channelId, WxPayClientConfig config) {
- super(channelId, PayChannelEnum.WX_LITE.getCode(), config);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClient.java
deleted file mode 100644
index 5a073501d4..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClient.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-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.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
-import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
-import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
-import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
-import com.github.binarywang.wxpay.constant.WxPayConstants;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 微信支付【Native 二维码】的 PayClient 实现类
- *
- * 文档:Native 下单
- *
- * @author zwy
- */
-@Slf4j
-public class WxNativePayClient extends AbstractWxPayClient {
-
- public WxNativePayClient(Long channelId, WxPayClientConfig config) {
- super(channelId, PayChannelEnum.WX_NATIVE.getCode(), config);
- }
-
- @Override
- protected void doInit() {
- super.doInit(WxPayConstants.TradeType.NATIVE);
- }
-
- @Override
- protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
- // 构建 WxPayUnifiedOrderRequest 对象
- WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO);
- // 执行请求
- WxPayNativeOrderResult response = client.createOrder(request);
-
- // 转换结果
- return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.QR_CODE.getMode(), response.getCodeUrl(),
- reqDTO.getOutTradeNo(), response);
- }
-
- @Override
- protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
- // 构建 WxPayUnifiedOrderV3Request 对象
- WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO);
- // 执行请求
- String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
-
- // 转换结果
- return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.QR_CODE.getMode(), response,
- reqDTO.getOutTradeNo(), response);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPayClientConfig.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPayClientConfig.java
deleted file mode 100644
index de5b0234a4..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPayClientConfig.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-import cn.hutool.core.io.IoUtil;
-import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
-import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
-import lombok.Data;
-
-import jakarta.validation.Validator;
-import jakarta.validation.constraints.NotBlank;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
-/**
- * 微信支付的 PayClientConfig 实现类
- * 属性主要来自 {@link com.github.binarywang.wxpay.config.WxPayConfig} 的必要属性
- *
- * @author 芋道源码
- */
-@Data
-public class WxPayClientConfig implements PayClientConfig {
-
- /**
- * API 版本 - V2
- *
- * V2 协议说明
- */
- public static final String API_VERSION_V2 = "v2";
- /**
- * API 版本 - V3
- *
- * V3 协议说明
- */
- public static final String API_VERSION_V3 = "v3";
-
- /**
- * 公众号或者小程序的 appid
- *
- * 只有公众号或小程序需要该字段
- */
- @NotBlank(message = "APPID 不能为空", groups = {V2.class, V3.class})
- private String appId;
- /**
- * 商户号
- */
- @NotBlank(message = "商户号不能为空", groups = {V2.class, V3.class})
- private String mchId;
- /**
- * API 版本
- */
- @NotBlank(message = "API 版本不能为空", groups = {V2.class, V3.class})
- private String apiVersion;
-
- // ========== V2 版本的参数 ==========
-
- /**
- * 商户密钥
- */
- @NotBlank(message = "商户密钥不能为空", groups = V2.class)
- private String mchKey;
- /**
- * apiclient_cert.p12 证书文件的对应字符串【base64 格式】
- *
- * 为什么采用 base64 格式?因为 p12 读取后是二进制,需要转换成 base64 格式才好传输和存储
- */
- @NotBlank(message = "apiclient_cert.p12 不能为空", groups = V2.class)
- private String keyContent;
-
- // ========== V3 版本的参数 ==========
- /**
- * apiclient_key.pem 证书文件的对应字符串
- */
- @NotBlank(message = "apiclient_key 不能为空", groups = V3.class)
- private String privateKeyContent;
- /**
- * apiclient_cert.pem 证书文件的对应的字符串
- */
- @NotBlank(message = "apiclient_cert 不能为空", groups = V3.class)
- private String privateCertContent;
- /**
- * apiV3 密钥值
- */
- @NotBlank(message = "apiV3 密钥值不能为空", groups = V3.class)
- private String apiV3Key;
-
- /**
- * 分组校验 v2版本
- */
- public interface V2 {
- }
-
- /**
- * 分组校验 v3版本
- */
- public interface V3 {
- }
-
- @Override
- public void validate(Validator validator) {
- ValidationUtils.validate(validator, this,
- API_VERSION_V2.equals(this.getApiVersion()) ? V2.class : V3.class);
- }
-
- public static void main(String[] args) throws FileNotFoundException {
- String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.p12";
- /// String path = "/Users/yunai/Downloads/wx_pay/apiclient_key.pem";
- /// String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.pem";
- System.out.println(IoUtil.readUtf8(new FileInputStream(path)));
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPubPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPubPayClient.java
deleted file mode 100644
index 390c513630..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPubPayClient.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.StrUtil;
-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.enums.channel.PayChannelEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
-import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
-import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
-import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
-import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
-import com.github.binarywang.wxpay.constant.WxPayConstants;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import lombok.extern.slf4j.Slf4j;
-
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
-
-/**
- * 微信支付(公众号)的 PayClient 实现类
- *
- * 文档:JSAPI 下单>
- *
- * @author 芋道源码
- */
-@Slf4j
-public class WxPubPayClient extends AbstractWxPayClient {
-
- public WxPubPayClient(Long channelId, WxPayClientConfig config) {
- super(channelId, PayChannelEnum.WX_PUB.getCode(), config);
- }
-
- protected WxPubPayClient(Long channelId, String channelCode, WxPayClientConfig config) {
- super(channelId, channelCode, config);
- }
-
- @Override
- protected void doInit() {
- super.doInit(WxPayConstants.TradeType.JSAPI);
- }
-
- @Override
- protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
- // 构建 WxPayUnifiedOrderRequest 对象
- WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO)
- .setOpenid(getOpenid(reqDTO));
- // 执行请求
- WxPayMpOrderResult response = client.createOrder(request);
-
- // 转换结果
- return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
- reqDTO.getOutTradeNo(), response);
- }
-
- @Override
- protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
- // 构建 WxPayUnifiedOrderRequest 对象
- WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO)
- .setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO)));
- // 执行请求
- WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.JSAPI, request);
-
- // 转换结果
- return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
- reqDTO.getOutTradeNo(), response);
- }
-
- // ========== 各种工具方法 ==========
-
- static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {
- String openid = MapUtil.getStr(reqDTO.getChannelExtras(), "openid");
- if (StrUtil.isEmpty(openid)) {
- throw invalidParamException("支付请求的 openid 不能为空!");
- }
- return openid;
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
deleted file mode 100644
index 83d2d13add..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.enums.channel;
-
-import cn.hutool.core.util.ArrayUtil;
-import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
-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.weixin.WxPayClientConfig;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 支付渠道的编码的枚举
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum PayChannelEnum {
-
- WX_PUB("wx_pub", "微信 JSAPI 支付", WxPayClientConfig.class), // 公众号网页
- WX_LITE("wx_lite", "微信小程序支付", WxPayClientConfig.class),
- WX_APP("wx_app", "微信 App 支付", WxPayClientConfig.class),
- WX_NATIVE("wx_native", "微信 Native 支付", WxPayClientConfig.class),
- WX_BAR("wx_bar", "微信付款码支付", WxPayClientConfig.class),
-
- ALIPAY_PC("alipay_pc", "支付宝 PC 网站支付", AlipayPayClientConfig.class),
- ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class),
- ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class),
- ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class),
- ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class),
- MOCK("mock", "模拟支付", NonePayClientConfig.class),
-
- WALLET("wallet", "钱包支付", NonePayClientConfig.class);
-
- /**
- * 编码
- *
- * 参考 支付渠道属性值
- */
- private final String code;
- /**
- * 名字
- */
- private final String name;
-
- /**
- * 配置类
- */
- private final Class extends PayClientConfig> configClass;
-
- /**
- * 微信支付
- */
- public static final String WECHAT = "WECHAT";
-
- /**
- * 支付宝支付
- */
- public static final String ALIPAY = "ALIPAY";
-
- public static PayChannelEnum getByCode(String code) {
- return ArrayUtil.firstMatch(o -> o.getCode().equals(code), values());
- }
-
- public static boolean isAlipay(String channelCode) {
- return channelCode != null && channelCode.startsWith("alipay");
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderDisplayModeEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderDisplayModeEnum.java
deleted file mode 100644
index 129c406029..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderDisplayModeEnum.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.enums.order;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 支付 UI 展示模式
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum PayOrderDisplayModeEnum {
-
- URL("url"), // Redirect 跳转链接的方式
- IFRAME("iframe"), // IFrame 内嵌链接的方式【目前暂时用不到】
- FORM("form"), // HTML 表单提交
- QR_CODE("qr_code"), // 二维码的文字内容
- QR_CODE_URL("qr_code_url"), // 二维码的图片链接
- BAR_CODE("bar_code"), // 条形码
- APP("app"), // 应用:Android、iOS、微信小程序、微信公众号等,需要做自定义处理的
- ;
-
- /**
- * 展示模式
- */
- private final String mode;
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderStatusRespEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderStatusRespEnum.java
deleted file mode 100644
index eac381c472..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderStatusRespEnum.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.enums.order;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.util.Objects;
-
-/**
- * 渠道的支付状态枚举
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum PayOrderStatusRespEnum {
-
- WAITING(0, "未支付"),
- SUCCESS(10, "支付成功"),
- REFUND(20, "已退款"),
- CLOSED(30, "支付关闭"),
- ;
-
- private final Integer status;
- private final String name;
-
- /**
- * 判断是否支付成功
- *
- * @param status 状态
- * @return 是否支付成功
- */
- public static boolean isSuccess(Integer status) {
- return Objects.equals(status, SUCCESS.getStatus());
- }
-
- /**
- * 判断是否已退款
- *
- * @param status 状态
- * @return 是否支付成功
- */
- public static boolean isRefund(Integer status) {
- return Objects.equals(status, REFUND.getStatus());
- }
-
- /**
- * 判断是否支付关闭
- *
- * @param status 状态
- * @return 是否支付关闭
- */
- public static boolean isClosed(Integer status) {
- return Objects.equals(status, CLOSED.getStatus());
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/refund/PayRefundStatusRespEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/refund/PayRefundStatusRespEnum.java
deleted file mode 100644
index 8ad61a6cff..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/refund/PayRefundStatusRespEnum.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.enums.refund;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.util.Objects;
-
-/**
- * 渠道的退款状态枚举
- *
- * @author jason
- */
-@Getter
-@AllArgsConstructor
-public enum PayRefundStatusRespEnum {
-
- WAITING(0, "等待退款"),
- SUCCESS(10, "退款成功"),
- FAILURE(20, "退款失败");
-
- private final Integer status;
- private final String name;
-
- public static boolean isSuccess(Integer status) {
- return Objects.equals(status, SUCCESS.getStatus());
- }
-
- public static boolean isFailure(Integer status) {
- return Objects.equals(status, FAILURE.getStatus());
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java
deleted file mode 100644
index 35ea344da2..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.enums.transfer;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.util.Objects;
-
-/**
- * 渠道的转账状态枚举
- *
- * @author jason
- */
-@Getter
-@AllArgsConstructor
-public enum PayTransferStatusRespEnum {
-
- WAITING(0, "等待转账"),
-
- /**
- * TODO 转账到银行卡. 会有T+0 T+1 到账的请情况。 还未实现
- * TODO @jason:可以看看其它开源项目,针对这个场景,处理策略是怎么样的?例如说,每天主动轮询?这个状态的单子?
- */
- IN_PROGRESS(10, "转账进行中"),
-
- SUCCESS(20, "转账成功"),
- /**
- * 转账关闭 (失败,或者其它情况)
- */
- CLOSED(30, "转账关闭");
-
- private final Integer status;
- private final String name;
-
- public static boolean isSuccess(Integer status) {
- return Objects.equals(status, SUCCESS.getStatus());
- }
-
- public static boolean isClosed(Integer status) {
- return Objects.equals(status, CLOSED.getStatus());
- }
-
- public static boolean isInProgress(Integer status) {
- return Objects.equals(status, IN_PROGRESS.getStatus());
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java
deleted file mode 100644
index a7580f0132..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.enums.transfer;
-
-import cn.hutool.core.util.ArrayUtil;
-import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.util.Arrays;
-
-/**
- * 转账类型枚举
- *
- * @author jason
- */
-@AllArgsConstructor
-@Getter
-public enum PayTransferTypeEnum implements IntArrayValuable {
-
- ALIPAY_BALANCE(1, "支付宝余额"),
- WX_BALANCE(2, "微信余额"),
- BANK_CARD(3, "银行卡"),
- WALLET_BALANCE(4, "钱包余额");
-
- public interface WxPay {
- }
-
- public interface Alipay {
- }
-
- private final Integer type;
- private final String name;
-
- public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PayTransferTypeEnum::getType).toArray();
-
- @Override
- public int[] array() {
- return ARRAYS;
- }
-
- public static PayTransferTypeEnum typeOf(Integer type) {
- return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
deleted file mode 100644
index f2a8bf1463..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ /dev/null
@@ -1 +0,0 @@
-cn.iocoder.yudao.framework.pay.config.YudaoPayAutoConfiguration
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java
deleted file mode 100644
index 9842560636..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl;
-
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.RandomUtil;
-import cn.iocoder.yudao.framework.pay.core.client.PayClient;
-import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
-import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
-import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayQrPayClient;
-import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayWapPayClient;
-import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
-import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPubPayClient;
-import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
-/**
- * {@link PayClientFactoryImpl} 的集成测试
- *
- * @author 芋道源码
- */
-@Disabled
-public class PayClientFactoryImplIntegrationTest {
-
- private static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
-
- private final PayClientFactoryImpl payClientFactory = new PayClientFactoryImpl();
-
- /**
- * {@link WxPubPayClient} 的 V2 版本
- */
- @Test
- public void testCreatePayClient_WX_PUB_V2() {
- // 创建配置
- WxPayClientConfig config = new WxPayClientConfig();
- config.setAppId("wx041349c6f39b268b");
- config.setMchId("1545083881");
- config.setApiVersion(WxPayClientConfig.API_VERSION_V2);
- config.setMchKey("0alL64UDQdlCwiKZ73ib7ypaIjMns06p");
- // 创建客户端
- Long channelId = RandomUtil.randomLong();
- payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.WX_PUB.getCode(), config);
- PayClient client = payClientFactory.getPayClient(channelId);
- // 发起支付
- PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
-// CommonResult> result = client.unifiedOrder(reqDTO);
-// System.out.println(result);
- }
-
- /**
- * {@link WxPubPayClient} 的 V3 版本
- */
- @Test
- public void testCreatePayClient_WX_PUB_V3() throws FileNotFoundException {
- // 创建配置
- WxPayClientConfig config = new WxPayClientConfig();
- config.setAppId("wx041349c6f39b268b");
- config.setMchId("1545083881");
- config.setApiVersion(WxPayClientConfig.API_VERSION_V3);
- config.setPrivateKeyContent(IoUtil.readUtf8(new FileInputStream("/Users/yunai/Downloads/wx_pay/apiclient_key.pem")));
- config.setPrivateCertContent(IoUtil.readUtf8(new FileInputStream("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem")));
- config.setApiV3Key("joerVi8y5DJ3o4ttA0o1uH47Xz1u2Ase");
- // 创建客户端
- Long channelId = RandomUtil.randomLong();
- payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.WX_PUB.getCode(), config);
- PayClient client = payClientFactory.getPayClient(channelId);
- // 发起支付
- PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
-// CommonResult> result = client.unifiedOrder(reqDTO);
-// System.out.println(result);
- }
-
- /**
- * {@link AlipayQrPayClient}
- */
- @Test
- @SuppressWarnings("unchecked")
- public void testCreatePayClient_ALIPAY_QR() {
- // 创建配置
- AlipayPayClientConfig config = new AlipayPayClientConfig();
- config.setAppId("2021000118634035");
- config.setServerUrl(SERVER_URL_SANDBOX);
- config.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT);
- config.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJv890x84qbppUtRIfhaKSwSVN0thCcsDCaAsGR5MZslDkO8NCT9V4r2SVXjyY7eJUZlZd1M0C8T01Tg4UOx5LUbic0O3A1uJMy6V1n9IyYwbAW3AEZhBd5bSbPgrqvmv3NeWSTQT6Anxnllf+2iDH6zyA2fPl7cYyQtbZoDJQFGqr4F+cGh2R6akzRKNoBkAeMYwoY6es2lX8sJxCVPWUmxNUoL3tScwlSpd7Bxw0q9c/X01jMwuQ0+Va358zgFiGERTE6yD01eu40OBDXOYO3z++y+TAYHlQQ2toMO63trepo88X3xV3R44/1DH+k2pAm2IF5ixiLrAgMBAAECggEAPx3SoXcseaD7rmcGcE0p4SMfbsUDdkUSmBBbtfF0GzwnqNLkWa+mgE0rWt9SmXngTQH97vByAYmLPl1s3G82ht1V7Sk7yQMe74lhFllr8eEyTjeVx3dTK1EEM4TwN+936DTXdFsr4TELJEcJJdD0KaxcCcfBLRDs2wnitEFZ9N+GoZybVmY8w0e0MI7PLObUZ2l0X4RurQnfG9ZxjXjC7PkeMVv7cGGylpNFi3BbvkRhdhLPDC2E6wqnr9e7zk+hiENivAezXrtxtwKovzCtnWJ1r0IO14Rh47H509Ic0wFnj+o5YyUL4LdmpL7yaaH6fM7zcSLFjNZPHvZCKPwYcQKBgQDQFho98QvnL8ex4v6cry4VitGpjSXm1qP3vmMQk4rTsn8iPWtcxPjqGEqOQJjdi4Mi0VZKQOLFwlH0kl95wNrD/isJ4O1yeYfX7YAXApzHqYNINzM79HemO3Yx1qLMW3okRFJ9pPRzbQ9qkTpsaegsmyX316zOBhzGRYjKbutTYwKBgQCm7phr9XdFW5Vh+XR90mVs483nrLmMiDKg7YKxSLJ8amiDjzPejCn7i95Hah08P+2MIZLIPbh2VLacczR6ltRRzN5bg5etFuqSgfkuHyxpoDmpjbe08+Q2h8JBYqcC5Nhv1AKU4iOUhVLHo/FBAQliMcGc/J3eiYTFC7EsNx382QKBgClb20doe7cttgFTXswBvaUmfFm45kmla924B7SpvrQpDD/f+VDtDZRp05fGmxuduSjYdtA3aVtpLiTwWu22OUUvZZqHDGruYOO4Hvdz23mL5b4ayqImCwoNU4bAZIc9v18p/UNf3/55NNE3oGcf/bev9rH2OjCQ4nM+Ktwhg8CFAoGACSgvbkShzUkv0ZcIf9ppu+ZnJh1AdGgINvGwaJ8vQ0nm/8h8NOoFZ4oNoGc+wU5Ubops7dUM6FjPR5e+OjdJ4E7Xp7d5O4J1TaIZlCEbo5OpdhaTDDcQvrkFu+Z4eN0qzj+YAKjDAOOrXc4tbr5q0FsgXscwtcNfaBuzFVTUrUkCgYEAwzPnMNhWG3zOWLUs2QFA2GP4Y+J8cpUYfj6pbKKzeLwyG9qBwF1NJpN8m+q9q7V9P2LY+9Lp9e1mGsGeqt5HMEA3P6vIpcqLJLqE/4PBLLRzfccTcmqb1m71+erxTRhHBRkGS+I7dZEb3olQfnS1Y1tpMBxiwYwR3LW4oXuJwj8=");
- config.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB");
- // 创建客户端
- Long channelId = RandomUtil.randomLong();
- payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config);
- PayClient client = payClientFactory.getPayClient(channelId);
- // 发起支付
- PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
- reqDTO.setNotifyUrl("http://yunai.natapp1.cc/admin-api/pay/notify/callback/18"); // TODO @tina: 这里改成你的 natapp 回调地址
-// CommonResult result = (CommonResult) client.unifiedOrder(reqDTO);
-// System.out.println(JsonUtils.toJsonString(result));
-// System.out.println(result.getData().getQrCode());
- }
-
- /**
- * {@link AlipayWapPayClient}
- */
- @Test
- public void testCreatePayClient_ALIPAY_WAP() {
- // 创建配置
- AlipayPayClientConfig config = new AlipayPayClientConfig();
- config.setAppId("2021000118634035");
- config.setServerUrl(SERVER_URL_SANDBOX);
- config.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT);
- config.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJv890x84qbppUtRIfhaKSwSVN0thCcsDCaAsGR5MZslDkO8NCT9V4r2SVXjyY7eJUZlZd1M0C8T01Tg4UOx5LUbic0O3A1uJMy6V1n9IyYwbAW3AEZhBd5bSbPgrqvmv3NeWSTQT6Anxnllf+2iDH6zyA2fPl7cYyQtbZoDJQFGqr4F+cGh2R6akzRKNoBkAeMYwoY6es2lX8sJxCVPWUmxNUoL3tScwlSpd7Bxw0q9c/X01jMwuQ0+Va358zgFiGERTE6yD01eu40OBDXOYO3z++y+TAYHlQQ2toMO63trepo88X3xV3R44/1DH+k2pAm2IF5ixiLrAgMBAAECggEAPx3SoXcseaD7rmcGcE0p4SMfbsUDdkUSmBBbtfF0GzwnqNLkWa+mgE0rWt9SmXngTQH97vByAYmLPl1s3G82ht1V7Sk7yQMe74lhFllr8eEyTjeVx3dTK1EEM4TwN+936DTXdFsr4TELJEcJJdD0KaxcCcfBLRDs2wnitEFZ9N+GoZybVmY8w0e0MI7PLObUZ2l0X4RurQnfG9ZxjXjC7PkeMVv7cGGylpNFi3BbvkRhdhLPDC2E6wqnr9e7zk+hiENivAezXrtxtwKovzCtnWJ1r0IO14Rh47H509Ic0wFnj+o5YyUL4LdmpL7yaaH6fM7zcSLFjNZPHvZCKPwYcQKBgQDQFho98QvnL8ex4v6cry4VitGpjSXm1qP3vmMQk4rTsn8iPWtcxPjqGEqOQJjdi4Mi0VZKQOLFwlH0kl95wNrD/isJ4O1yeYfX7YAXApzHqYNINzM79HemO3Yx1qLMW3okRFJ9pPRzbQ9qkTpsaegsmyX316zOBhzGRYjKbutTYwKBgQCm7phr9XdFW5Vh+XR90mVs483nrLmMiDKg7YKxSLJ8amiDjzPejCn7i95Hah08P+2MIZLIPbh2VLacczR6ltRRzN5bg5etFuqSgfkuHyxpoDmpjbe08+Q2h8JBYqcC5Nhv1AKU4iOUhVLHo/FBAQliMcGc/J3eiYTFC7EsNx382QKBgClb20doe7cttgFTXswBvaUmfFm45kmla924B7SpvrQpDD/f+VDtDZRp05fGmxuduSjYdtA3aVtpLiTwWu22OUUvZZqHDGruYOO4Hvdz23mL5b4ayqImCwoNU4bAZIc9v18p/UNf3/55NNE3oGcf/bev9rH2OjCQ4nM+Ktwhg8CFAoGACSgvbkShzUkv0ZcIf9ppu+ZnJh1AdGgINvGwaJ8vQ0nm/8h8NOoFZ4oNoGc+wU5Ubops7dUM6FjPR5e+OjdJ4E7Xp7d5O4J1TaIZlCEbo5OpdhaTDDcQvrkFu+Z4eN0qzj+YAKjDAOOrXc4tbr5q0FsgXscwtcNfaBuzFVTUrUkCgYEAwzPnMNhWG3zOWLUs2QFA2GP4Y+J8cpUYfj6pbKKzeLwyG9qBwF1NJpN8m+q9q7V9P2LY+9Lp9e1mGsGeqt5HMEA3P6vIpcqLJLqE/4PBLLRzfccTcmqb1m71+erxTRhHBRkGS+I7dZEb3olQfnS1Y1tpMBxiwYwR3LW4oXuJwj8=");
- config.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB");
- // 创建客户端
- Long channelId = RandomUtil.randomLong();
- payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config);
- PayClient client = payClientFactory.getPayClient(channelId);
- // 发起支付
- PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
-// CommonResult> result = client.unifiedOrder(reqDTO);
-// System.out.println(JsonUtils.toJsonString(result));
- }
-
- private static PayOrderUnifiedReqDTO buildPayOrderUnifiedReqDTO() {
- PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO();
- reqDTO.setPrice(123);
- reqDTO.setSubject("IPhone 13");
- reqDTO.setBody("biubiubiu");
- reqDTO.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
- reqDTO.setUserIp("127.0.0.1");
- reqDTO.setNotifyUrl("http://127.0.0.1:8080");
- return reqDTO;
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java
deleted file mode 100644
index 7c45b6a90f..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.hutool.core.date.LocalDateTimeUtil;
-import cn.hutool.core.util.RandomUtil;
-import cn.iocoder.yudao.framework.common.exception.ServiceException;
-import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
-import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
-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.exception.PayException;
-import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
-import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.DefaultAlipayClient;
-import com.alipay.api.DefaultSigner;
-import com.alipay.api.domain.AlipayTradeRefundModel;
-import com.alipay.api.request.AlipayTradeRefundRequest;
-import com.alipay.api.response.AlipayTradeRefundResponse;
-import lombok.Setter;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-
-import jakarta.validation.ConstraintViolationException;
-import java.util.Date;
-
-import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_PUBLIC_KEY;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.when;
-
-/**
- * 支付宝 Client 的测试基类
- *
- * @author jason
- */
-public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
-
- protected AlipayPayClientConfig config = randomPojo(AlipayPayClientConfig.class, o -> {
- o.setServerUrl(randomURL());
- o.setPrivateKey(randomString());
- o.setMode(MODE_PUBLIC_KEY);
- o.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT);
- o.setAppCertContent("");
- o.setAlipayPublicCertContent("");
- o.setRootCertContent("");
- });
-
- @Mock
- protected DefaultAlipayClient defaultAlipayClient;
-
- @Setter
- private AbstractAlipayPayClient client;
-
- /**
- * 子类需要实现该方法. 设置 client 的具体实现
- */
- @BeforeEach
- public abstract void setUp();
-
- @Test
- @DisplayName("支付宝 Client 初始化")
- public void testDoInit() {
- // 调用
- client.doInit();
- // 断言
- DefaultAlipayClient realClient = client.getClient();
- assertNotSame(defaultAlipayClient, realClient);
- assertInstanceOf(DefaultSigner.class, realClient.getSigner());
- assertEquals(config.getPrivateKey(), ((DefaultSigner) realClient.getSigner()).getPrivateKey());
- }
-
- @Test
- @DisplayName("支付宝 Client 统一退款:成功")
- public void testUnifiedRefund_success() throws AlipayApiException {
- // mock 方法
- String notifyUrl = randomURL();
- Date refundTime = randomDate();
- String outRefundNo = randomString();
- String outTradeNo = randomString();
- Integer refundAmount = randomInteger();
- AlipayTradeRefundResponse response = randomPojo(AlipayTradeRefundResponse.class, o -> {
- o.setSubCode("");
- o.setGmtRefundPay(refundTime);
- });
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> {
- assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel());
- AlipayTradeRefundModel bizModel = (AlipayTradeRefundModel) request.getBizModel();
- assertEquals(outRefundNo, bizModel.getOutRequestNo());
- assertEquals(outTradeNo, bizModel.getOutTradeNo());
- assertEquals(String.valueOf(refundAmount / 100.0), bizModel.getRefundAmount());
- return true;
- }))).thenReturn(response);
- // 准备请求参数
- PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
- o.setOutRefundNo(outRefundNo);
- o.setOutTradeNo(outTradeNo);
- o.setNotifyUrl(notifyUrl);
- o.setRefundPrice(refundAmount);
- });
-
- // 调用
- PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO);
- // 断言
- assertEquals(PayRefundStatusRespEnum.SUCCESS.getStatus(), resp.getStatus());
- assertEquals(outRefundNo, resp.getOutRefundNo());
- assertNull(resp.getChannelRefundNo());
- assertEquals(LocalDateTimeUtil.of(refundTime), resp.getSuccessTime());
- assertSame(response, resp.getRawData());
- assertNull(resp.getChannelErrorCode());
- assertNull(resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝 Client 统一退款:渠道返回失败")
- public void test_unified_refund_channel_failed() throws AlipayApiException {
- // mock 方法
- String notifyUrl = randomURL();
- String subCode = randomString();
- String subMsg = randomString();
- AlipayTradeRefundResponse response = randomPojo(AlipayTradeRefundResponse.class, o -> {
- o.setSubCode(subCode);
- o.setSubMsg(subMsg);
- });
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> {
- assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel());
- return true;
- }))).thenReturn(response);
- // 准备请求参数
- String outRefundNo = randomString();
- String outTradeNo = randomString();
- PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
- o.setOutRefundNo(outRefundNo);
- o.setOutTradeNo(outTradeNo);
- o.setNotifyUrl(notifyUrl);
- });
-
- // 调用
- PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO);
- // 断言
- assertEquals(PayRefundStatusRespEnum.FAILURE.getStatus(), resp.getStatus());
- assertEquals(outRefundNo, resp.getOutRefundNo());
- assertNull(resp.getChannelRefundNo());
- assertNull(resp.getSuccessTime());
- assertSame(response, resp.getRawData());
- assertEquals(subCode, resp.getChannelErrorCode());
- assertEquals(subMsg, resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝 Client 统一退款:参数校验不通过")
- public void testUnifiedRefund_paramInvalidate() {
- // 准备请求参数
- String notifyUrl = randomURL();
- PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
- o.setOutTradeNo("");
- o.setNotifyUrl(notifyUrl);
- });
-
- // 调用,并断言
- assertThrows(ConstraintViolationException.class, () -> client.unifiedRefund(refundReqDTO));
- }
-
- @Test
- @DisplayName("支付宝 Client 统一退款:抛出业务异常")
- public void testUnifiedRefund_throwServiceException() throws AlipayApiException {
- // mock 方法
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> true)))
- .thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR));
- // 准备请求参数
- String notifyUrl = randomURL();
- PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> o.setNotifyUrl(notifyUrl));
-
- // 调用,并断言
- assertThrows(ServiceException.class, () -> client.unifiedRefund(refundReqDTO));
- }
-
- @Test
- @DisplayName("支付宝 Client 统一退款:抛出系统异常")
- public void testUnifiedRefund_throwPayException() throws AlipayApiException {
- // mock 方法
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> true)))
- .thenThrow(new RuntimeException("系统异常"));
- // 准备请求参数
- String notifyUrl = randomURL();
- PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> o.setNotifyUrl(notifyUrl));
-
- // 调用,并断言
- assertThrows(PayException.class, () -> client.unifiedRefund(refundReqDTO));
- }
-
- @Test
- @DisplayName("支付宝 Client 统一下单:参数校验不通过")
- public void testUnifiedOrder_paramInvalidate() {
- // 准备请求参数
- String outTradeNo = randomString();
- String notifyUrl = randomURL();
- PayOrderUnifiedReqDTO reqDTO = randomPojo(PayOrderUnifiedReqDTO.class, o -> {
- o.setOutTradeNo(outTradeNo);
- o.setNotifyUrl(notifyUrl);
- });
-
- // 调用,并断言
- assertThrows(ConstraintViolationException.class, () -> client.unifiedOrder(reqDTO));
- }
-
- protected PayOrderUnifiedReqDTO buildOrderUnifiedReqDTO(String notifyUrl, String outTradeNo, Integer price) {
- return randomPojo(PayOrderUnifiedReqDTO.class, o -> {
- o.setOutTradeNo(outTradeNo);
- o.setNotifyUrl(notifyUrl);
- o.setPrice(price);
- o.setSubject(RandomUtil.randomString(32));
- o.setBody(RandomUtil.randomString(32));
- });
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClientTest.java
deleted file mode 100644
index 47f10081ca..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClientTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.hutool.core.date.LocalDateTimeUtil;
-import cn.iocoder.yudao.framework.common.exception.ServiceException;
-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.enums.order.PayOrderDisplayModeEnum;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.domain.AlipayTradePayModel;
-import com.alipay.api.request.AlipayTradePayRequest;
-import com.alipay.api.response.AlipayTradePayResponse;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InjectMocks;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
-import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.when;
-
-/**
- * {@link AlipayBarPayClient} 单元测试
- *
- * @author jason
- */
-public class AlipayBarPayClientTest extends AbstractAlipayClientTest {
-
- @InjectMocks
- private AlipayBarPayClient client = new AlipayBarPayClient(randomLongId(), config);
-
- @Override
- @BeforeEach
- public void setUp() {
- setClient(client);
- }
-
- @Test
- @DisplayName("支付宝条码支付:非免密码支付下单成功")
- public void testUnifiedOrder_success() throws AlipayApiException {
- // mock 方法
- String outTradeNo = randomString();
- String notifyUrl = randomURL();
- Integer price = randomInteger();
- String authCode = randomString();
- AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> o.setSubCode(""));
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> {
- assertInstanceOf(AlipayTradePayModel.class, request.getBizModel());
- assertEquals(notifyUrl, request.getNotifyUrl());
- AlipayTradePayModel model = (AlipayTradePayModel) request.getBizModel();
- assertEquals(outTradeNo, model.getOutTradeNo());
- assertEquals(String.valueOf(price / 100.0), model.getTotalAmount());
- assertEquals(authCode, model.getAuthCode());
- return true;
- }))).thenReturn(response);
- // 准备请求参数
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
- Map extraParam = new HashMap<>();
- extraParam.put("auth_code", authCode);
- reqDTO.setChannelExtras(extraParam);
-
- // 调用方法
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(WAITING.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertEquals(PayOrderDisplayModeEnum.BAR_CODE.getMode(), resp.getDisplayMode());
- assertEquals("", resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertNull(resp.getChannelErrorCode());
- assertNull(resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝条码支付:免密码支付下单成功")
- public void testUnifiedOrder_code10000Success() throws AlipayApiException {
- // mock 方法
- String outTradeNo = randomString();
- String channelNo = randomString();
- String channelUserId = randomString();
- Date payTime = randomDate();
- AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> {
- o.setSubCode("");
- o.setCode("10000");
- o.setOutTradeNo(outTradeNo);
- o.setTradeNo(channelNo);
- o.setBuyerUserId(channelUserId);
- o.setGmtPayment(payTime);
- });
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> true)))
- .thenReturn(response);
- // 准备请求参数
- String authCode = randomString();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger());
- Map extraParam = new HashMap<>();
- extraParam.put("auth_code", authCode);
- reqDTO.setChannelExtras(extraParam);
-
- // 下单请求
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(PayOrderStatusRespEnum.SUCCESS.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertEquals(channelNo, resp.getChannelOrderNo());
- assertEquals(channelUserId, resp.getChannelUserId());
- assertEquals(LocalDateTimeUtil.of(payTime), resp.getSuccessTime());
- assertEquals(PayOrderDisplayModeEnum.BAR_CODE.getMode(), resp.getDisplayMode());
- assertEquals("", resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertNull(resp.getChannelErrorCode());
- assertNull(resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝条码支付:没有传条码")
- public void testUnifiedOrder_emptyAuthCode() {
- // 准备参数
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
-
- // 调用,并断言
- assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO));
- }
-
- @Test
- @DisplayName("支付宝条码支付:渠道返回失败")
- public void test_unified_order_channel_failed() throws AlipayApiException {
- // mock 方法
- String subCode = randomString();
- String subMsg = randomString();
- AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> {
- o.setSubCode(subCode);
- o.setSubMsg(subMsg);
- });
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> true)))
- .thenReturn(response);
- // 准备请求参数
- String authCode = randomString();
- String outTradeNo = randomString();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger());
- Map extraParam = new HashMap<>();
- extraParam.put("auth_code", authCode);
- reqDTO.setChannelExtras(extraParam);
-
- // 调用方法
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(CLOSED.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertNull(resp.getDisplayMode());
- assertNull(resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertEquals(subCode, resp.getChannelErrorCode());
- assertEquals(subMsg, resp.getChannelErrorMsg());
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClientTest.java
deleted file mode 100644
index d78caf28c5..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClientTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.hutool.http.Method;
-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.enums.order.PayOrderDisplayModeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.request.AlipayTradePagePayRequest;
-import com.alipay.api.response.AlipayTradePagePayResponse;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InjectMocks;
-
-import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
-import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-/**
- * {@link AlipayPcPayClient} 单元测试
- *
- * @author jason
- */
-public class AlipayPcPayClientTest extends AbstractAlipayClientTest {
-
- @InjectMocks
- private AlipayPcPayClient client = new AlipayPcPayClient(randomLongId(), config);
-
- @Override
- @BeforeEach
- public void setUp() {
- setClient(client);
- }
-
- @Test
- @DisplayName("支付宝 PC 网站支付:URL Display Mode 下单成功")
- public void testUnifiedOrder_urlSuccess() throws AlipayApiException {
- // mock 方法
- String notifyUrl = randomURL();
- AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> o.setSubCode(""));
- when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> true),
- eq(Method.GET.name()))).thenReturn(response);
- // 准备请求参数
- String outTradeNo = randomString();
- Integer price = randomInteger();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
- reqDTO.setDisplayMode(null);
-
- // 调用
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(WAITING.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertEquals(PayOrderDisplayModeEnum.URL.getMode(), resp.getDisplayMode());
- assertEquals(response.getBody(), resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertNull(resp.getChannelErrorCode());
- assertNull(resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝 PC 网站支付:Form Display Mode 下单成功")
- public void testUnifiedOrder_formSuccess() throws AlipayApiException {
- // mock 方法
- String notifyUrl = randomURL();
- AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> o.setSubCode(""));
- when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> true),
- eq(Method.POST.name()))).thenReturn(response);
- // 准备请求参数
- String outTradeNo = randomString();
- Integer price = randomInteger();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
- reqDTO.setDisplayMode(PayOrderDisplayModeEnum.FORM.getMode());
-
- // 调用
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(WAITING.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertEquals(PayOrderDisplayModeEnum.FORM.getMode(), resp.getDisplayMode());
- assertEquals(response.getBody(), resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertNull(resp.getChannelErrorCode());
- assertNull(resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝 PC 网站支付:渠道返回失败")
- public void testUnifiedOrder_channelFailed() throws AlipayApiException {
- // mock 方法
- String subCode = randomString();
- String subMsg = randomString();
- AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> {
- o.setSubCode(subCode);
- o.setSubMsg(subMsg);
- });
- when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> true),
- eq(Method.GET.name()))).thenReturn(response);
- // 准备请求参数
- String outTradeNo = randomString();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger());
- reqDTO.setDisplayMode(PayOrderDisplayModeEnum.URL.getMode());
-
- // 调用
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(CLOSED.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertNull(resp.getDisplayMode());
- assertNull(resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertEquals(subCode, resp.getChannelErrorCode());
- assertEquals(subMsg, resp.getChannelErrorMsg());
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java
deleted file mode 100644
index c7e1eb33f7..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.iocoder.yudao.framework.common.exception.ServiceException;
-import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
-import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
-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.exception.PayException;
-import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.request.AlipayTradePrecreateRequest;
-import com.alipay.api.response.AlipayTradePrecreateResponse;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InjectMocks;
-
-import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
-import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.when;
-
-/**
- * {@link AlipayQrPayClient} 单元测试
- *
- * @author jason
- */
-public class AlipayQrPayClientTest extends AbstractAlipayClientTest {
-
- @InjectMocks
- private AlipayQrPayClient client = new AlipayQrPayClient(randomLongId(), config);
-
- @BeforeEach
- public void setUp() {
- setClient(client);
- }
-
- @Test
- @DisplayName("支付宝扫描支付:下单成功")
- public void testUnifiedOrder_success() throws AlipayApiException {
- // mock 方法
- String notifyUrl = randomURL();
- String qrCode = randomString();
- Integer price = randomInteger();
- AlipayTradePrecreateResponse response = randomPojo(AlipayTradePrecreateResponse.class, o -> {
- o.setQrCode(qrCode);
- o.setSubCode("");
- });
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> {
- assertEquals(notifyUrl, request.getNotifyUrl());
- return true;
- }))).thenReturn(response);
- // 准备请求参数
- String outTradeNo = randomString();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
-
- // 调用
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(WAITING.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertEquals(PayOrderDisplayModeEnum.QR_CODE.getMode(), resp.getDisplayMode());
- assertEquals(response.getQrCode(), resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertNull(resp.getChannelErrorCode());
- assertNull(resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝扫描支付:渠道返回失败")
- public void testUnifiedOrder_channelFailed() throws AlipayApiException {
- // mock 方法
- String notifyUrl = randomURL();
- String subCode = randomString();
- String subMsg = randomString();
- Integer price = randomInteger();
- AlipayTradePrecreateResponse response = randomPojo(AlipayTradePrecreateResponse.class, o -> {
- o.setSubCode(subCode);
- o.setSubMsg(subMsg);
- });
- // mock
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> {
- assertEquals(notifyUrl, request.getNotifyUrl());
- return true;
- }))).thenReturn(response);
- // 准备请求参数
- String outTradeNo = randomString();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
-
- // 调用
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(CLOSED.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertNull(resp.getDisplayMode());
- assertNull(resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertEquals(subCode, resp.getChannelErrorCode());
- assertEquals(subMsg, resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝扫描支付, 抛出系统异常")
- public void testUnifiedOrder_throwPayException() throws AlipayApiException {
- // mock 方法
- String outTradeNo = randomString();
- String notifyUrl = randomURL();
- Integer price = randomInteger();
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> {
- assertEquals(notifyUrl, request.getNotifyUrl());
- return true;
- }))).thenThrow(new RuntimeException("系统异常"));
- // 准备请求参数
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo,price);
-
- // 调用,并断言
- assertThrows(PayException.class, () -> client.unifiedOrder(reqDTO));
- }
-
- @Test
- @DisplayName("支付宝 Client 统一下单:抛出业务异常")
- public void testUnifiedOrder_throwServiceException() throws AlipayApiException {
- // mock 方法
- String outTradeNo = randomString();
- String notifyUrl = randomURL();
- Integer price = randomInteger();
- when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> {
- assertEquals(notifyUrl, request.getNotifyUrl());
- return true;
- }))).thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR));
- // 准备请求参数
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
-
- // 调用,并断言
- assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO));
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java
deleted file mode 100644
index af0c7170bf..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
-
-import cn.hutool.http.Method;
-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.enums.order.PayOrderDisplayModeEnum;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.domain.AlipayTradeWapPayModel;
-import com.alipay.api.request.AlipayTradeWapPayRequest;
-import com.alipay.api.response.AlipayTradeWapPayResponse;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InjectMocks;
-
-import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
-import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-/**
- * {@link AlipayWapPayClient} 单元测试
- *
- * @author jason
- */
-public class AlipayWapPayClientTest extends AbstractAlipayClientTest {
-
- /**
- * 支付宝 H5 支付 Client
- */
- @InjectMocks
- private AlipayWapPayClient client = new AlipayWapPayClient(randomLongId(), config);
-
- @BeforeEach
- public void setUp() {
- setClient(client);
- }
-
- @Test
- @DisplayName("支付宝 H5 支付:下单成功")
- public void testUnifiedOrder_success() throws AlipayApiException {
- // mock 方法
- String h5Body = randomString();
- Integer price = randomInteger();
- AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> {
- o.setSubCode("");
- o.setBody(h5Body);
- });
- String notifyUrl = randomURL();
- when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> {
- assertInstanceOf(AlipayTradeWapPayModel.class, request.getBizModel());
- AlipayTradeWapPayModel bizModel = (AlipayTradeWapPayModel) request.getBizModel();
- assertEquals(String.valueOf(price / 100.0), bizModel.getTotalAmount());
- assertEquals(notifyUrl, request.getNotifyUrl());
- return true;
- }), eq(Method.GET.name()))).thenReturn(response);
- // 准备请求参数
- String outTradeNo = randomString();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
-
- // 调用
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(WAITING.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertEquals(PayOrderDisplayModeEnum.URL.getMode(), resp.getDisplayMode());
- assertEquals(response.getBody(), resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertNull(resp.getChannelErrorCode());
- assertNull(resp.getChannelErrorMsg());
- }
-
- @Test
- @DisplayName("支付宝 H5 支付:渠道返回失败")
- public void test_unified_order_channel_failed() throws AlipayApiException {
- // mock 方法
- String subCode = randomString();
- String subMsg = randomString();
- AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> {
- o.setSubCode(subCode);
- o.setSubMsg(subMsg);
- });
- when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> true),
- eq(Method.GET.name()))).thenReturn(response);
- String outTradeNo = randomString();
- PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger());
-
- // 调用
- PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
- // 断言
- assertEquals(CLOSED.getStatus(), resp.getStatus());
- assertEquals(outTradeNo, resp.getOutTradeNo());
- assertNull(resp.getChannelOrderNo());
- assertNull(resp.getChannelUserId());
- assertNull(resp.getSuccessTime());
- assertNull(resp.getDisplayMode());
- assertNull(resp.getDisplayContent());
- assertSame(response, resp.getRawData());
- assertEquals(subCode, resp.getChannelErrorCode());
- assertEquals(subMsg, resp.getChannelErrorMsg());
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClientIntegrationTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClientIntegrationTest.java
deleted file mode 100644
index 9af11ac3fc..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClientIntegrationTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
-import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
-import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
-import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
-import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
-import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
-import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
-import com.github.binarywang.wxpay.config.WxPayConfig;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import com.github.binarywang.wxpay.service.WxPayService;
-import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import java.time.Duration;
-
-import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.AbstractWxPayClient.formatDateV2;
-
-/**
- * {@link WxBarPayClient} 的集成测试,用于快速调试微信条码支付
- *
- * @author 芋道源码
- */
-@Disabled
-public class WxBarPayClientIntegrationTest {
-
- @Test
- public void testPayV2() throws WxPayException {
- // 创建 config 配置
- WxPayConfig config = buildWxPayConfigV2();
- // 创建 WxPayService 客户端
- WxPayService client = new WxPayServiceImpl();
- client.setConfig(config);
-
- // 执行发起支付
- WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
- .outTradeNo(String.valueOf(System.currentTimeMillis()))
- .body("测试支付-body")
- .detail("测试支付-detail")
- .totalFee(1) // 单位分
- .timeExpire(formatDateV2(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
- .spbillCreateIp("127.0.0.1")
- .authCode("134298744426278497")
- .build();
- System.out.println("========= request ==========");
- System.out.println(JsonUtils.toJsonPrettyString(request));
- WxPayMicropayResult response = client.micropay(request);
- System.out.println("========= response ==========");
- System.out.println(JsonUtils.toJsonPrettyString(response));
- }
-
- @Test
- public void testParseRefundNotifyV2() throws WxPayException {
- // 创建 config 配置
- WxPayConfig config = buildWxPayConfigV2();
- // 创建 WxPayService 客户端
- WxPayService client = new WxPayServiceImpl();
- client.setConfig(config);
-
- // 执行解析
- String xml = "SUCCESS";
- WxPayRefundNotifyResult response = client.parseRefundNotifyResult(xml);
- System.out.println(response.getReqInfo());
- }
-
- @Test
- public void testRefundV2() throws WxPayException {
- // 创建 config 配置
- WxPayConfig config = buildWxPayConfigV2();
- // 创建 WxPayService 客户端
- WxPayService client = new WxPayServiceImpl();
- client.setConfig(config);
-
- // 执行发起退款
- WxPayRefundRequest request = new WxPayRefundRequest()
- .setOutTradeNo("1689545667276")
- .setOutRefundNo(String.valueOf(System.currentTimeMillis()))
- .setRefundFee(1)
- .setRefundDesc("就是想退了")
- .setTotalFee(1);
- System.out.println("========= request ==========");
- System.out.println(JsonUtils.toJsonPrettyString(request));
- WxPayRefundResult response = client.refund(request);
- System.out.println("========= response ==========");
- System.out.println(JsonUtils.toJsonPrettyString(response));
- }
-
- @Test
- public void testRefundV3() throws WxPayException {
- // 创建 config 配置
- WxPayConfig config = buildWxPayConfigV2();
- // 创建 WxPayService 客户端
- WxPayService client = new WxPayServiceImpl();
- client.setConfig(config);
-
- // 执行发起退款
- WxPayRefundV3Request request = new WxPayRefundV3Request()
- .setOutTradeNo("1689506325635")
- .setOutRefundNo(String.valueOf(System.currentTimeMillis()))
- .setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
- .setReason("就是想退了");
- System.out.println("========= request ==========");
- System.out.println(JsonUtils.toJsonPrettyString(request));
- WxPayRefundV3Result response = client.refundV3(request);
- System.out.println("========= response ==========");
- System.out.println(JsonUtils.toJsonPrettyString(response));
- }
-
- private WxPayConfig buildWxPayConfigV2() {
- WxPayConfig config = new WxPayConfig();
- config.setAppId("wx62056c0d5e8db250");
- config.setMchId("1545083881");
- config.setMchKey("dS1ngeN63JLr3NRbvPH9AJy3MyUxZdim");
-// config.setSignType(WxPayConstants.SignType.MD5);
- config.setKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.p12");
- return config;
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClientIntegrationTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClientIntegrationTest.java
deleted file mode 100644
index 5e73601c2b..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClientIntegrationTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
-
-import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
-import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
-import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
-import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
-import com.github.binarywang.wxpay.config.WxPayConfig;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import com.github.binarywang.wxpay.service.WxPayService;
-import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import java.time.Duration;
-
-import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.AbstractWxPayClient.formatDateV3;
-
-/**
- * {@link WxNativePayClient} 的集成测试,用于快速调试微信扫码支付
- *
- * @author 芋道源码
- */
-@Disabled
-public class WxNativePayClientIntegrationTest {
-
- @Test
- public void testPayV3() throws WxPayException {
- // 创建 config 配置
- WxPayConfig config = buildWxPayConfigV3();
- // 创建 WxPayService 客户端
- WxPayService client = new WxPayServiceImpl();
- client.setConfig(config);
-
- // 执行发起支付
- WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request()
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .setDescription("测试支付-body")
- .setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(1)) // 单位分
- .setTimeExpire(formatDateV3(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
- .setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp("127.0.0.1"))
- .setNotifyUrl("http://127.0.0.1:48080");
- System.out.println("========= request ==========");
- System.out.println(JsonUtils.toJsonPrettyString(request));
- String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
- System.out.println("========= response ==========");
- System.out.println(JsonUtils.toJsonPrettyString(response));
- }
-
- @Test
- public void testRefundV3() throws WxPayException {
- // 创建 config 配置
- WxPayConfig config = buildWxPayConfigV3();
- // 创建 WxPayService 客户端
- WxPayService client = new WxPayServiceImpl();
- client.setConfig(config);
-
- // 执行发起退款
- WxPayRefundV3Request request = new WxPayRefundV3Request()
- .setOutTradeNo("1689545729695")
- .setOutRefundNo(String.valueOf(System.currentTimeMillis()))
- .setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
- .setReason("就是想退了");
- System.out.println("========= request ==========");
- System.out.println(JsonUtils.toJsonPrettyString(request));
- WxPayRefundV3Result response = client.refundV3(request);
- System.out.println("========= response ==========");
- System.out.println(JsonUtils.toJsonPrettyString(response));
- }
-
- private WxPayConfig buildWxPayConfigV3() {
- WxPayConfig config = new WxPayConfig();
- config.setAppId("wx62056c0d5e8db250");
- config.setMchId("1545083881");
- config.setApiV3Key("459arNsYHl1mgkiO6H9ZH5KkhFXSxaA4");
-// config.setCertSerialNo(serialNo);
- config.setPrivateCertPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem");
- config.setPrivateKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_key.pem");
- return config;
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-sms/pom.xml
index faa6a8d34d..c0d056c18d 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-sms/pom.xml
@@ -33,13 +33,6 @@
opentracing-util
-
-
- cn.iocoder.boot
- yudao-spring-boot-starter-test
- test
-
-
com.google.guava
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/test/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/test/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsClientTest.java
deleted file mode 100644
index c60cd26a1b..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/test/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsClientTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-package cn.iocoder.yudao.framework.sms.core.client.impl.aliyun;
-
-import cn.hutool.core.util.ReflectUtil;
-import cn.iocoder.yudao.framework.common.core.KeyValue;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsReceiveRespDTO;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsSendRespDTO;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO;
-import cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
-import cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties;
-import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
-import com.aliyuncs.IAcsClient;
-import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest;
-import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateResponse;
-import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
-import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
-import com.google.common.collect.Lists;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.when;
-
-/**
- * {@link AliyunSmsClient} 的单元测试
- *
- * @author 芋道源码
- */
-public class AliyunSmsClientTest extends BaseMockitoUnitTest {
-
- private final SmsChannelProperties properties = new SmsChannelProperties()
- .setApiKey(randomString()) // 随机一个 apiKey,避免构建报错
- .setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
- .setSignature("芋道源码");
-
- @InjectMocks
- private final AliyunSmsClient smsClient = new AliyunSmsClient(properties);
-
- @Mock
- private IAcsClient client;
-
- @Test
- public void testDoInit() {
- // 准备参数
- // mock 方法
-
- // 调用
- smsClient.doInit();
- // 断言
- assertNotSame(client, ReflectUtil.getFieldValue(smsClient, "acsClient"));
- }
-
- @Test
- public void tesSendSms_success() throws Throwable {
- // 准备参数
- Long sendLogId = randomLongId();
- String mobile = randomString();
- String apiTemplateId = randomString();
- List> templateParams = Lists.newArrayList(
- new KeyValue<>("code", 1234), new KeyValue<>("op", "login"));
- // mock 方法
- SendSmsResponse response = randomPojo(SendSmsResponse.class, o -> o.setCode("OK"));
- when(client.getAcsResponse(argThat((ArgumentMatcher) acsRequest -> {
- assertEquals(mobile, acsRequest.getPhoneNumbers());
- assertEquals(properties.getSignature(), acsRequest.getSignName());
- assertEquals(apiTemplateId, acsRequest.getTemplateCode());
- assertEquals(toJsonString(MapUtils.convertMap(templateParams)), acsRequest.getTemplateParam());
- assertEquals(sendLogId.toString(), acsRequest.getOutId());
- return true;
- }))).thenReturn(response);
-
- // 调用
- SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
- apiTemplateId, templateParams);
- // 断言
- assertTrue(result.getSuccess());
- assertEquals(response.getRequestId(), result.getApiRequestId());
- assertEquals(response.getCode(), result.getApiCode());
- assertEquals(response.getMessage(), result.getApiMsg());
- assertEquals(response.getBizId(), result.getSerialNo());
- }
-
- @Test
- public void tesSendSms_fail() throws Throwable {
- // 准备参数
- Long sendLogId = randomLongId();
- String mobile = randomString();
- String apiTemplateId = randomString();
- List> templateParams = Lists.newArrayList(
- new KeyValue<>("code", 1234), new KeyValue<>("op", "login"));
- // mock 方法
- SendSmsResponse response = randomPojo(SendSmsResponse.class, o -> o.setCode("ERROR"));
- when(client.getAcsResponse(argThat((ArgumentMatcher) acsRequest -> {
- assertEquals(mobile, acsRequest.getPhoneNumbers());
- assertEquals(properties.getSignature(), acsRequest.getSignName());
- assertEquals(apiTemplateId, acsRequest.getTemplateCode());
- assertEquals(toJsonString(MapUtils.convertMap(templateParams)), acsRequest.getTemplateParam());
- assertEquals(sendLogId.toString(), acsRequest.getOutId());
- return true;
- }))).thenReturn(response);
-
- // 调用
- SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
- // 断言
- assertFalse(result.getSuccess());
- assertEquals(response.getRequestId(), result.getApiRequestId());
- assertEquals(response.getCode(), result.getApiCode());
- assertEquals(response.getMessage(), result.getApiMsg());
- assertEquals(response.getBizId(), result.getSerialNo());
- }
-
- @Test
- public void testParseSmsReceiveStatus() {
- // 准备参数
- String text = "[\n" +
- " {\n" +
- " \"phone_number\" : \"13900000001\",\n" +
- " \"send_time\" : \"2017-01-01 11:12:13\",\n" +
- " \"report_time\" : \"2017-02-02 22:23:24\",\n" +
- " \"success\" : true,\n" +
- " \"err_code\" : \"DELIVERED\",\n" +
- " \"err_msg\" : \"用户接收成功\",\n" +
- " \"sms_size\" : \"1\",\n" +
- " \"biz_id\" : \"12345\",\n" +
- " \"out_id\" : \"67890\"\n" +
- " }\n" +
- "]";
- // mock 方法
-
- // 调用
- List statuses = smsClient.parseSmsReceiveStatus(text);
- // 断言
- assertEquals(1, statuses.size());
- assertTrue(statuses.get(0).getSuccess());
- assertEquals("DELIVERED", statuses.get(0).getErrorCode());
- assertEquals("用户接收成功", statuses.get(0).getErrorMsg());
- assertEquals("13900000001", statuses.get(0).getMobile());
- assertEquals(LocalDateTime.of(2017, 2, 2, 22, 23, 24),
- statuses.get(0).getReceiveTime());
- assertEquals("12345", statuses.get(0).getSerialNo());
- assertEquals(67890L, statuses.get(0).getLogId());
- }
-
- @Test
- public void testGetSmsTemplate() throws Throwable {
- // 准备参数
- String apiTemplateId = randomString();
- // mock 方法
- QuerySmsTemplateResponse response = randomPojo(QuerySmsTemplateResponse.class, o -> {
- o.setCode("OK");
- o.setTemplateStatus(1); // 设置模板通过
- });
- when(client.getAcsResponse(argThat((ArgumentMatcher) acsRequest -> {
- assertEquals(apiTemplateId, acsRequest.getTemplateCode());
- return true;
- }))).thenReturn(response);
-
- // 调用
- SmsTemplateRespDTO result = smsClient.getSmsTemplate(apiTemplateId);
- // 断言
- assertEquals(response.getTemplateCode(), result.getId());
- assertEquals(response.getTemplateContent(), result.getContent());
- assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getAuditStatus());
- assertEquals(response.getReason(), result.getAuditReason());
- }
-
- @Test
- public void testConvertSmsTemplateAuditStatus() {
- assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
- smsClient.convertSmsTemplateAuditStatus(0));
- assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
- smsClient.convertSmsTemplateAuditStatus(1));
- assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
- smsClient.convertSmsTemplateAuditStatus(2));
- assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus(3),
- "未知审核状态(3)");
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/test/java/cn/iocoder/yudao/framework/sms/core/client/impl/tencent/TencentSmsClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/test/java/cn/iocoder/yudao/framework/sms/core/client/impl/tencent/TencentSmsClientTest.java
deleted file mode 100644
index d62eed1e1f..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/test/java/cn/iocoder/yudao/framework/sms/core/client/impl/tencent/TencentSmsClientTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-package cn.iocoder.yudao.framework.sms.core.client.impl.tencent;
-
-import cn.hutool.core.util.ReflectUtil;
-import cn.iocoder.yudao.framework.common.core.KeyValue;
-import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsReceiveRespDTO;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsSendRespDTO;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO;
-import cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
-import cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties;
-import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
-import com.google.common.collect.Lists;
-import com.tencentcloudapi.sms.v20210111.SmsClient;
-import com.tencentcloudapi.sms.v20210111.models.DescribeSmsTemplateListResponse;
-import com.tencentcloudapi.sms.v20210111.models.DescribeTemplateListStatus;
-import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
-import com.tencentcloudapi.sms.v20210111.models.SendStatus;
-import org.junit.jupiter.api.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.when;
-
-/**
- * {@link TencentSmsClient} 的单元测试
- *
- * @author shiwp
- */
-public class TencentSmsClientTest extends BaseMockitoUnitTest {
-
- private final SmsChannelProperties properties = new SmsChannelProperties()
- .setApiKey(randomString() + " " + randomString()) // 随机一个 apiKey,避免构建报错
- .setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
- .setSignature("芋道源码");
-
- @InjectMocks
- private TencentSmsClient smsClient = new TencentSmsClient(properties);
-
- @Mock
- private SmsClient client;
-
- @Test
- public void testDoInit() {
- // 准备参数
- // mock 方法
-
- // 调用
- smsClient.doInit();
- // 断言
- assertNotSame(client, ReflectUtil.getFieldValue(smsClient, "client"));
- }
-
- @Test
- public void testRefresh() {
- // 准备参数
- SmsChannelProperties p = new SmsChannelProperties()
- .setApiKey(randomString() + " " + randomString()) // 随机一个 apiKey,避免构建报错
- .setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
- .setSignature("芋道源码");
- // 调用
- smsClient.refresh(p);
- // 断言
- assertNotSame(client, ReflectUtil.getFieldValue(smsClient, "client"));
- }
-
- @Test
- public void testDoSendSms_success() throws Throwable {
- // 准备参数
- Long sendLogId = randomLongId();
- String mobile = randomString();
- String apiTemplateId = randomString();
- List> templateParams = Lists.newArrayList(
- new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
- String requestId = randomString();
- String serialNo = randomString();
- // mock 方法
- SendSmsResponse response = randomPojo(SendSmsResponse.class, o -> {
- o.setRequestId(requestId);
- SendStatus[] sendStatuses = new SendStatus[1];
- o.setSendStatusSet(sendStatuses);
- SendStatus sendStatus = new SendStatus();
- sendStatuses[0] = sendStatus;
- sendStatus.setCode(TencentSmsClient.API_CODE_SUCCESS);
- sendStatus.setMessage("send success");
- sendStatus.setSerialNo(serialNo);
- });
- when(client.SendSms(argThat(request -> {
- assertEquals(mobile, request.getPhoneNumberSet()[0]);
- assertEquals(properties.getSignature(), request.getSignName());
- assertEquals(apiTemplateId, request.getTemplateId());
- assertEquals(toJsonString(ArrayUtils.toArray(new ArrayList<>(MapUtils.convertMap(templateParams).values()), String::valueOf)),
- toJsonString(request.getTemplateParamSet()));
- assertEquals(sendLogId, ReflectUtil.getFieldValue(JsonUtils.parseObject(request.getSessionContext(), TencentSmsClient.SessionContext.class), "logId"));
- return true;
- }))).thenReturn(response);
-
- // 调用
- SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
- // 断言
- assertTrue(result.getSuccess());
- assertEquals(response.getRequestId(), result.getApiRequestId());
- assertEquals(response.getSendStatusSet()[0].getCode(), result.getApiCode());
- assertEquals(response.getSendStatusSet()[0].getMessage(), result.getApiMsg());
- assertEquals(response.getSendStatusSet()[0].getSerialNo(), result.getSerialNo());
- }
-
- @Test
- public void testDoSendSms_fail() throws Throwable {
- // 准备参数
- Long sendLogId = randomLongId();
- String mobile = randomString();
- String apiTemplateId = randomString();
- List> templateParams = Lists.newArrayList(
- new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
- String requestId = randomString();
- String serialNo = randomString();
- // mock 方法
- SendSmsResponse response = randomPojo(SendSmsResponse.class, o -> {
- o.setRequestId(requestId);
- SendStatus[] sendStatuses = new SendStatus[1];
- o.setSendStatusSet(sendStatuses);
- SendStatus sendStatus = new SendStatus();
- sendStatuses[0] = sendStatus;
- sendStatus.setCode("ERROR");
- sendStatus.setMessage("send success");
- sendStatus.setSerialNo(serialNo);
- });
- when(client.SendSms(argThat(request -> {
- assertEquals(mobile, request.getPhoneNumberSet()[0]);
- assertEquals(properties.getSignature(), request.getSignName());
- assertEquals(apiTemplateId, request.getTemplateId());
- assertEquals(toJsonString(ArrayUtils.toArray(new ArrayList<>(MapUtils.convertMap(templateParams).values()), String::valueOf)),
- toJsonString(request.getTemplateParamSet()));
- assertEquals(sendLogId, ReflectUtil.getFieldValue(JsonUtils.parseObject(request.getSessionContext(), TencentSmsClient.SessionContext.class), "logId"));
- return true;
- }))).thenReturn(response);
-
- // 调用
- SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
- // 断言
- assertFalse(result.getSuccess());
- assertEquals(response.getRequestId(), result.getApiRequestId());
- assertEquals(response.getSendStatusSet()[0].getCode(), result.getApiCode());
- assertEquals(response.getSendStatusSet()[0].getMessage(), result.getApiMsg());
- assertEquals(response.getSendStatusSet()[0].getSerialNo(), result.getSerialNo());
- }
-
- @Test
- public void testParseSmsReceiveStatus() {
- // 准备参数
- String text = "[\n" +
- " {\n" +
- " \"user_receive_time\": \"2015-10-17 08:03:04\",\n" +
- " \"nationcode\": \"86\",\n" +
- " \"mobile\": \"13900000001\",\n" +
- " \"report_status\": \"SUCCESS\",\n" +
- " \"errmsg\": \"DELIVRD\",\n" +
- " \"description\": \"用户短信送达成功\",\n" +
- " \"sid\": \"12345\",\n" +
- " \"ext\": {\"logId\":\"67890\"}\n" +
- " }\n" +
- "]";
- // mock 方法
-
- // 调用
- List statuses = smsClient.parseSmsReceiveStatus(text);
- // 断言
- assertEquals(1, statuses.size());
- assertTrue(statuses.get(0).getSuccess());
- assertEquals("DELIVRD", statuses.get(0).getErrorCode());
- assertEquals("用户短信送达成功", statuses.get(0).getErrorMsg());
- assertEquals("13900000001", statuses.get(0).getMobile());
- assertEquals(LocalDateTime.of(2015, 10, 17, 8, 3, 4), statuses.get(0).getReceiveTime());
- assertEquals("12345", statuses.get(0).getSerialNo());
- assertEquals(67890L, statuses.get(0).getLogId());
- }
-
- @Test
- public void testGetSmsTemplate() throws Throwable {
- // 准备参数
- Long apiTemplateId = randomLongId();
- String requestId = randomString();
-
- // mock 方法
- DescribeSmsTemplateListResponse response = randomPojo(DescribeSmsTemplateListResponse.class, o -> {
- DescribeTemplateListStatus[] describeTemplateListStatuses = new DescribeTemplateListStatus[1];
- DescribeTemplateListStatus templateStatus = new DescribeTemplateListStatus();
- templateStatus.setTemplateId(apiTemplateId);
- templateStatus.setStatusCode(0L);// 设置模板通过
- describeTemplateListStatuses[0] = templateStatus;
- o.setDescribeTemplateStatusSet(describeTemplateListStatuses);
- o.setRequestId(requestId);
- });
- when(client.DescribeSmsTemplateList(argThat(request -> {
- assertEquals(apiTemplateId, request.getTemplateIdSet()[0]);
- return true;
- }))).thenReturn(response);
-
- // 调用
- SmsTemplateRespDTO result = smsClient.getSmsTemplate(apiTemplateId.toString());
- // 断言
- assertEquals(response.getDescribeTemplateStatusSet()[0].getTemplateId().toString(), result.getId());
- assertEquals(response.getDescribeTemplateStatusSet()[0].getTemplateContent(), result.getContent());
- assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getAuditStatus());
- assertEquals(response.getDescribeTemplateStatusSet()[0].getReviewReply(), result.getAuditReason());
- }
-
- @Test
- public void testConvertSmsTemplateAuditStatus() {
- assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
- smsClient.convertSmsTemplateAuditStatus(0));
- assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
- smsClient.convertSmsTemplateAuditStatus(1));
- assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
- smsClient.convertSmsTemplateAuditStatus(-1));
- assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus(3),
- "未知审核状态(3)");
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml
index c1a537613e..b831767fc6 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml
@@ -66,13 +66,6 @@
true
-
-
- cn.iocoder.boot
- yudao-spring-boot-starter-test
- test
-
-
com.google.guava
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/pom.xml b/yudao-framework/yudao-spring-boot-starter-desensitize/pom.xml
index c4a96ebe1e..90d30fa1c3 100644
--- a/yudao-framework/yudao-spring-boot-starter-desensitize/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/pom.xml
@@ -28,11 +28,5 @@
jackson-databind
-
-
- cn.iocoder.boot
- yudao-spring-boot-starter-test
- test
-
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/DesensitizeTest.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/DesensitizeTest.java
deleted file mode 100644
index c308a0eb55..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/DesensitizeTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package cn.iocoder.yudao.framework.desensitize.core;
-
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.EmailDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.RegexDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.annotation.Address;
-import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.BankCardDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.CarLicenseDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.ChineseNameDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.FixedPhoneDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.IdCardDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.PasswordDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.MobileDesensitize;
-import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.SliderDesensitize;
-import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
-import lombok.Data;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * {@link DesensitizeTest} 的单元测试
- */
-public class DesensitizeTest extends BaseMockitoUnitTest {
-
- @Test
- public void test() {
- // 准备参数
- DesensitizeDemo desensitizeDemo = new DesensitizeDemo();
- desensitizeDemo.setNickname("芋道源码");
- desensitizeDemo.setBankCard("9988002866797031");
- desensitizeDemo.setCarLicense("粤A66666");
- desensitizeDemo.setFixedPhone("01086551122");
- desensitizeDemo.setIdCard("530321199204074611");
- desensitizeDemo.setPassword("123456");
- desensitizeDemo.setPhoneNumber("13248765917");
- desensitizeDemo.setSlider1("ABCDEFG");
- desensitizeDemo.setSlider2("ABCDEFG");
- desensitizeDemo.setSlider3("ABCDEFG");
- desensitizeDemo.setEmail("1@email.com");
- desensitizeDemo.setRegex("你好,我是芋道源码");
- desensitizeDemo.setAddress("北京市海淀区上地十街10号");
- desensitizeDemo.setOrigin("芋道源码");
-
- // 调用
- DesensitizeDemo d = JsonUtils.parseObject(JsonUtils.toJsonString(desensitizeDemo), DesensitizeDemo.class);
- // 断言
- assertNotNull(d);
- assertEquals("芋***", d.getNickname());
- assertEquals("998800********31", d.getBankCard());
- assertEquals("粤A6***6", d.getCarLicense());
- assertEquals("0108*****22", d.getFixedPhone());
- assertEquals("530321**********11", d.getIdCard());
- assertEquals("******", d.getPassword());
- assertEquals("132****5917", d.getPhoneNumber());
- assertEquals("#######", d.getSlider1());
- assertEquals("ABC*EFG", d.getSlider2());
- assertEquals("*******", d.getSlider3());
- assertEquals("1****@email.com", d.getEmail());
- assertEquals("你好,我是*", d.getRegex());
- assertEquals("北京市海淀区上地十街10号*", d.getAddress());
- assertEquals("芋道源码", d.getOrigin());
- }
-
- @Data
- public static class DesensitizeDemo {
-
- @ChineseNameDesensitize
- private String nickname;
- @BankCardDesensitize
- private String bankCard;
- @CarLicenseDesensitize
- private String carLicense;
- @FixedPhoneDesensitize
- private String fixedPhone;
- @IdCardDesensitize
- private String idCard;
- @PasswordDesensitize
- private String password;
- @MobileDesensitize
- private String phoneNumber;
- @SliderDesensitize(prefixKeep = 6, suffixKeep = 1, replacer = "#")
- private String slider1;
- @SliderDesensitize(prefixKeep = 3, suffixKeep = 3)
- private String slider2;
- @SliderDesensitize(prefixKeep = 10)
- private String slider3;
- @EmailDesensitize
- private String email;
- @RegexDesensitize(regex = "芋道源码", replacer = "*")
- private String regex;
- @Address
- private String address;
- private String origin;
-
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/annotation/Address.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/annotation/Address.java
deleted file mode 100644
index 735d25b346..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/annotation/Address.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.framework.desensitize.core.annotation;
-
-import cn.iocoder.yudao.framework.desensitize.core.DesensitizeTest;
-import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
-import cn.iocoder.yudao.framework.desensitize.core.handler.AddressHandler;
-import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 地址
- *
- * 用于 {@link DesensitizeTest} 测试使用
- *
- * @author gaibu
- */
-@Documented
-@Target({ElementType.FIELD})
-@Retention(RetentionPolicy.RUNTIME)
-@JacksonAnnotationsInside
-@DesensitizeBy(handler = AddressHandler.class)
-public @interface Address {
-
- String replacer() default "*";
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/handler/AddressHandler.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/handler/AddressHandler.java
deleted file mode 100644
index 7a8455f8d1..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/handler/AddressHandler.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.framework.desensitize.core.handler;
-
-import cn.iocoder.yudao.framework.desensitize.core.DesensitizeTest;
-import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler;
-import cn.iocoder.yudao.framework.desensitize.core.annotation.Address;
-
-/**
- * {@link Address} 的脱敏处理器
- *
- * 用于 {@link DesensitizeTest} 测试使用
- */
-public class AddressHandler implements DesensitizationHandler {
-
- @Override
- public String desensitize(String origin, Address annotation) {
- return origin + annotation.replacer();
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/pom.xml b/yudao-framework/yudao-spring-boot-starter-file/pom.xml
index 5ce48a857f..93fad220b5 100644
--- a/yudao-framework/yudao-spring-boot-starter-file/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-file/pom.xml
@@ -72,12 +72,6 @@
minio
-
-
- cn.iocoder.boot
- yudao-spring-boot-starter-test
- test
-
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/config/package-info.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/config/package-info.java
deleted file mode 100644
index 113f3e5e5f..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/config/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * 占位,避免 package 无法提交到 Git 仓库
- */
-package cn.iocoder.yudao.framework.file.config;
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/ftp/FtpFileClientTest.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/ftp/FtpFileClientTest.java
deleted file mode 100644
index 619e52db88..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/ftp/FtpFileClientTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package cn.iocoder.yudao.framework.file.core.client.ftp;
-
-import cn.hutool.core.io.resource.ResourceUtil;
-import cn.hutool.core.util.IdUtil;
-import cn.hutool.extra.ftp.FtpMode;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-public class FtpFileClientTest {
-
- @Test
- @Disabled
- public void test() {
- // 创建客户端
- FtpFileClientConfig config = new FtpFileClientConfig();
- config.setDomain("http://127.0.0.1:48080");
- config.setBasePath("/home/ftp");
- config.setHost("kanchai.club");
- config.setPort(221);
- config.setUsername("");
- config.setPassword("");
- config.setMode(FtpMode.Passive.name());
- FtpFileClient client = new FtpFileClient(0L, config);
- client.init();
- // 上传文件
- String path = IdUtil.fastSimpleUUID() + ".jpg";
- byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
- String fullPath = client.upload(content, path, "image/jpeg");
- System.out.println("访问地址:" + fullPath);
- if (false) {
- byte[] bytes = client.getContent(path);
- System.out.println("文件内容:" + bytes);
- }
- if (false) {
- client.delete(path);
- }
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/local/LocalFileClientTest.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/local/LocalFileClientTest.java
deleted file mode 100644
index d48609bc6c..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/local/LocalFileClientTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.framework.file.core.client.local;
-
-import cn.hutool.core.io.resource.ResourceUtil;
-import cn.hutool.core.util.IdUtil;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-public class LocalFileClientTest {
-
- @Test
- @Disabled
- public void test() {
- // 创建客户端
- LocalFileClientConfig config = new LocalFileClientConfig();
- config.setDomain("http://127.0.0.1:48080");
- config.setBasePath("/Users/yunai/file_test");
- LocalFileClient client = new LocalFileClient(0L, config);
- client.init();
- // 上传文件
- String path = IdUtil.fastSimpleUUID() + ".jpg";
- byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
- String fullPath = client.upload(content, path, "image/jpeg");
- System.out.println("访问地址:" + fullPath);
- client.delete(path);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientTest.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientTest.java
deleted file mode 100644
index cbd41ab3e0..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package cn.iocoder.yudao.framework.file.core.client.s3;
-
-import cn.hutool.core.io.resource.ResourceUtil;
-import cn.hutool.core.util.IdUtil;
-import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import jakarta.validation.Validation;
-
-public class S3FileClientTest {
-
- @Test
- @Disabled // MinIO,如果要集成测试,可以注释本行
- public void testMinIO() throws Exception {
- S3FileClientConfig config = new S3FileClientConfig();
- // 配置成你自己的
- config.setAccessKey("admin");
- config.setAccessSecret("password");
- config.setBucket("yudaoyuanma");
- config.setDomain(null);
- // 默认 9000 endpoint
- config.setEndpoint("http://127.0.0.1:9000");
-
- // 执行上传
- testExecuteUpload(config);
- }
-
- @Test
- @Disabled // 阿里云 OSS,如果要集成测试,可以注释本行
- public void testAliyun() throws Exception {
- S3FileClientConfig config = new S3FileClientConfig();
- // 配置成你自己的
- config.setAccessKey(System.getenv("ALIYUN_ACCESS_KEY"));
- config.setAccessSecret(System.getenv("ALIYUN_SECRET_KEY"));
- config.setBucket("yunai-aoteman");
- config.setDomain(null); // 如果有自定义域名,则可以设置。http://ali-oss.iocoder.cn
- // 默认北京的 endpoint
- config.setEndpoint("oss-cn-beijing.aliyuncs.com");
-
- // 执行上传
- testExecuteUpload(config);
- }
-
- @Test
- @Disabled // 腾讯云 COS,如果要集成测试,可以注释本行
- public void testQCloud() throws Exception {
- S3FileClientConfig config = new S3FileClientConfig();
- // 配置成你自己的
- config.setAccessKey(System.getenv("QCLOUD_ACCESS_KEY"));
- config.setAccessSecret(System.getenv("QCLOUD_SECRET_KEY"));
- config.setBucket("aoteman-1255880240");
- config.setDomain(null); // 如果有自定义域名,则可以设置。http://tengxun-oss.iocoder.cn
- // 默认上海的 endpoint
- config.setEndpoint("cos.ap-shanghai.myqcloud.com");
-
- // 执行上传
- testExecuteUpload(config);
- }
-
- @Test
- @Disabled // 七牛云存储,如果要集成测试,可以注释本行
- public void testQiniu() throws Exception {
- S3FileClientConfig config = new S3FileClientConfig();
- // 配置成你自己的
-// config.setAccessKey(System.getenv("QINIU_ACCESS_KEY"));
-// config.setAccessSecret(System.getenv("QINIU_SECRET_KEY"));
- config.setAccessKey("b7yvuhBSAGjmtPhMFcn9iMOxUOY_I06cA_p0ZUx8");
- config.setAccessSecret("kXM1l5ia1RvSX3QaOEcwI3RLz3Y2rmNszWonKZtP");
- config.setBucket("ruoyi-vue-pro");
- config.setDomain("http://test.yudao.iocoder.cn"); // 如果有自定义域名,则可以设置。http://static.yudao.iocoder.cn
- // 默认上海的 endpoint
- config.setEndpoint("s3-cn-south-1.qiniucs.com");
-
- // 执行上传
- testExecuteUpload(config);
- }
-
- @Test
- @Disabled // 华为云存储,如果要集成测试,可以注释本行
- public void testHuaweiCloud() throws Exception {
- S3FileClientConfig config = new S3FileClientConfig();
- // 配置成你自己的
-// config.setAccessKey(System.getenv("HUAWEI_CLOUD_ACCESS_KEY"));
-// config.setAccessSecret(System.getenv("HUAWEI_CLOUD_SECRET_KEY"));
- config.setBucket("yudao");
- config.setDomain(null); // 如果有自定义域名,则可以设置。
- // 默认上海的 endpoint
- config.setEndpoint("obs.cn-east-3.myhuaweicloud.com");
-
- // 执行上传
- testExecuteUpload(config);
- }
-
- private void testExecuteUpload(S3FileClientConfig config) throws Exception {
- // 校验配置
- ValidationUtils.validate(Validation.buildDefaultValidatorFactory().getValidator(), config);
- // 创建 Client
- S3FileClient client = new S3FileClient(0L, config);
- client.init();
- // 上传文件
- String path = IdUtil.fastSimpleUUID() + ".jpg";
- byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
- String fullPath = client.upload(content, path, "image/jpeg");
- System.out.println("访问地址:" + fullPath);
- // 读取文件
- if (true) {
- byte[] bytes = client.getContent(path);
- System.out.println("文件内容:" + bytes.length);
- }
- // 删除文件
- if (false) {
- client.delete(path);
- }
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/sftp/SftpFileClientTest.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/sftp/SftpFileClientTest.java
deleted file mode 100644
index 4785c0d892..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/sftp/SftpFileClientTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package cn.iocoder.yudao.framework.file.core.client.sftp;
-
-import cn.hutool.core.io.resource.ResourceUtil;
-import cn.hutool.core.util.IdUtil;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-public class SftpFileClientTest {
-
- @Test
- @Disabled
- public void test() {
- // 创建客户端
- SftpFileClientConfig config = new SftpFileClientConfig();
- config.setDomain("http://127.0.0.1:48080");
- config.setBasePath("/home/ftp");
- config.setHost("kanchai.club");
- config.setPort(222);
- config.setUsername("");
- config.setPassword("");
- SftpFileClient client = new SftpFileClient(0L, config);
- client.init();
- // 上传文件
- String path = IdUtil.fastSimpleUUID() + ".jpg";
- byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
- String fullPath = client.upload(content, path, "image/jpeg");
- System.out.println("访问地址:" + fullPath);
- if (false) {
- byte[] bytes = client.getContent(path);
- System.out.println("文件内容:" + bytes);
- }
- if (false) {
- client.delete(path);
- }
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/enums/package-info.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/enums/package-info.java
deleted file mode 100644
index e1da5db239..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/enums/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * 占位,避免 package 无法提交到 Git 仓库
- */
-package cn.iocoder.yudao.framework.file.core.enums;
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/resources/file/erweima.jpg b/yudao-framework/yudao-spring-boot-starter-file/src/test/resources/file/erweima.jpg
deleted file mode 100644
index 1447283cdf..0000000000
Binary files a/yudao-framework/yudao-spring-boot-starter-file/src/test/resources/file/erweima.jpg and /dev/null differ
diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml b/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml
deleted file mode 100644
index ac24f27aeb..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
- yudao-framework
- cn.iocoder.boot
- ${revision}
-
- 4.0.0
-
- yudao-spring-boot-starter-flowable
-
-
-
- cn.iocoder.boot
- yudao-common
-
-
-
-
- cn.iocoder.boot
- yudao-spring-boot-starter-security
-
-
-
-
- org.flowable
- flowable-spring-boot-starter-process
-
-
- org.flowable
- flowable-spring-boot-starter-actuator
-
-
-
-
diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java
deleted file mode 100644
index 7c29a64626..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package cn.iocoder.yudao.framework.flowable.config;
-
-import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
-import cn.iocoder.yudao.framework.flowable.core.web.FlowableWebFilter;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.core.task.AsyncListenableTaskExecutor;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-
-@AutoConfiguration
-public class YudaoFlowableConfiguration {
-
- /**
- * 参考 {@link org.flowable.spring.boot.FlowableJobConfiguration} 类,创建对应的 AsyncListenableTaskExecutor Bean
- *
- * 如果不创建,会导致项目启动时,Flowable 报错的问题
- */
- @Bean
- public AsyncListenableTaskExecutor taskExecutor() {
- ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
- executor.setCorePoolSize(8);
- executor.setMaxPoolSize(8);
- executor.setQueueCapacity(100);
- executor.setThreadNamePrefix("flowable-task-Executor-");
- executor.setAwaitTerminationSeconds(30);
- executor.setWaitForTasksToCompleteOnShutdown(true);
- executor.setAllowCoreThreadTimeOut(true);
- executor.initialize();
- return executor;
- }
-
- /**
- * 配置 flowable Web 过滤器
- */
- @Bean
- public FilterRegistrationBean flowableWebFilter() {
- FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
- registrationBean.setFilter(new FlowableWebFilter());
- registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER);
- return registrationBean;
- }
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/context/FlowableContextHolder.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/context/FlowableContextHolder.java
deleted file mode 100644
index efc6d5340d..0000000000
--- a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/context/FlowableContextHolder.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package cn.iocoder.yudao.framework.flowable.core.context;
-
-import cn.hutool.core.collection.CollUtil;
-import com.alibaba.ttl.TransmittableThreadLocal;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 工作流--用户用到的上下文相关信息
- */
-public class FlowableContextHolder {
-
- private static final ThreadLocal