新增支付接口:支持支付宝pc沙箱支付流程、新增微信native预留接口

This commit is contained in:
gaoqr
2025-05-21 16:40:54 +08:00
parent 3fcd0abbf7
commit f94bf9f38e
28 changed files with 1198 additions and 113 deletions
@@ -0,0 +1,63 @@
package com.cf.imes.framework.common.exception;
import com.cf.imes.framework.common.exception.enums.ServiceErrorCodeRange;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 支付系统异常 Exception
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PayException extends RuntimeException {
/**
* 业务错误码
*
* @see ServiceErrorCodeRange
*/
private Integer code;
/**
* 错误提示
*/
private String message;
public PayException(Throwable cause) {
super(cause);
}
/**
* 空构造方法,避免反序列化问题
*/
public PayException() {
}
public PayException(ErrorCode errorCode) {
this.code = errorCode.getCode();
this.message = errorCode.getMsg();
}
public PayException(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public PayException setCode(Integer code) {
this.code = code;
return this;
}
@Override
public String getMessage() {
return message;
}
public PayException setMessage(String message) {
this.message = message;
return this;
}
}
@@ -0,0 +1,70 @@
package com.cf.imes.framework.pay.config;
import com.cf.imes.framework.common.util.encrypt.AesUtils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Gqr
* @since 2025/4/15 16:24
*/
@ConfigurationProperties(prefix = "chenfeng.pay.alipay")
@Data
public class ChenfengAlipayConfig extends com.alipay.api.AlipayConfig {
@Value("${chenfeng.encrypt.publicKey:}")
private String publicKey;
/**
* 销售产品码
*/
private String productCode = "FAST_INSTANT_TRADE_PAY";
/**
* 二维码模式:效果参见:https://help.pingxx.com/article/1137360/
*/
private String qrPayMode = "1";
/**
* 给支付宝的回调地址
*/
private String notifyUrl;
// 加密数据
@Override
public void setAppId(String appId) {
if (StringUtils.isNotEmpty(publicKey)) {
super.setAppId(AesUtils.decrypt(appId, publicKey));
} else {
super.setAppId(appId);
}
}
@Override
public void setPrivateKey(String privateKey) {
if (StringUtils.isNotEmpty(publicKey)) {
super.setPrivateKey(AesUtils.decrypt(privateKey, publicKey));
} else {
super.setPrivateKey(privateKey);
}
}
@Override
public void setAlipayPublicKey(String alipayPublicKey) {
if (StringUtils.isNotEmpty(publicKey)) {
super.setAlipayPublicKey(AesUtils.decrypt(alipayPublicKey, publicKey));
} else {
super.setAlipayPublicKey(alipayPublicKey);
}
}
public void setNotifyUrl(String notifyUrl) {
if (StringUtils.isNotEmpty(publicKey)) {
this.notifyUrl = AesUtils.decrypt(notifyUrl, publicKey);
} else {
this.notifyUrl = notifyUrl;
}
}
}
@@ -3,6 +3,7 @@ package com.cf.imes.framework.pay.config;
import com.cf.imes.framework.pay.core.client.PayClientFactory;
import com.cf.imes.framework.pay.core.client.impl.PayClientFactoryImpl;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
@@ -11,6 +12,7 @@ import org.springframework.context.annotation.Bean;
* @author 晨丰科技
*/
@AutoConfiguration
@EnableConfigurationProperties({ChenfengAlipayConfig.class, ChenfengWechatPayConfig.class})
public class ChenfengPayAutoConfiguration {
@Bean
@@ -0,0 +1,14 @@
package com.cf.imes.framework.pay.config;
import com.github.binarywang.wxpay.config.WxPayConfig;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Gqr
* @since 2025/4/15 16:52
*/
@ConfigurationProperties(prefix = "chenfeng.pay.wechat")
@Data
public class ChenfengWechatPayConfig extends WxPayConfig {
}
@@ -1,6 +1,6 @@
package com.cf.imes.framework.pay.core.client.dto.order;
import com.cf.imes.framework.pay.core.client.exception.PayException;
import com.cf.imes.framework.common.exception.PayException;
import com.cf.imes.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.cf.imes.framework.pay.core.enums.order.PayOrderStatusRespEnum;
import lombok.Data;
@@ -1,6 +1,7 @@
package com.cf.imes.framework.pay.core.client.dto.order;
import com.cf.imes.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.URL;
@@ -11,6 +12,9 @@ import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.Map;
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
import static com.cf.imes.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
/**
* 统一下单 Request DTO
*
@@ -70,6 +74,7 @@ public class PayOrderUnifiedReqDTO {
* 支付过期时间
*/
@NotNull(message = "支付过期时间不能为空")
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private LocalDateTime expireTime;
// ========== 拓展参数 ==========
@@ -1,6 +1,6 @@
package com.cf.imes.framework.pay.core.client.dto.refund;
import com.cf.imes.framework.pay.core.client.exception.PayException;
import com.cf.imes.framework.common.exception.PayException;
import com.cf.imes.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
import lombok.Data;
@@ -1,17 +0,0 @@
package com.cf.imes.framework.pay.core.client.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 支付系统异常 Exception
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PayException extends RuntimeException {
public PayException(Throwable cause) {
super(cause);
}
}
@@ -10,7 +10,7 @@ import com.cf.imes.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import com.cf.imes.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import com.cf.imes.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
import com.cf.imes.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
import com.cf.imes.framework.pay.core.client.exception.PayException;
import com.cf.imes.framework.common.exception.PayException;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
@@ -8,7 +8,7 @@ import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import com.cf.imes.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import com.cf.imes.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import com.cf.imes.framework.pay.core.client.exception.PayException;
import com.cf.imes.framework.common.exception.PayException;
import com.cf.imes.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
import com.alipay.api.AlipayApiException;
@@ -5,7 +5,7 @@ import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.pay.core.client.dto.order.PayOrderRespDTO;
import com.cf.imes.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import com.cf.imes.framework.pay.core.client.exception.PayException;
import com.cf.imes.framework.common.exception.PayException;
import com.cf.imes.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.request.AlipayTradePrecreateRequest;
@@ -3,6 +3,7 @@ package com.cf.imes.framework.web.core.handler;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.cf.imes.framework.common.exception.PayException;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.monitor.TracerUtils;
@@ -98,6 +99,9 @@ public class GlobalExceptionHandler {
if (ex instanceof HttpMessageNotReadableException) {
return httpMessageNotReadableExceptionHandler(request, (HttpMessageNotReadableException) ex);
}
if (ex instanceof PayException) {
return payExceptionHandler((PayException) ex);
}
return defaultExceptionHandler(request, ex);
}
@@ -260,6 +264,18 @@ public class GlobalExceptionHandler {
return CommonResult.error(ex.getCode(), ex.getMessage());
}
/**
* 支付异常 PayException
*
* @param ex
* @return
*/
@ExceptionHandler(value = PayException.class)
public CommonResult payExceptionHandler(PayException ex) {
log.info(String.format("==========[payExceptionHandler]==========%s", ex.getMessage()));
return CommonResult.error(ex.getCode(), ex.getMessage());
}
/**
* 处理数据库DuplicateKeyException,违反唯一约束异常
*