完善支付宝的 AlipayPayClient 的实现

This commit is contained in:
YunaiV 2021-10-20 08:27:44 +08:00
parent 7ca756a234
commit 6690b9b120
16 changed files with 319 additions and 68 deletions

View File

@ -19,6 +19,16 @@
<artifactId>yudao-common</artifactId> <artifactId>yudao-common</artifactId>
</dependency> </dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<!-- 三方云服务相关 --> <!-- 三方云服务相关 -->
<dependency> <dependency>
<groupId>com.github.javen205</groupId> <groupId>com.github.javen205</groupId>
@ -30,5 +40,6 @@
<artifactId>IJPay-WxPay</artifactId> <artifactId>IJPay-WxPay</artifactId>
<version>2.7.8</version> <version>2.7.8</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client;
import cn.iocoder.yudao.framework.pay.core.PayClient;
import com.alipay.api.DefaultAlipayClient;
/**
* 支付客户端的抽象类提供模板方法减少子类的冗余代码
*
* @author 芋道源码
*/
public abstract class AbstractPayClient implements PayClient {
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.framework.pay.core; package cn.iocoder.yudao.framework.pay.core.client;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
/** /**
* 支付客户端用于对接各支付渠道的 SDK实现发起支付退款等功能 * 支付客户端用于对接各支付渠道的 SDK实现发起支付退款等功能
@ -9,6 +10,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
*/ */
public interface PayClient { public interface PayClient {
CommonResult<String> unifiedOrder(); // TODO 缺少注释
CommonResult<Object> unifiedOrder(PayOrderUnifiedReqDTO reqDTO);
} }

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.framework.pay.core; package cn.iocoder.yudao.framework.pay.core.client;
/** /**
* 支付客户端的配置本质是支付渠道的配置 * 支付客户端的配置本质是支付渠道的配置

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.framework.pay.core.client;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
import java.util.function.Function;
/**
* API 的错误码转换为通用的错误码
*
* @see PayCommonResult
* @see PayFrameworkErrorCodeConstants
*
* @author 芋道源码
*/
public interface PayCodeMapping extends Function<String, ErrorCode> {
}

View File

@ -0,0 +1,60 @@
package cn.iocoder.yudao.framework.pay.core.client;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* 支付的 CommonResult 拓展类
*
* 考虑到不同的平台返回的 code msg 是不同的所以统一额外返回 {@link #apiCode} {@link #apiMsg} 字段
*
* @author 芋道源码
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PayCommonResult<T> extends CommonResult<T> {
/**
* API 返回错误码
*
* 由于第三方的错误码可能是字符串所以使用 String 类型
*/
private String apiCode;
/**
* API 返回提示
*/
private String apiMsg;
private PayCommonResult() {
}
public static <T> PayCommonResult<T> build(String apiCode, String apiMsg, T data, PayCodeMapping codeMapping) {
Assert.notNull(codeMapping, "参数 codeMapping 不能为空");
PayCommonResult<T> result = new PayCommonResult<T>().setApiCode(apiCode).setApiMsg(apiMsg);
result.setData(data);
// 翻译错误码
if (codeMapping != null) {
ErrorCode errorCode = codeMapping.apply(apiCode);
if (errorCode == null) {
errorCode = PayFrameworkErrorCodeConstants.EXCEPTION;
}
result.setCode(errorCode.getCode()).setMsg(errorCode.getMsg());
}
return result;
}
public static <T> PayCommonResult<T> error(Throwable ex) {
PayCommonResult<T> result = new PayCommonResult<>();
result.setCode(PayFrameworkErrorCodeConstants.EXCEPTION.getCode());
result.setMsg(ExceptionUtil.getRootCauseMessage(ex));
return result;
}
}

View File

@ -1,42 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.alipay;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.pay.core.client.AbstractPayClient;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
/**
* 支付宝的 PayClient 实现类
*/
public class AlipayPayClient extends AbstractPayClient {
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");
@Override
public CommonResult<String> unifiedOrder() {
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
request.setBizModel(model);
model.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
model.setTotalAmount("88.88");
model.setSubject("Iphone6 16G");
AlipayTradePrecreateResponse response = null;
try {
response = client.execute(request);
} catch (AlipayApiException e) {
e.printStackTrace();
}
System.out.println(response.getBody());
System.out.println(response.getQrCode());
return null;
}
public static void main(String[] args) {
AlipayPayClient client = new AlipayPayClient();
client.unifiedOrder();
}
}

View File

@ -0,0 +1,58 @@
package cn.iocoder.yudao.framework.pay.core.client.dto;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 统一下单 Request DTO
*/
@Data
public class PayOrderUnifiedReqDTO {
/**
* 客户端 IP
*/
@NotEmpty(message = "客户端 IP 不能为空")
private String clientIp;
// ========== 商户相关字段 ==========
/**
* 商户订单编号
*/
@NotEmpty(message = "商户订单编号不能为空")
private String merchantOrderId;
/**
* 商品标题
*/
@NotEmpty(message = "商品标题不能为空")
@Length(max = 32, message = "商品标题不能超过 32")
private String subject;
/**
* 商品描述信息
*/
@NotEmpty(message = "商品描述信息不能为空")
@Length(max = 128, message = "商品描述信息长度不能超过128")
private String body;
// ========== 订单相关字段 ==========
/**
* 支付金额单位
*/
@NotNull(message = "支付金额不能为空")
@DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
private Integer amount;
/**
* 支付过期时间
*/
@NotNull(message = "支付过期时间不能为空")
private Date expireTime;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.framework.pay.core.client.impl;
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.PayCodeMapping;
/**
* 支付客户端的抽象类提供模板方法减少子类的冗余代码
*
* @author 芋道源码
*/
public abstract class AbstractPayClient implements PayClient {
/**
* 错误码枚举类
*/
protected PayCodeMapping codeMapping;
protected Double calculateAmount(Integer amount) {
return amount / 100.0;
}
}

View File

@ -0,0 +1,79 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.SneakyThrows;
/**
* 支付宝的 PayClient 实现类
*/
public class AlipayPayClient extends AbstractPayClient {
private final DefaultAlipayClient client;
@SneakyThrows
public AlipayPayClient(AlipayPayConfig config) {
// 创建 DefaultAlipayClient 对象
AlipayConfig alipayConfig = new AlipayConfig();
BeanUtil.copyProperties(config, alipayConfig, false);
this.client = new DefaultAlipayClient(alipayConfig);
// 创建 AlipayPayCodeMapping 对象
super.codeMapping = new AlipayPayCodeMapping();
}
// TODO 芋艿暂时是扫码支付需要调整成 wap https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay
@Override
public CommonResult<Object> unifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
// 构建 AlipayTradePrecreateModel 请求
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo(reqDTO.getMerchantOrderId());
model.setSubject(reqDTO.getSubject());
model.setBody(reqDTO.getBody());
model.setTotalAmount(calculateAmount(reqDTO.getAmount()).toString());
// TODO 芋艿clientIp + expireTime
// 构建 AlipayTradePrecreateRequest
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setBizModel(model);
// 执行请求
AlipayTradePrecreateResponse response = null;
try {
response = client.execute(request);
} catch (AlipayApiException e) {
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
}
System.out.println(response.getBody());
System.out.println(response.getQrCode());
// TODO 芋艿sub Code
return PayCommonResult.build(response.getCode(), response.getMsg(), response, codeMapping);
}
public static void main(String[] args) {
AlipayPayConfig config = new AlipayPayConfig();
config.setAppId("2021000118634035");
config.setServerUrl(AlipayPayConfig.SERVER_URL_SANDBOX);
config.setSignType(AlipayPayConfig.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");
AlipayPayClient client = new AlipayPayClient(config);
PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO();
reqDTO.setAmount(123);
reqDTO.setSubject("IPhone 13");
reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis()));
client.unifiedOrder(reqDTO);
}
}

View File

@ -0,0 +1,13 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.pay.core.client.PayCodeMapping;
public class AlipayPayCodeMapping implements PayCodeMapping {
@Override
public ErrorCode apply(String s) {
return null;
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.framework.pay.core.client.alipay; package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import lombok.Data; import lombok.Data;
@ -15,11 +15,11 @@ public class AlipayPayConfig {
/** /**
* 网关地址 - 线上 * 网关地址 - 线上
*/ */
private static final String SERVER_URL_PROD = "https://openapi.alipay.com/gateway.do"; public static final String SERVER_URL_PROD = "https://openapi.alipay.com/gateway.do";
/** /**
* 网关地址 - 沙箱 * 网关地址 - 沙箱
*/ */
private static final String SERVER_URL_SANDBOX = "https://openapi.alipay.com/gateway.do"; public static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
/** /**
* 公钥类型 - 公钥模式 * 公钥类型 - 公钥模式
@ -33,7 +33,7 @@ public class AlipayPayConfig {
/** /**
* 签名算法类型 - RSA * 签名算法类型 - RSA
*/ */
private static final String SIGN_TYPE_DEFAULT = "RSA2"; public static final String SIGN_TYPE_DEFAULT = "RSA2";
/** /**
* 网关地址 * 网关地址

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.framework.pay.core.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* 支付框架的错误码枚举
*
* 短信框架使用 2-002-000-000
*
* @author 芋道源码
*/
public interface PayFrameworkErrorCodeConstants {
ErrorCode PAY_UNKNOWN = new ErrorCode(2001000000, "未知错误,需要解析");
// // ========== 权限 / 限流等相关 2001000100 ==========
//
// ErrorCode SMS_PERMISSION_DENY = new ErrorCode(2001000100, "没有发送短信的权限");
// // 云片可以配置 IP 白名单只有在白名单中才可以发送短信
// ErrorCode SMS_IP_DENY = new ErrorCode(2001000100, "IP 不允许发送短信");
//
// // 阿里云将短信发送频率限制在正常的业务限流范围内默认短信验证码使用同一签名对同一个手机号验证码支持 1 / 分钟5 / 小时累计 10 /
// ErrorCode SMS_SEND_BUSINESS_LIMIT_CONTROL = new ErrorCode(2001000102, "指定手机的发送限流");
// // 阿里云已经达到您在控制台设置的短信日发送量限额值在国内消息设置 > 安全设置修改发送总量阈值
// ErrorCode SMS_SEND_DAY_LIMIT_CONTROL = new ErrorCode(2001000103, "每天的发送限流");
//
// ErrorCode SMS_SEND_CONTENT_INVALID = new ErrorCode(2001000104, "短信内容有敏感词");
//
// // ========== 模板相关 2001000200 ==========
// ErrorCode SMS_TEMPLATE_INVALID = new ErrorCode(2001000200, "短信模板不合法"); // 包括短信模板不存在
// ErrorCode SMS_TEMPLATE_PARAM_ERROR = new ErrorCode(2001000201, "模板参数不正确");
//
// // ========== 签名相关 2001000300 ==========
// ErrorCode SMS_SIGN_INVALID = new ErrorCode(2001000300, "短信签名不可用");
//
// // ========== 账户相关 2001000400 ==========
// ErrorCode SMS_ACCOUNT_MONEY_NOT_ENOUGH = new ErrorCode(2001000400, "账户余额不足");
// ErrorCode SMS_ACCOUNT_INVALID = new ErrorCode(2001000401, "apiKey 不存在");
//
// // ========== 其它相关 2001000900 开头 ==========
// ErrorCode SMS_API_PARAM_ERROR = new ErrorCode(2001000900, "请求参数缺失");
// ErrorCode SMS_MOBILE_INVALID = new ErrorCode(2001000901, "手机格式不正确");
// ErrorCode SMS_MOBILE_BLACK = new ErrorCode(2001000902, "手机号在黑名单中");
ErrorCode EXCEPTION = new ErrorCode(2002000999, "调用异常");
}

View File

@ -83,7 +83,8 @@ public class YunpianSmsClient extends AbstractSmsClient {
} }
// 参考 https://www.yunpian.com/official/document/sms/zh_cn/introduction_demos_encode_sample 格式化 // 参考 https://www.yunpian.com/official/document/sms/zh_cn/introduction_demos_encode_sample 格式化
StringJoiner joiner = new StringJoiner("&"); StringJoiner joiner = new StringJoiner("&");
templateParams.forEach(param -> joiner.add(String.format("#%s#=%s", param.getKey(), URLUtil.encode(String.valueOf(param.getValue()))))); templateParams.forEach(param -> joiner.add(String.format("#%s#=%s", param.getKey(),
URLUtil.encode(String.valueOf(param.getValue())))));
return joiner.toString(); return joiner.toString();
} }

View File

@ -4,7 +4,6 @@ import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date; import java.util.Date;
/** /**
@ -14,7 +13,7 @@ import java.util.Date;
*/ */
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
public class ApiErrorLogCreateDTO implements Serializable { public class ApiErrorLogCreateDTO {
/** /**
* 链路编号 * 链路编号