Browse Source

refactor(shop): 重构微信支付证书加载逻辑

- 提前声明所有需要的变量,避免重复定义
- 将开发环境和生产环境的证书加载逻辑分离,提高可读性
- 优化证书路径构建逻辑,处理数据库路径可能以/开头的情况
- 添加公钥加载逻辑,支持开发环境和生产环境的公钥配置- 移除冗余的代码和不必要的注释,简化代码结构
pan
科技小王子 1 month ago
parent
commit
d79bc09137
  1. 172
      src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java

172
src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java

@ -556,9 +556,17 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
public JsapiServiceExtension getWxService(ShopOrder order) {
try {
final Payment payment = getPayment(order);
// 提前声明所有需要的变量,避免重复定义
String privateKey;
String apiclientCert = null;
String pubKey = null;
String tenantCertPath = null;
String privateKeyPath = null;
String pubKeyPath = null;
String apiclientCertPath = null;
String apiclientCertFile = null;
String pubKeyFile = null;
// 运行配置诊断
System.out.println("=== 运行微信支付配置诊断 ===");
@ -570,74 +578,19 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
certificateDiagnostic.diagnoseCertificateConfig(payment, order.getTenantId(), active);
System.out.println(diagnosticResult.getFullReport());
// 开发环境配置 - 使用自动证书配置
if (active.equals("dev")) {
// 构建包含租户号的证书路径: dev/wechat/{tenantId}/
String tenantCertPath = "dev/wechat/" + order.getTenantId();
String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
System.out.println("开发环境证书路径 - 租户ID: " + order.getTenantId());
System.out.println("开发环境证书路径 - 私钥: " + privateKeyPath);
System.out.println("=== 支付配置详细信息 ===");
System.out.println("商户号: " + payment.getMchId());
System.out.println("序列号: " + payment.getMerchantSerialNumber());
System.out.println("API密钥: " + (payment.getApiKey() != null ? "已配置(长度:" + payment.getApiKey().length() + ")" : "未配置"));
System.out.println("应用ID: " + payment.getAppId());
System.out.println("支付类型: " + payment.getType());
System.out.println("支付代码: " + payment.getCode());
privateKey = certificateLoader.loadCertificatePath(privateKeyPath);
System.out.println("私钥完整路径: " + privateKey);
System.out.println("证书加载完成 - 私钥文件: " + privateKey);
System.out.println("使用自动证书配置,无需手动加载微信支付平台证书");
// 更新诊断信息,包含私钥路径
wechatPayDiagnostic.diagnosePaymentConfig(payment, privateKey, active);
} else {
// 生产环境配置 - 从容器证书目录加载
final String certRootPath = certConfig.getCertRootPath(); // /www/wwwroot/file.ws
final String certBasePath = certRootPath + "/file"; // 实际文件存储路径
System.out.println("生产环境证书路径 - 租户ID: " + order.getTenantId());
System.out.println("生产环境证书根路径: " + certRootPath);
System.out.println("生产环境证书基础路径: " + certBasePath);
System.out.println("私钥文件名: " + payment.getApiclientKey());
System.out.println("证书文件名: " + payment.getApiclientCert());
// 构建完整的证书文件路径
// 处理数据库路径可能以/开头的情况,避免双斜杠
String privateKeyRelativePath = payment.getApiclientKey();
String apiclientCertRelativePath = payment.getApiclientCert();
// 如果数据库路径以/开头,直接拼接;否则添加/
String privateKeyFullPath = privateKeyRelativePath.startsWith("/")
? certBasePath + privateKeyRelativePath
: certBasePath + "/" + privateKeyRelativePath;
String apiclientCertFullPath = apiclientCertRelativePath.startsWith("/")
? certBasePath + apiclientCertRelativePath
: certBasePath + "/" + apiclientCertRelativePath;
System.out.println("私钥完整路径: " + privateKeyFullPath);
System.out.println("证书完整路径: " + apiclientCertFullPath);
privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath);
apiclientCert = certificateLoader.loadCertificatePath(apiclientCertFullPath);
if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) {
String pubKeyRelativePath = payment.getPubKey();
String pubKeyFullPath = pubKeyRelativePath.startsWith("/")
? certBasePath + pubKeyRelativePath
: certBasePath + "/" + pubKeyRelativePath;
System.out.println("公钥完整路径: " + pubKeyFullPath);
pubKey = certificateLoader.loadCertificatePath(pubKeyFullPath);
}
}
// 构建微信支付配置
Config config = null;
if (active.equals("dev")) {
// 开发环境使用自动证书配置
// 首先初始化私钥路径
tenantCertPath = "dev/wechat/" + order.getTenantId();
privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
privateKey = certificateLoader.loadCertificatePath(privateKeyPath);
System.out.println("开发环境私钥路径: " + privateKeyPath);
System.out.println("开发环境私钥加载成功: " + privateKey);
// 检查数据库配置是否完整
if (payment.getMchId() == null || payment.getMchId().trim().isEmpty()) {
throw new RuntimeException("数据库中商户号(mchId)未配置");
@ -664,8 +617,7 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
try {
// 开发环境固定使用 wechatpay_public_key.pem
String tenantCertPath = "dev/wechat/" + order.getTenantId();
String pubKeyPath = tenantCertPath + "/wechatpay_public_key.pem";
pubKeyPath = tenantCertPath + "/wechatpay_public_key.pem";
System.out.println("开发环境公钥文件路径: " + pubKeyPath);
@ -675,7 +627,7 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
System.out.println("公钥文件: " + payment.getPubKey());
System.out.println("公钥ID: " + payment.getPubKeyId());
String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath);
pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath);
System.out.println("✅ 开发环境公钥文件加载成功: " + pubKeyFile);
config = new RSAPublicKeyConfig.Builder()
@ -738,11 +690,10 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
System.err.println("⚠️ 开发环境回退到基础RSA配置...");
try {
// 方案1:尝试使用RSA证书配置(需要商户证书文件)
String tenantCertPath = "dev/wechat/" + order.getTenantId();
String apiclientCertPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getApiclientCertFile();
apiclientCertPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getApiclientCertFile();
if (certificateLoader.certificateExists(apiclientCertPath)) {
String apiclientCertFile = certificateLoader.loadCertificatePath(apiclientCertPath);
apiclientCertFile = certificateLoader.loadCertificatePath(apiclientCertPath);
System.out.println("方案1: 使用RSA证书配置作为回退方案");
System.out.println("商户证书路径: " + apiclientCertFile);
@ -798,6 +749,16 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
}
}
} else {
// 生产环境 - 首先初始化私钥
final String certRootPath = certConfig.getCertRootPath();
final String certBasePath = certRootPath + "/file";
String privateKeyRelativePath = payment.getApiclientKey();
String privateKeyFullPath = privateKeyRelativePath.startsWith("/")
? certBasePath + privateKeyRelativePath
: certBasePath + "/" + privateKeyRelativePath;
privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath);
System.out.println("✅ 生产环境私钥加载完成: " + privateKey);
// 生产环境也优先检查公钥配置
if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() &&
payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) {
@ -808,7 +769,7 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
try {
// 生产环境处理公钥路径
String pubKeyPath = payment.getPubKey();
pubKeyPath = payment.getPubKey();
// 如果路径不是以 /file 开头,需要添加 /file 前缀
if (!pubKeyPath.startsWith("/file/") && !pubKeyPath.startsWith("file/")) {
@ -818,7 +779,7 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
System.out.println("生产环境公钥路径: " + pubKeyPath);
}
String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath);
pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath);
System.out.println("✅ 生产环境公钥文件加载成功: " + pubKeyFile);
config = new RSAPublicKeyConfig.Builder()
@ -945,40 +906,59 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
String apiclientCert = null;
String pubKey = null;
// 运行配置诊断
System.out.println("=== 微信支付配置诊断 ===");
System.out.println("租户ID: " + order.getTenantId());
System.out.println("商户号: " + payment.getMchId());
System.out.println("应用ID: " + payment.getAppId());
System.out.println("序列号: " + payment.getMerchantSerialNumber());
System.out.println("API密钥: " + (payment.getApiKey() != null ? "已配置" : "未配置"));
// 证书路径构建
String tenantCertPath = active + "/wechat/" + order.getTenantId();
// 初始化证书路径
if (active.equals("dev")) {
// 开发环境 - 构建包含租户号的证书路径
String tenantCertPath = "dev/wechat/" + order.getTenantId();
String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
String certPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getApiclientCertFile();
String pubKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getWechatpayCertFile();
System.out.println("=== 证书路径信息 ===");
System.out.println("私钥路径: " + privateKeyPath);
System.out.println("证书路径: " + certPath);
System.out.println("公钥路径: " + pubKeyPath);
System.out.println("开发环境证书路径 - 租户ID: " + order.getTenantId());
System.out.println("开发环境证书路径 - 私钥: " + privateKeyPath);
// 获取私钥文件路径
String actualPrivateKeyPath = certificateLoader.loadCertificatePath(privateKeyPath);
privateKey = actualPrivateKeyPath;
if (privateKey == null || privateKey.trim().isEmpty()) {
throw new RuntimeException("私钥文件路径为空,路径: " + privateKeyPath);
privateKey = certificateLoader.loadCertificatePath(privateKeyPath);
System.out.println("私钥完整路径: " + privateKey);
// 尝试加载公钥(如果配置了)
if (StrUtil.isNotBlank(payment.getPubKey()) && StrUtil.isNotBlank(payment.getPubKeyId())) {
try {
String pubKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getWechatpayCertFile();
pubKey = certificateLoader.loadCertificatePath(pubKeyPath);
System.out.println("✅ 开发环境公钥加载成功");
} catch (Exception e) {
System.out.println("⚠️ 开发环境公钥加载失败,将使用自动证书配置: " + e.getMessage());
}
}
} else {
// 生产环境 - 从数据库配置的路径加载
final String certRootPath = certConfig.getCertRootPath();
final String certBasePath = certRootPath + "/file";
System.out.println("生产环境证书路径 - 租户ID: " + order.getTenantId());
System.out.println("生产环境证书根路径: " + certRootPath);
System.out.println("生产环境证书基础路径: " + certBasePath);
System.out.println("私钥文件名: " + payment.getApiclientKey());
String privateKeyRelativePath = payment.getApiclientKey();
String privateKeyFullPath = privateKeyRelativePath.startsWith("/")
? certBasePath + privateKeyRelativePath
: certBasePath + "/" + privateKeyRelativePath;
System.out.println("私钥完整路径: " + privateKeyFullPath);
privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath);
System.out.println("✅ 生产环境私钥加载完成: " + privateKey);
// 尝试获取公钥文件路径(如果配置了公钥)
// 尝试加载公钥(如果配置了
if (StrUtil.isNotBlank(payment.getPubKey()) && StrUtil.isNotBlank(payment.getPubKeyId())) {
try {
String actualPubKeyPath = certificateLoader.loadCertificatePath(pubKeyPath);
pubKey = actualPubKeyPath;
System.out.println("✅ 公钥文件路径获取成功,将使用RSA公钥配置");
String pubKeyRelativePath = payment.getPubKey();
String pubKeyFullPath = pubKeyRelativePath.startsWith("/")
? certBasePath + pubKeyRelativePath
: certBasePath + "/" + pubKeyRelativePath;
pubKey = certificateLoader.loadCertificatePath(pubKeyFullPath);
System.out.println("✅ 生产环境公钥加载成功");
} catch (Exception e) {
System.out.println("⚠️ 公钥文件路径获取失败,将使用自动证书配置: " + e.getMessage());
System.out.println("⚠️ 生产环境公钥加载失败,将使用自动证书配置: " + e.getMessage());
}
}
}

Loading…
Cancel
Save