Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # src/main/resources/application-dev.yml
This commit is contained in:
@@ -3,12 +3,16 @@ package com.gxwebsoft.common.core.utils;
|
||||
import com.wechat.pay.java.core.Config;
|
||||
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.gxwebsoft.common.core.config.ConfigProperties;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 微信支付证书自动配置工具类
|
||||
* 使用RSAAutoCertificateConfig实现证书自动管理
|
||||
*
|
||||
*
|
||||
* @author 科技小王子
|
||||
* @since 2024-07-26
|
||||
*/
|
||||
@@ -16,38 +20,47 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class WechatCertAutoConfig {
|
||||
|
||||
@Value("${spring.profiles.active:prod}")
|
||||
private String activeProfile;
|
||||
|
||||
@Resource
|
||||
private ConfigProperties configProperties;
|
||||
|
||||
@Resource
|
||||
private ConfigProperties configProperties;
|
||||
|
||||
/**
|
||||
* 创建微信支付自动证书配置
|
||||
*
|
||||
*
|
||||
* @param merchantId 商户号
|
||||
* @param privateKeyPath 私钥文件路径
|
||||
* @param merchantSerialNumber 商户证书序列号
|
||||
* @param apiV3Key APIv3密钥
|
||||
* @return 微信支付配置对象
|
||||
*/
|
||||
public Config createAutoConfig(String merchantId, String privateKeyPath,
|
||||
public Config createAutoConfig(String merchantId, String privateKeyPath,
|
||||
String merchantSerialNumber, String apiV3Key) {
|
||||
try {
|
||||
log.info("创建微信支付自动证书配置...");
|
||||
log.info("商户号: {}", merchantId);
|
||||
log.info("私钥路径: {}", privateKeyPath);
|
||||
log.info("证书序列号: {}", merchantSerialNumber);
|
||||
|
||||
|
||||
Config config = new RSAAutoCertificateConfig.Builder()
|
||||
.merchantId(merchantId)
|
||||
.privateKeyFromPath(privateKeyPath)
|
||||
.merchantSerialNumber(merchantSerialNumber)
|
||||
.apiV3Key(apiV3Key)
|
||||
.build();
|
||||
|
||||
|
||||
log.info("✅ 微信支付自动证书配置创建成功");
|
||||
log.info("🔄 系统将自动管理平台证书的下载和更新");
|
||||
|
||||
|
||||
return config;
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("❌ 创建微信支付自动证书配置失败: {}", e.getMessage(), e);
|
||||
|
||||
|
||||
// 提供详细的错误诊断信息
|
||||
log.error("🔍 错误诊断:");
|
||||
log.error("1. 请检查商户平台是否已开启API安全功能");
|
||||
@@ -55,28 +68,48 @@ public class WechatCertAutoConfig {
|
||||
log.error("3. 请验证APIv3密钥和证书序列号是否正确");
|
||||
log.error("4. 请检查网络连接是否正常");
|
||||
log.error("5. 请确认私钥文件路径是否正确: {}", privateKeyPath);
|
||||
|
||||
|
||||
throw new RuntimeException("微信支付自动证书配置失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 使用默认开发环境配置创建自动证书配置
|
||||
*
|
||||
* 根据当前环境自动选择证书路径
|
||||
* 开发环境拼接规则:配置文件upload-path + dev/wechat/ + 租户ID
|
||||
*
|
||||
* @return 微信支付配置对象
|
||||
*/
|
||||
public Config createDefaultDevConfig() {
|
||||
String merchantId = "1723321338";
|
||||
String privateKeyPath = "src/main/resources/certs/dev/wechat/apiclient_key.pem";
|
||||
String privateKeyPath;
|
||||
String merchantSerialNumber = "2B933F7C35014A1C363642623E4A62364B34C4EB";
|
||||
String apiV3Key = "0kF5OlPr482EZwtn9zGufUcqa7ovgxRL";
|
||||
|
||||
|
||||
// 根据环境选择证书路径
|
||||
if ("dev".equals(activeProfile)) {
|
||||
// 开发环境:使用配置文件upload-path拼接证书路径
|
||||
String uploadPath = configProperties.getUploadPath(); // 配置文件路径
|
||||
String tenantId = "10550"; // 租户ID
|
||||
String certPath = uploadPath + "dev/wechat/" + tenantId + "/";
|
||||
privateKeyPath = certPath + "apiclient_key.pem";
|
||||
|
||||
log.info("开发环境:使用配置文件upload-path拼接证书路径");
|
||||
log.info("配置文件upload-path: {}", uploadPath);
|
||||
log.info("证书基础路径: {}", certPath);
|
||||
log.info("私钥文件路径: {}", privateKeyPath);
|
||||
} else {
|
||||
// 生产环境:使用相对路径,由系统动态解析
|
||||
privateKeyPath = "src/main/resources/certs/dev/wechat/apiclient_key.pem";
|
||||
log.info("生产环境:使用相对证书路径 - {}", privateKeyPath);
|
||||
}
|
||||
|
||||
return createAutoConfig(merchantId, privateKeyPath, merchantSerialNumber, apiV3Key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 测试证书配置是否正常
|
||||
*
|
||||
*
|
||||
* @param config 微信支付配置
|
||||
* @return 是否配置成功
|
||||
*/
|
||||
@@ -84,56 +117,56 @@ public class WechatCertAutoConfig {
|
||||
try {
|
||||
// 这里可以添加一些基本的配置验证逻辑
|
||||
log.info("🧪 测试微信支付证书配置...");
|
||||
|
||||
|
||||
if (config == null) {
|
||||
log.error("配置对象为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
log.info("✅ 证书配置测试通过");
|
||||
return true;
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("❌ 证书配置测试失败: {}", e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取配置使用说明
|
||||
*
|
||||
*
|
||||
* @return 使用说明
|
||||
*/
|
||||
public String getUsageInstructions() {
|
||||
return """
|
||||
🚀 微信支付自动证书配置使用说明
|
||||
================================
|
||||
|
||||
|
||||
✅ 优势:
|
||||
1. 自动下载微信支付平台证书
|
||||
2. 证书过期时自动更新
|
||||
3. 无需手动管理 wechatpay_cert.pem 文件
|
||||
4. 符合微信支付官方最佳实践
|
||||
|
||||
|
||||
📝 使用方法:
|
||||
|
||||
|
||||
// 方法1: 使用默认开发环境配置
|
||||
Config config = wechatCertAutoConfig.createDefaultDevConfig();
|
||||
|
||||
|
||||
// 方法2: 自定义配置
|
||||
Config config = wechatCertAutoConfig.createAutoConfig(
|
||||
"商户号",
|
||||
"私钥路径",
|
||||
"证书序列号",
|
||||
"商户号",
|
||||
"私钥路径",
|
||||
"证书序列号",
|
||||
"APIv3密钥"
|
||||
);
|
||||
|
||||
|
||||
🔧 前置条件:
|
||||
1. 微信商户平台已开启API安全功能
|
||||
2. 已申请使用微信支付公钥
|
||||
3. 私钥文件存在且路径正确
|
||||
4. 网络连接正常
|
||||
|
||||
|
||||
📚 更多信息:
|
||||
https://pay.weixin.qq.com/doc/v3/merchant/4012153196
|
||||
""";
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.gxwebsoft.common.system.service.SettingService;
|
||||
import com.wechat.pay.java.core.Config;
|
||||
import com.wechat.pay.java.core.RSAConfig;
|
||||
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -41,6 +42,9 @@ public class SettingServiceImpl extends ServiceImpl<SettingMapper, Setting> impl
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Value("${spring.profiles.active:prod}")
|
||||
private String activeProfile;
|
||||
|
||||
@Override
|
||||
public PageResult<Setting> pageRel(SettingParam param) {
|
||||
PageParam<Setting, SettingParam> page = new PageParam<>(param);
|
||||
@@ -120,20 +124,41 @@ public class SettingServiceImpl extends ServiceImpl<SettingMapper, Setting> impl
|
||||
final String merchantSerialNumber = jsonObject.getString("merchantSerialNumber");
|
||||
final String apiV3key = jsonObject.getString("wechatApiKey");
|
||||
if(config == null){
|
||||
// config = new RSAAutoCertificateConfig.Builder()
|
||||
// .merchantId(mchId)
|
||||
// .privateKeyFromPath("/Users/gxwebsoft/Documents/uploads/file/20230622/fb193d3bfff0467b83dc498435a4f433.pem")
|
||||
// .merchantSerialNumber(merchantSerialNumber)
|
||||
// .apiV3Key(apiV3key)
|
||||
// .build();
|
||||
config =
|
||||
new RSAConfig.Builder()
|
||||
// 根据环境选择不同的证书路径配置
|
||||
if ("dev".equals(activeProfile)) {
|
||||
// 开发环境:使用配置文件的upload-path拼接证书路径 - 租户ID 10550
|
||||
System.out.println("=== 开发环境:使用配置文件upload-path拼接证书路径 ===");
|
||||
String uploadPath = pathConfig.getUploadPath(); // 获取配置的upload-path
|
||||
String tenantId = "10550"; // 租户ID
|
||||
String certBasePath = uploadPath + "dev/wechat/" + tenantId + "/";
|
||||
String devPrivateKeyPath = certBasePath + "apiclient_key.pem";
|
||||
String devCertPath = certBasePath + "apiclient_cert.pem";
|
||||
|
||||
System.out.println("配置的upload-path: " + uploadPath);
|
||||
System.out.println("证书基础路径: " + certBasePath);
|
||||
System.out.println("私钥文件路径: " + devPrivateKeyPath);
|
||||
System.out.println("证书文件路径: " + devCertPath);
|
||||
|
||||
config = new RSAConfig.Builder()
|
||||
.merchantId("1246610101")
|
||||
.privateKeyFromPath("/Users/gxwebsoft/cert/1246610101_20221225_cert/01ac632fea184e248d0375e9917063a4.pem")
|
||||
.privateKeyFromPath(devPrivateKeyPath)
|
||||
.merchantSerialNumber("2903B872D5CA36E525FAEC37AEDB22E54ECDE7B7")
|
||||
.wechatPayCertificatesFromPath("/Users/gxwebsoft/cert/1246610101_20221225_cert/bac91dfb3ef143328dde489004c6d002.pem")
|
||||
.wechatPayCertificatesFromPath(devCertPath)
|
||||
.build();
|
||||
System.out.println("开发环境证书路径配置完成");
|
||||
} else {
|
||||
// 生产环境:使用数据库存储的路径
|
||||
System.out.println("=== 生产环境:使用数据库存储的证书路径 ===");
|
||||
config = new RSAConfig.Builder()
|
||||
.merchantId(mchId)
|
||||
.privateKeyFromPath(privateKey)
|
||||
.merchantSerialNumber(merchantSerialNumber)
|
||||
.wechatPayCertificatesFromPath(apiclientCert)
|
||||
.build();
|
||||
System.out.println("生产环境证书路径: " + privateKey);
|
||||
}
|
||||
configMap.put(data.getTenantId().toString(),config);
|
||||
System.out.println("当前环境: " + activeProfile);
|
||||
System.out.println("config = " + config);
|
||||
}
|
||||
if (service == null) {
|
||||
|
||||
Reference in New Issue
Block a user