Commit 6690b9b12035ae422c41f0b8ea268e5b1fa12805

Authored by YunaiV
1 parent 7ca756a2

完善支付宝的 AlipayPayClient 的实现

Showing 15 changed files with 307 additions and 56 deletions
yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
... ... @@ -19,6 +19,16 @@
19 19 <artifactId>yudao-common</artifactId>
20 20 </dependency>
21 21  
  22 + <!-- 工具类相关 -->
  23 + <dependency>
  24 + <groupId>jakarta.validation</groupId>
  25 + <artifactId>jakarta.validation-api</artifactId>
  26 + </dependency>
  27 + <dependency>
  28 + <groupId>org.hibernate.validator</groupId>
  29 + <artifactId>hibernate-validator</artifactId>
  30 + </dependency>
  31 +
22 32 <!-- 三方云服务相关 -->
23 33 <dependency>
24 34 <groupId>com.github.javen205</groupId>
... ... @@ -30,5 +40,6 @@
30 40 <artifactId>IJPay-WxPay</artifactId>
31 41 <version>2.7.8</version>
32 42 </dependency>
  43 +
33 44 </dependencies>
34 45 </project>
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/PayClient.java renamed to yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java
1   -package cn.iocoder.yudao.framework.pay.core;
  1 +package cn.iocoder.yudao.framework.pay.core.client;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
4 5  
5 6 /**
6 7 * 支付客户端,用于对接各支付渠道的 SDK,实现发起支付、退款等功能
... ... @@ -9,6 +10,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
9 10 */
10 11 public interface PayClient {
11 12  
12   - CommonResult<String> unifiedOrder();
  13 + // TODO 缺少注释
  14 + CommonResult<Object> unifiedOrder(PayOrderUnifiedReqDTO reqDTO);
13 15  
14 16 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/PayClientConfig.java renamed to yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientConfig.java
1   -package cn.iocoder.yudao.framework.pay.core;
  1 +package cn.iocoder.yudao.framework.pay.core.client;
2 2  
3 3 /**
4 4 * 支付客户端的配置,本质是支付渠道的配置
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayCodeMapping.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client;
  2 +
  3 +import cn.iocoder.yudao.framework.common.exception.ErrorCode;
  4 +import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
  5 +
  6 +import java.util.function.Function;
  7 +
  8 +/**
  9 + * 将 API 的错误码,转换为通用的错误码
  10 + *
  11 + * @see PayCommonResult
  12 + * @see PayFrameworkErrorCodeConstants
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +public interface PayCodeMapping extends Function<String, ErrorCode> {
  17 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayCommonResult.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client;
  2 +
  3 +import cn.hutool.core.exceptions.ExceptionUtil;
  4 +import cn.hutool.core.lang.Assert;
  5 +import cn.iocoder.yudao.framework.common.exception.ErrorCode;
  6 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  7 +import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
  8 +import lombok.Data;
  9 +import lombok.EqualsAndHashCode;
  10 +import lombok.ToString;
  11 +
  12 +/**
  13 + * 支付的 CommonResult 拓展类
  14 + *
  15 + * 考虑到不同的平台,返回的 code 和 msg 是不同的,所以统一额外返回 {@link #apiCode} 和 {@link #apiMsg} 字段
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +public class PayCommonResult<T> extends CommonResult<T> {
  23 +
  24 + /**
  25 + * API 返回错误码
  26 + *
  27 + * 由于第三方的错误码可能是字符串,所以使用 String 类型
  28 + */
  29 + private String apiCode;
  30 + /**
  31 + * API 返回提示
  32 + */
  33 + private String apiMsg;
  34 +
  35 + private PayCommonResult() {
  36 + }
  37 +
  38 + public static <T> PayCommonResult<T> build(String apiCode, String apiMsg, T data, PayCodeMapping codeMapping) {
  39 + Assert.notNull(codeMapping, "参数 codeMapping 不能为空");
  40 + PayCommonResult<T> result = new PayCommonResult<T>().setApiCode(apiCode).setApiMsg(apiMsg);
  41 + result.setData(data);
  42 + // 翻译错误码
  43 + if (codeMapping != null) {
  44 + ErrorCode errorCode = codeMapping.apply(apiCode);
  45 + if (errorCode == null) {
  46 + errorCode = PayFrameworkErrorCodeConstants.EXCEPTION;
  47 + }
  48 + result.setCode(errorCode.getCode()).setMsg(errorCode.getMsg());
  49 + }
  50 + return result;
  51 + }
  52 +
  53 + public static <T> PayCommonResult<T> error(Throwable ex) {
  54 + PayCommonResult<T> result = new PayCommonResult<>();
  55 + result.setCode(PayFrameworkErrorCodeConstants.EXCEPTION.getCode());
  56 + result.setMsg(ExceptionUtil.getRootCauseMessage(ex));
  57 + return result;
  58 + }
  59 +
  60 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/alipay/AlipayPayClient.java deleted
1   -package cn.iocoder.yudao.framework.pay.core.client.alipay;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4   -import cn.iocoder.yudao.framework.pay.core.client.AbstractPayClient;
5   -import com.alipay.api.AlipayApiException;
6   -import com.alipay.api.DefaultAlipayClient;
7   -import com.alipay.api.domain.AlipayTradePrecreateModel;
8   -import com.alipay.api.request.AlipayTradePrecreateRequest;
9   -import com.alipay.api.response.AlipayTradePrecreateResponse;
10   -
11   -/**
12   - * 支付宝的 PayClient 实现类
13   - */
14   -public class AlipayPayClient extends AbstractPayClient {
15   -
16   - private DefaultAlipayClient client = new DefaultAlipayClient("https://openapi.alipaydev.com/gateway.do","2021000118634035","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=","json","utf-8","MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB","RSA2");
17   -
18   - @Override
19   - public CommonResult<String> unifiedOrder() {
20   - AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
21   - AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
22   - request.setBizModel(model);
23   - model.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
24   - model.setTotalAmount("88.88");
25   - model.setSubject("Iphone6 16G");
26   - AlipayTradePrecreateResponse response = null;
27   - try {
28   - response = client.execute(request);
29   - } catch (AlipayApiException e) {
30   - e.printStackTrace();
31   - }
32   - System.out.println(response.getBody());
33   - System.out.println(response.getQrCode());
34   - return null;
35   - }
36   -
37   - public static void main(String[] args) {
38   - AlipayPayClient client = new AlipayPayClient();
39   - client.unifiedOrder();
40   - }
41   -
42   -}
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client.dto;
  2 +
  3 +import lombok.Data;
  4 +import org.hibernate.validator.constraints.Length;
  5 +
  6 +import javax.validation.constraints.DecimalMin;
  7 +import javax.validation.constraints.NotEmpty;
  8 +import javax.validation.constraints.NotNull;
  9 +import java.util.Date;
  10 +
  11 +/**
  12 + * 统一下单 Request DTO
  13 + */
  14 +@Data
  15 +public class PayOrderUnifiedReqDTO {
  16 +
  17 + /**
  18 + * 客户端 IP
  19 + */
  20 + @NotEmpty(message = "客户端 IP 不能为空")
  21 + private String clientIp;
  22 +
  23 + // ========== 商户相关字段 ==========
  24 +
  25 + /**
  26 + * 商户订单编号
  27 + */
  28 + @NotEmpty(message = "商户订单编号不能为空")
  29 + private String merchantOrderId;
  30 + /**
  31 + * 商品标题
  32 + */
  33 + @NotEmpty(message = "商品标题不能为空")
  34 + @Length(max = 32, message = "商品标题不能超过 32")
  35 + private String subject;
  36 + /**
  37 + * 商品描述信息
  38 + */
  39 + @NotEmpty(message = "商品描述信息不能为空")
  40 + @Length(max = 128, message = "商品描述信息长度不能超过128")
  41 + private String body;
  42 +
  43 + // ========== 订单相关字段 ==========
  44 +
  45 + /**
  46 + * 支付金额,单位:分
  47 + */
  48 + @NotNull(message = "支付金额不能为空")
  49 + @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
  50 + private Integer amount;
  51 +
  52 + /**
  53 + * 支付过期时间
  54 + */
  55 + @NotNull(message = "支付过期时间不能为空")
  56 + private Date expireTime;
  57 +
  58 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/AbstractPayClient.java renamed to yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java
1   -package cn.iocoder.yudao.framework.pay.core.client;
  1 +package cn.iocoder.yudao.framework.pay.core.client.impl;
2 2  
3   -import cn.iocoder.yudao.framework.pay.core.PayClient;
4   -import com.alipay.api.DefaultAlipayClient;
  3 +import cn.iocoder.yudao.framework.pay.core.client.PayClient;
  4 +import cn.iocoder.yudao.framework.pay.core.client.PayCodeMapping;
5 5  
6 6 /**
7 7 * 支付客户端的抽象类,提供模板方法,减少子类的冗余代码
... ... @@ -10,6 +10,13 @@ import com.alipay.api.DefaultAlipayClient;
10 10 */
11 11 public abstract class AbstractPayClient implements PayClient {
12 12  
  13 + /**
  14 + * 错误码枚举类
  15 + */
  16 + protected PayCodeMapping codeMapping;
13 17  
  18 + protected Double calculateAmount(Integer amount) {
  19 + return amount / 100.0;
  20 + }
14 21  
15 22 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClient.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
  6 +import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
  7 +import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
  8 +import com.alipay.api.AlipayApiException;
  9 +import com.alipay.api.AlipayConfig;
  10 +import com.alipay.api.DefaultAlipayClient;
  11 +import com.alipay.api.domain.AlipayTradePrecreateModel;
  12 +import com.alipay.api.request.AlipayTradePrecreateRequest;
  13 +import com.alipay.api.response.AlipayTradePrecreateResponse;
  14 +import lombok.SneakyThrows;
  15 +
  16 +/**
  17 + * 支付宝的 PayClient 实现类
  18 + */
  19 +public class AlipayPayClient extends AbstractPayClient {
  20 +
  21 + private final DefaultAlipayClient client;
  22 +
  23 + @SneakyThrows
  24 + public AlipayPayClient(AlipayPayConfig config) {
  25 + // 创建 DefaultAlipayClient 对象
  26 + AlipayConfig alipayConfig = new AlipayConfig();
  27 + BeanUtil.copyProperties(config, alipayConfig, false);
  28 + this.client = new DefaultAlipayClient(alipayConfig);
  29 +
  30 + // 创建 AlipayPayCodeMapping 对象
  31 + super.codeMapping = new AlipayPayCodeMapping();
  32 + }
  33 +
  34 + // TODO 芋艿:暂时是扫码支付,需要调整成 wap https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay
  35 + @Override
  36 + public CommonResult<Object> unifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
  37 + // 构建 AlipayTradePrecreateModel 请求
  38 + AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
  39 + model.setOutTradeNo(reqDTO.getMerchantOrderId());
  40 + model.setSubject(reqDTO.getSubject());
  41 + model.setBody(reqDTO.getBody());
  42 + model.setTotalAmount(calculateAmount(reqDTO.getAmount()).toString());
  43 + // TODO 芋艿:clientIp + expireTime
  44 + // 构建 AlipayTradePrecreateRequest
  45 + AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
  46 + request.setBizModel(model);
  47 +
  48 + // 执行请求
  49 + AlipayTradePrecreateResponse response = null;
  50 + try {
  51 + response = client.execute(request);
  52 + } catch (AlipayApiException e) {
  53 + return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
  54 + }
  55 +
  56 + System.out.println(response.getBody());
  57 + System.out.println(response.getQrCode());
  58 +
  59 + // TODO 芋艿:sub Code
  60 + return PayCommonResult.build(response.getCode(), response.getMsg(), response, codeMapping);
  61 + }
  62 +
  63 + public static void main(String[] args) {
  64 + AlipayPayConfig config = new AlipayPayConfig();
  65 + config.setAppId("2021000118634035");
  66 + config.setServerUrl(AlipayPayConfig.SERVER_URL_SANDBOX);
  67 + config.setSignType(AlipayPayConfig.SIGN_TYPE_DEFAULT);
  68 + 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=");
  69 + config.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB");
  70 + AlipayPayClient client = new AlipayPayClient(config);
  71 +
  72 + PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO();
  73 + reqDTO.setAmount(123);
  74 + reqDTO.setSubject("IPhone 13");
  75 + reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis()));
  76 + client.unifiedOrder(reqDTO);
  77 + }
  78 +
  79 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayCodeMapping.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
  2 +
  3 +import cn.iocoder.yudao.framework.common.exception.ErrorCode;
  4 +import cn.iocoder.yudao.framework.pay.core.client.PayCodeMapping;
  5 +
  6 +public class AlipayPayCodeMapping implements PayCodeMapping {
  7 +
  8 + @Override
  9 + public ErrorCode apply(String s) {
  10 + return null;
  11 + }
  12 +
  13 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/alipay/AlipayPayConfig.java renamed to yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayConfig.java
1   -package cn.iocoder.yudao.framework.pay.core.client.alipay;
  1 +package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2  
3 3 import lombok.Data;
4 4  
... ... @@ -15,11 +15,11 @@ public class AlipayPayConfig {
15 15 /**
16 16 * 网关地址 - 线上
17 17 */
18   - private static final String SERVER_URL_PROD = "https://openapi.alipay.com/gateway.do";
  18 + public static final String SERVER_URL_PROD = "https://openapi.alipay.com/gateway.do";
19 19 /**
20 20 * 网关地址 - 沙箱
21 21 */
22   - private static final String SERVER_URL_SANDBOX = "https://openapi.alipay.com/gateway.do";
  22 + public static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
23 23  
24 24 /**
25 25 * 公钥类型 - 公钥模式
... ... @@ -33,7 +33,7 @@ public class AlipayPayConfig {
33 33 /**
34 34 * 签名算法类型 - RSA
35 35 */
36   - private static final String SIGN_TYPE_DEFAULT = "RSA2";
  36 + public static final String SIGN_TYPE_DEFAULT = "RSA2";
37 37  
38 38 /**
39 39 * 网关地址
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/package-info.java deleted
1   -package cn.iocoder.yudao.framework.pay.core.client;
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayFrameworkErrorCodeConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.enums;
  2 +
  3 +import cn.iocoder.yudao.framework.common.exception.ErrorCode;
  4 +
  5 +/**
  6 + * 支付框架的错误码枚举
  7 + *
  8 + * 短信框架,使用 2-002-000-000 段
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +public interface PayFrameworkErrorCodeConstants {
  13 +
  14 + ErrorCode PAY_UNKNOWN = new ErrorCode(2001000000, "未知错误,需要解析");
  15 +
  16 +// // ========== 权限 / 限流等相关 2001000100 ==========
  17 +//
  18 +// ErrorCode SMS_PERMISSION_DENY = new ErrorCode(2001000100, "没有发送短信的权限");
  19 +// // 云片:可以配置 IP 白名单,只有在白名单中才可以发送短信
  20 +// ErrorCode SMS_IP_DENY = new ErrorCode(2001000100, "IP 不允许发送短信");
  21 +//
  22 +// // 阿里云:将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟,5 条 / 小时,累计 10 条 / 天。
  23 +// ErrorCode SMS_SEND_BUSINESS_LIMIT_CONTROL = new ErrorCode(2001000102, "指定手机的发送限流");
  24 +// // 阿里云:已经达到您在控制台设置的短信日发送量限额值。在国内消息设置 > 安全设置,修改发送总量阈值。
  25 +// ErrorCode SMS_SEND_DAY_LIMIT_CONTROL = new ErrorCode(2001000103, "每天的发送限流");
  26 +//
  27 +// ErrorCode SMS_SEND_CONTENT_INVALID = new ErrorCode(2001000104, "短信内容有敏感词");
  28 +//
  29 +// // ========== 模板相关 2001000200 ==========
  30 +// ErrorCode SMS_TEMPLATE_INVALID = new ErrorCode(2001000200, "短信模板不合法"); // 包括短信模板不存在
  31 +// ErrorCode SMS_TEMPLATE_PARAM_ERROR = new ErrorCode(2001000201, "模板参数不正确");
  32 +//
  33 +// // ========== 签名相关 2001000300 ==========
  34 +// ErrorCode SMS_SIGN_INVALID = new ErrorCode(2001000300, "短信签名不可用");
  35 +//
  36 +// // ========== 账户相关 2001000400 ==========
  37 +// ErrorCode SMS_ACCOUNT_MONEY_NOT_ENOUGH = new ErrorCode(2001000400, "账户余额不足");
  38 +// ErrorCode SMS_ACCOUNT_INVALID = new ErrorCode(2001000401, "apiKey 不存在");
  39 +//
  40 +// // ========== 其它相关 2001000900 开头 ==========
  41 +// ErrorCode SMS_API_PARAM_ERROR = new ErrorCode(2001000900, "请求参数缺失");
  42 +// ErrorCode SMS_MOBILE_INVALID = new ErrorCode(2001000901, "手机格式不正确");
  43 +// ErrorCode SMS_MOBILE_BLACK = new ErrorCode(2001000902, "手机号在黑名单中");
  44 +
  45 + ErrorCode EXCEPTION = new ErrorCode(2002000999, "调用异常");
  46 +
  47 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/yunpian/YunpianSmsClient.java
... ... @@ -83,7 +83,8 @@ public class YunpianSmsClient extends AbstractSmsClient {
83 83 }
84 84 // 参考 https://www.yunpian.com/official/document/sms/zh_cn/introduction_demos_encode_sample 格式化
85 85 StringJoiner joiner = new StringJoiner("&");
86   - templateParams.forEach(param -> joiner.add(String.format("#%s#=%s", param.getKey(), URLUtil.encode(String.valueOf(param.getValue())))));
  86 + templateParams.forEach(param -> joiner.add(String.format("#%s#=%s", param.getKey(),
  87 + URLUtil.encode(String.valueOf(param.getValue())))));
87 88 return joiner.toString();
88 89 }
89 90  
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/dto/ApiErrorLogCreateDTO.java
... ... @@ -4,7 +4,6 @@ import lombok.Data;
4 4 import lombok.experimental.Accessors;
5 5  
6 6 import javax.validation.constraints.NotNull;
7   -import java.io.Serializable;
8 7 import java.util.Date;
9 8  
10 9 /**
... ... @@ -14,7 +13,7 @@ import java.util.Date;
14 13 */
15 14 @Data
16 15 @Accessors(chain = true)
17   -public class ApiErrorLogCreateDTO implements Serializable {
  16 +public class ApiErrorLogCreateDTO {
18 17  
19 18 /**
20 19 * 链路编号
... ...