修复微信支付,兼容公钥模块

This commit is contained in:
2025-07-29 12:32:56 +08:00
parent ade737c3bd
commit 764974b3d1
19 changed files with 2737 additions and 99 deletions

View File

@@ -0,0 +1,158 @@
package com.gxwebsoft.test;
import com.gxwebsoft.common.core.config.CertificateProperties;
import com.gxwebsoft.common.core.service.PaymentCacheService;
import com.gxwebsoft.common.core.utils.CertificateLoader;
import com.gxwebsoft.common.system.entity.Payment;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* 微信支付路径处理测试
*
* @author 科技小王子
* @since 2025-07-29
*/
@SpringBootTest
public class WechatPayPathTest {
@Autowired
private PaymentCacheService paymentCacheService;
@Autowired
private CertificateLoader certificateLoader;
@Autowired
private CertificateProperties certConfig;
@Test
public void testPublicKeyPathHandling() {
try {
System.out.println("=== 微信支付公钥路径处理测试 ===");
// 测试租户ID
Integer tenantId = 10547;
// 获取支付配置
Payment payment = paymentCacheService.getWechatPayConfig(tenantId);
if (payment == null) {
System.err.println("❌ 支付配置不存在");
return;
}
System.out.println("数据库配置信息:");
System.out.println("租户ID: " + tenantId);
System.out.println("商户号: " + payment.getMchId());
System.out.println("公钥文件配置: " + payment.getPubKey());
System.out.println("公钥ID: " + payment.getPubKeyId());
// 测试路径处理逻辑
if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) {
System.out.println("\n=== 路径处理测试 ===");
String pubKeyPath;
if (payment.getPubKey().startsWith("dev/wechat/") || payment.getPubKey().startsWith("/")) {
// 如果数据库中存储的是完整路径,直接使用
pubKeyPath = payment.getPubKey();
System.out.println("✅ 检测到完整路径,直接使用: " + pubKeyPath);
} else {
// 如果是相对路径,需要拼接租户目录
String tenantCertPath = "dev/wechat/" + tenantId;
pubKeyPath = tenantCertPath + "/" + payment.getPubKey();
System.out.println("✅ 检测到相对路径,拼接后: " + pubKeyPath);
}
// 测试文件是否存在
System.out.println("\n=== 文件存在性检查 ===");
if (certificateLoader.certificateExists(pubKeyPath)) {
try {
String actualPath = certificateLoader.loadCertificatePath(pubKeyPath);
System.out.println("✅ 公钥文件存在: " + actualPath);
// 检查文件大小
java.io.File file = new java.io.File(actualPath);
if (file.exists()) {
System.out.println("文件大小: " + file.length() + " 字节");
System.out.println("文件可读: " + file.canRead());
}
} catch (Exception e) {
System.err.println("❌ 加载公钥文件失败: " + e.getMessage());
}
} else {
System.err.println("❌ 公钥文件不存在: " + pubKeyPath);
// 提供修复建议
System.out.println("\n=== 修复建议 ===");
if (payment.getPubKey().contains("/")) {
System.out.println("1. 检查数据库中的路径是否正确");
System.out.println("2. 确认文件是否已上传到指定位置");
System.out.println("3. 当前配置的路径: " + payment.getPubKey());
} else {
System.out.println("1. 将公钥文件放置到: src/main/resources/dev/wechat/" + tenantId + "/");
System.out.println("2. 或者更新数据库配置为完整路径");
}
}
// 测试其他证书文件
System.out.println("\n=== 其他证书文件检查 ===");
String tenantCertPath = "dev/wechat/" + tenantId;
String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
String merchantCertPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getApiclientCertFile();
System.out.println("私钥文件: " + privateKeyPath + " - " +
(certificateLoader.certificateExists(privateKeyPath) ? "✅ 存在" : "❌ 不存在"));
System.out.println("商户证书: " + merchantCertPath + " - " +
(certificateLoader.certificateExists(merchantCertPath) ? "✅ 存在" : "❌ 不存在"));
} else {
System.out.println("⚠️ 未配置公钥信息");
}
System.out.println("\n=== 测试完成 ===");
} catch (Exception e) {
System.err.println("❌ 测试失败: " + e.getMessage());
e.printStackTrace();
}
}
@Test
public void testCreateCorrectDirectoryStructure() {
System.out.println("=== 创建正确的目录结构建议 ===");
try {
Integer tenantId = 10547;
Payment payment = paymentCacheService.getWechatPayConfig(tenantId);
if (payment != null && payment.getPubKey() != null) {
System.out.println("当前数据库配置的公钥路径: " + payment.getPubKey());
if (payment.getPubKey().contains("/")) {
// 包含路径分隔符,说明是完整路径
System.out.println("\n建议的文件放置位置:");
System.out.println("src/main/resources/" + payment.getPubKey());
// 创建目录的命令
String dirPath = payment.getPubKey().substring(0, payment.getPubKey().lastIndexOf("/"));
System.out.println("\n创建目录的命令:");
System.out.println("mkdir -p src/main/resources/" + dirPath);
// 复制文件的命令
System.out.println("\n如果您有公钥文件可以这样复制:");
System.out.println("cp your_public_key.pem src/main/resources/" + payment.getPubKey());
} else {
// 只是文件名,需要放在租户目录下
System.out.println("\n建议的文件放置位置:");
System.out.println("src/main/resources/dev/wechat/" + tenantId + "/" + payment.getPubKey());
System.out.println("\n或者更新数据库配置为:");
System.out.println("UPDATE sys_payment SET pub_key = 'dev/wechat/" + tenantId + "/" + payment.getPubKey() + "' WHERE tenant_id = " + tenantId + " AND type = 0;");
}
}
} catch (Exception e) {
System.err.println("获取配置失败: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,150 @@
package com.gxwebsoft.test;
import com.gxwebsoft.common.core.config.CertificateProperties;
import com.gxwebsoft.common.core.service.PaymentCacheService;
import com.gxwebsoft.common.core.utils.CertificateLoader;
import com.gxwebsoft.common.core.utils.WechatCertAutoConfig;
import com.gxwebsoft.common.system.entity.Payment;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* 微信支付公钥配置测试
*
* @author 科技小王子
* @since 2025-07-29
*/
@SpringBootTest
public class WechatPayPublicKeyTest {
@Autowired
private PaymentCacheService paymentCacheService;
@Autowired
private CertificateLoader certificateLoader;
@Autowired
private CertificateProperties certConfig;
@Autowired
private WechatCertAutoConfig wechatCertAutoConfig;
@Test
public void testPublicKeyConfiguration() {
try {
System.out.println("=== 微信支付公钥配置测试 ===");
// 测试租户ID
Integer tenantId = 10547;
// 获取支付配置
Payment payment = paymentCacheService.getWechatPayConfig(tenantId);
System.out.println("支付配置获取成功:");
System.out.println("商户号: " + payment.getMchId());
System.out.println("应用ID: " + payment.getAppId());
System.out.println("序列号: " + payment.getMerchantSerialNumber());
System.out.println("API密钥: " + (payment.getApiKey() != null ? "已配置(长度:" + payment.getApiKey().length() + ")" : "未配置"));
System.out.println("公钥文件: " + payment.getPubKey());
System.out.println("公钥ID: " + payment.getPubKeyId());
// 测试证书文件加载
String tenantCertPath = "dev/wechat/" + tenantId;
String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
System.out.println("\n=== 证书文件检查 ===");
System.out.println("私钥路径: " + privateKeyPath);
if (certificateLoader.certificateExists(privateKeyPath)) {
String privateKey = certificateLoader.loadCertificatePath(privateKeyPath);
System.out.println("✅ 私钥文件加载成功: " + privateKey);
// 检查是否配置了公钥
if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() &&
payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) {
System.out.println("\n=== 公钥配置测试 ===");
String pubKeyPath = tenantCertPath + "/" + payment.getPubKey();
System.out.println("公钥路径: " + pubKeyPath);
if (certificateLoader.certificateExists(pubKeyPath)) {
String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath);
System.out.println("✅ 公钥文件加载成功: " + pubKeyFile);
// 测试RSA公钥配置
try {
Config config = new RSAPublicKeyConfig.Builder()
.merchantId(payment.getMchId())
.privateKeyFromPath(privateKey)
.publicKeyFromPath(pubKeyFile)
.publicKeyId(payment.getPubKeyId())
.merchantSerialNumber(payment.getMerchantSerialNumber())
.apiV3Key(payment.getApiKey())
.build();
System.out.println("✅ RSA公钥配置创建成功");
System.out.println("配置类型: " + config.getClass().getSimpleName());
} catch (Exception e) {
System.err.println("❌ RSA公钥配置失败: " + e.getMessage());
e.printStackTrace();
}
} else {
System.err.println("❌ 公钥文件不存在: " + pubKeyPath);
System.out.println("💡 建议: 请将公钥文件放置到指定位置");
}
} else {
System.out.println("\n⚠ 未配置公钥信息");
System.out.println("💡 建议: 在数据库中配置 pubKey 和 pubKeyId 字段");
// 测试自动证书配置
System.out.println("\n=== 自动证书配置测试 ===");
try {
Config autoConfig = wechatCertAutoConfig.createAutoConfig(
payment.getMchId(),
privateKey,
payment.getMerchantSerialNumber(),
payment.getApiKey()
);
System.out.println("✅ 自动证书配置创建成功");
System.out.println("配置类型: " + autoConfig.getClass().getSimpleName());
} catch (Exception e) {
System.err.println("❌ 自动证书配置失败: " + e.getMessage());
System.err.println("错误类型: " + e.getClass().getName());
if (e.getMessage() != null && e.getMessage().contains("certificate")) {
System.err.println("🔍 这是证书相关错误,建议使用公钥模式");
}
}
}
} else {
System.err.println("❌ 私钥文件不存在: " + privateKeyPath);
}
System.out.println("\n=== 测试完成 ===");
} catch (Exception e) {
System.err.println("❌ 测试失败: " + e.getMessage());
e.printStackTrace();
}
}
@Test
public void testCreateSamplePublicKeyConfig() {
System.out.println("=== 创建示例公钥配置 ===");
System.out.println("如果您的后台使用公钥模式,请在数据库中配置以下字段:");
System.out.println("1. pubKey: 公钥文件名,例如 'wechatpay_public_key.pem'");
System.out.println("2. pubKeyId: 公钥ID例如 'PUB_KEY_ID_0112422897022025011300326200001208'");
System.out.println("3. 将公钥文件放置到: src/main/resources/dev/wechat/{tenantId}/");
System.out.println("\n示例SQL更新语句:");
System.out.println("UPDATE sys_payment SET ");
System.out.println(" pub_key = 'wechatpay_public_key.pem',");
System.out.println(" pub_key_id = 'PUB_KEY_ID_0112422897022025011300326200001208'");
System.out.println("WHERE tenant_id = 10547 AND type = 0;");
}
}