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

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,192 @@
# 微信支付证书问题修复总结
## 问题描述
**错误信息**`创建支付订单失败创建支付订单失败Cannot invoke "java.security.cert.X509Certificate.getSerialNumber()" because "certificate" is null`
**错误代码**1
## 问题分析
这个错误发生在微信支付SDK使用 `RSAAutoCertificateConfig` 自动证书配置时SDK尝试自动下载微信支付平台证书但失败导致证书对象为null进而在调用 `getSerialNumber()` 方法时抛出空指针异常。
## 已实施的修复方案
### 1. 增强错误处理和自动回退机制
**文件**`src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java`
**修复内容**
- 在开发环境和生产环境都增加了详细的错误诊断
- 实现了自动回退机制:当 `RSAAutoCertificateConfig` 失败时,自动回退到 `RSAConfig``RSAPublicKeyConfig`
- 增加了特定的证书错误检测和处理逻辑
- 提供了详细的错误信息和修复建议
### 2. 创建证书诊断工具
**文件**`src/main/java/com/gxwebsoft/common/core/utils/WechatPayCertificateDiagnostic.java`
**功能**
- 全面诊断微信支付证书配置
- 检查基本配置商户号、应用ID、APIv3密钥、证书序列号
- 验证证书文件存在性和有效性
- 检查证书内容和序列号匹配
- 生成详细的诊断报告和修复建议
### 3. 创建证书修复工具
**文件**`src/main/java/com/gxwebsoft/common/core/utils/WechatPayCertificateFixer.java`
**功能**
- 自动检测和修复常见的证书配置问题
- 验证证书文件路径和内容
- 检查序列号匹配性
- 提供自动修复建议
### 4. 创建诊断API接口
**文件**`src/main/java/com/gxwebsoft/common/core/controller/WechatPayDiagnosticController.java`
**提供的API**
- `GET /system/wechat-pay-diagnostic/diagnose/{tenantId}` - 诊断特定租户的证书配置
- `GET /system/wechat-pay-diagnostic/solutions` - 获取证书问题解决方案
- `POST /system/wechat-pay-diagnostic/test/{tenantId}` - 测试证书配置
- `GET /system/wechat-pay-diagnostic/environment` - 获取环境信息
- `GET /system/wechat-pay-diagnostic/guide` - 获取证书配置指南
### 5. 集成诊断功能
在支付服务中集成了证书诊断功能,每次创建支付订单时都会运行诊断,提供详细的配置信息和错误分析。
## 使用方法
### 1. 自动诊断
系统在创建支付订单时会自动运行诊断,查看控制台输出:
```
=== 微信支付证书诊断报告 ===
租户ID: 10550
商户号: 1723321338
应用ID: wx1234567890abcdef
商户证书序列号: 2B933F7C35014A1C363642623E4A62364B34C4EB
APIv3密钥: 已配置(32位)
证书文件路径: dev/wechat/10550/apiclient_key.pem
证书文件存在: 是
配置验证结果: 通过
```
### 2. 手动诊断
使用诊断API进行手动检查
```bash
# 诊断特定租户
curl -X GET "http://localhost:9200/system/wechat-pay-diagnostic/diagnose/10550" \
-H "Authorization: Bearer YOUR_TOKEN"
# 获取解决方案
curl -X GET "http://localhost:9200/system/wechat-pay-diagnostic/solutions"
# 测试证书配置
curl -X POST "http://localhost:9200/system/wechat-pay-diagnostic/test/10550" \
-H "Authorization: Bearer YOUR_TOKEN"
```
### 3. 查看配置指南
访问 `GET /system/wechat-pay-diagnostic/guide` 获取完整的证书配置指南。
## 常见问题解决
### 1. 商户平台配置
确保在微信商户平台完成以下配置:
1. 开启API安全功能
2. 申请使用微信支付公钥
3. 下载商户证书文件
4. 设置32位APIv3密钥
### 2. 证书文件配置
**开发环境**
```
src/main/resources/dev/wechat/{tenantId}/
├── apiclient_key.pem # 必需:商户私钥
└── apiclient_cert.pem # 可选:商户证书
```
**生产环境**
- 将证书文件上传到服务器指定目录
- 在数据库中配置正确的文件路径
### 3. 数据库配置
`payment` 表中确保以下字段正确配置:
- `mch_id`: 商户号
- `app_id`: 应用ID
- `merchant_serial_number`: 商户证书序列号
- `api_key`: APIv3密钥32位
## 技术特性
### 1. 自动回退机制
当自动证书配置失败时,系统会自动尝试以下回退方案:
1. `RSAAutoCertificateConfig` (首选)
2. `RSAPublicKeyConfig` (如果有公钥配置)
3. `RSAConfig` (如果有商户证书文件)
### 2. 详细错误诊断
系统会检测特定的错误类型并提供针对性的解决方案:
- X509Certificate相关错误
- 404错误API安全未开启
- 证书序列号错误
- APIv3密钥错误
- 网络连接问题
### 3. 环境适配
支持开发环境和生产环境的不同配置方式:
- 开发环境从classpath加载证书
- 生产环境从文件系统或Docker挂载卷加载证书
## 监控和维护
### 1. 日志监控
关注以下日志信息:
- 证书诊断报告
- 自动回退日志
- 错误详情和建议
### 2. 定期检查
建议定期执行以下检查:
- 证书有效期
- 配置完整性
- 网络连接状态
### 3. 更新维护
- 定期更新微信支付SDK版本
- 监控微信支付平台公告
- 及时更新过期证书
## 相关文档
- [微信支付证书问题修复指南](./WECHAT_PAY_CERTIFICATE_FIX.md)
- [微信支付官方文档](https://pay.weixin.qq.com/doc/v3/merchant/4012153196)
- [API安全配置指南](https://pay.weixin.qq.com/doc/v3/merchant/4012153196)
## 总结
通过实施以上修复方案,系统现在具备了:
1. **自动错误检测和诊断**
2. **智能回退机制**
3. **详细的错误信息和修复建议**
4. **完整的诊断和修复工具**
5. **API接口支持**
这些改进大大提高了微信支付证书问题的可诊断性和可修复性,减少了因证书配置问题导致的支付失败。

144
docs/FINAL_FIX_SUMMARY.md Normal file
View File

@@ -0,0 +1,144 @@
# 微信支付公钥路径修复总结
## 问题描述
**错误信息**`公钥文件不存在: /20250114/0f65a8517c284acb90aa83dd0c23e8f6.pem`
**根本原因**:开发环境的路径拼接逻辑不正确
## 修复方案
### 🔧 已修复的逻辑
**开发环境**
- 固定使用文件名:`wechatpay_public_key.pem`
- 路径格式:`dev/wechat/{tenantId}/wechatpay_public_key.pem`
- 实际路径:`/Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10547/wechatpay_public_key.pem`
**生产环境**
- 直接使用数据库中 `pubKey` 字段存储的完整路径
- 不进行任何路径拼接
### 📋 代码逻辑
```java
// 开发环境
if ("dev".equals(active)) {
// 固定使用 wechatpay_public_key.pem
String tenantCertPath = "dev/wechat/" + order.getTenantId();
String pubKeyPath = tenantCertPath + "/wechatpay_public_key.pem";
if (certificateLoader.certificateExists(pubKeyPath)) {
String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath);
// 使用 RSAPublicKeyConfig
}
}
// 生产环境
else {
if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) {
// 直接使用数据库中的路径
String pubKeyFile = certificateLoader.loadCertificatePath(payment.getPubKey());
// 使用 RSAPublicKeyConfig
}
}
```
### 🎯 预期日志输出
**开发环境成功**
```
=== 检测到公钥配置使用RSA公钥模式 ===
公钥文件: 20250114/0f65a8517c284acb90aa83dd0c23e8f6.pem
公钥ID: YOUR_PUBLIC_KEY_ID
开发环境公钥文件路径: dev/wechat/10547/wechatpay_public_key.pem
✅ 开发环境公钥文件加载成功: /Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10547/wechatpay_public_key.pem
✅ 开发环境RSA公钥配置成功
```
**生产环境成功**
```
=== 生产环境检测到公钥配置使用RSA公钥模式 ===
公钥文件路径: /path/to/production/public_key.pem
公钥ID: YOUR_PUBLIC_KEY_ID
✅ 生产环境公钥文件加载成功: /actual/file/path
✅ 生产环境RSA公钥配置成功
```
### 📁 文件结构要求
**开发环境**
```
src/main/resources/dev/wechat/10547/
├── apiclient_key.pem # 商户私钥
├── apiclient_cert.pem # 商户证书
└── wechatpay_public_key.pem # 微信支付平台公钥(固定文件名)
```
**生产环境**
- 文件可以放在任何位置
- 数据库中的 `pubKey` 字段存储完整的相对路径
- 例如:`/wechat/10547/public_key.pem`
### 🚀 测试步骤
1. **确认文件存在**
```bash
ls -la /Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10547/wechatpay_public_key.pem
```
2. **确认数据库配置**
```sql
SELECT tenant_id, pub_key, pub_key_id
FROM sys_payment
WHERE tenant_id = 10547 AND type = 0;
```
3. **重新测试支付订单创建**
### 🔍 故障排除
**如果仍然报错**
1. **检查文件是否存在**
```bash
ls -la /Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10547/
```
2. **检查文件权限**
```bash
chmod 644 /Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10547/wechatpay_public_key.pem
```
3. **查看详细日志**
- 关注 "开发环境公钥文件路径" 的输出
- 确认路径是否正确
4. **如果公钥ID不正确**
```sql
UPDATE sys_payment SET
pub_key_id = 'CORRECT_PUBLIC_KEY_ID'
WHERE tenant_id = 10547 AND type = 0;
```
### 📊 配置优先级
1. **RSA公钥配置**(最高优先级)
- 开发环境:固定使用 `wechatpay_public_key.pem`
- 生产环境:使用数据库路径
2. **RSA自动证书配置**
- 当没有公钥配置时使用
3. **RSA手动证书配置**
- 作为最后的回退方案
### ✅ 修复完成
现在系统应该能够:
1. 在开发环境正确找到 `wechatpay_public_key.pem` 文件
2. 在生产环境使用数据库中配置的路径
3. 成功创建RSA公钥配置
4. 避免 `X509Certificate.getSerialNumber() null` 错误
请重新测试支付订单创建功能!

216
docs/SOLUTION_SUMMARY.md Normal file
View File

@@ -0,0 +1,216 @@
# 微信支付证书问题解决方案总结
## 问题现状
**错误信息**`Cannot invoke "java.security.cert.X509Certificate.getSerialNumber()" because "certificate" is null`
**根本原因**微信支付SDK在使用自动证书配置时无法下载平台证书导致证书对象为null。
## 解决方案:使用公钥模式
### 🎯 推荐方案RSA公钥配置
我们已经实现了智能配置检测,系统会按以下优先级选择配置方式:
1. **RSA公钥配置**(最稳定,推荐)
2. **RSA自动证书配置**(需要网络连接)
3. **RSA手动证书配置**(回退方案)
### 📋 配置步骤
#### 1. 准备公钥文件
将微信支付平台公钥文件放置到:
```
src/main/resources/dev/wechat/10547/
├── apiclient_key.pem # 商户私钥(已有)
├── apiclient_cert.pem # 商户证书(已有)
└── wechatpay_public_key.pem # 微信支付平台公钥(新增)
```
#### 2. 数据库配置
执行以下SQL更新支付配置
```sql
-- 查看当前配置
SELECT id, tenant_id, mch_id, app_id, merchant_serial_number,
pub_key, pub_key_id, api_key
FROM sys_payment
WHERE tenant_id = 10547 AND type = 0;
-- 更新公钥配置
UPDATE sys_payment SET
pub_key = 'wechatpay_public_key.pem',
pub_key_id = 'YOUR_ACTUAL_PUBLIC_KEY_ID' -- 请替换为实际的公钥ID
WHERE tenant_id = 10547 AND type = 0;
```
#### 3. 验证配置
使用新增的API接口验证配置
```bash
# 快速检查配置状态
GET /system/wechat-pay-diagnostic/check/10547
# 获取详细配置建议
GET /system/wechat-pay-diagnostic/advice/10547
```
### 🔧 已实现的功能
#### 1. 智能配置检测
系统会自动检测数据库中的公钥配置:
```java
// 检测逻辑
if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() &&
payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) {
// 使用RSA公钥配置
config = new RSAPublicKeyConfig.Builder()...
} else {
// 回退到自动证书配置
config = wechatCertAutoConfig.createAutoConfig()...
}
```
#### 2. 详细日志输出
配置成功时的日志:
```
=== 检测到公钥配置使用RSA公钥模式 ===
公钥文件: wechatpay_public_key.pem
公钥ID: PUB_KEY_ID_0112422897022025011300326200001208
公钥文件路径: /path/to/wechatpay_public_key.pem
✅ 开发环境RSA公钥配置成功
```
#### 3. 配置诊断API
新增的API接口
| 接口 | 功能 | 说明 |
|------|------|------|
| `GET /system/wechat-pay-diagnostic/check/{tenantId}` | 快速配置检查 | 检查配置完整性和文件存在性 |
| `GET /system/wechat-pay-diagnostic/advice/{tenantId}` | 获取配置建议 | 生成详细的配置建议和修复步骤 |
| `GET /system/wechat-pay-diagnostic/diagnose/{tenantId}` | 全面诊断 | 完整的证书诊断报告 |
#### 4. 配置检查工具
`WechatPayConfigChecker` 提供:
- 配置完整性检查
- 文件存在性验证
- 配置模式识别
- 问题诊断和建议
### 📊 配置状态检查
使用配置检查API可以获得详细的状态报告
```json
{
"code": 200,
"message": "配置检查通过",
"data": {
"tenantId": 10547,
"environment": "dev",
"configMode": "公钥模式",
"configComplete": true,
"hasError": false,
"recommendation": "✅ 配置完整,建议使用当前配置",
"configDetails": {
"merchantId": "1723321338",
"appId": "wx1234567890abcdef",
"hasPublicKey": true,
"publicKeyExists": true,
"privateKeyExists": true
}
}
}
```
### 🚀 立即行动
#### 方案A使用公钥模式推荐
1. **获取公钥文件和ID**
- 从微信商户平台或技术支持获取
- 或使用现有的公钥文件
2. **放置文件**
```bash
# 将公钥文件复制到指定位置
cp wechatpay_public_key.pem src/main/resources/dev/wechat/10547/
```
3. **更新数据库**
```sql
UPDATE sys_payment SET
pub_key = 'wechatpay_public_key.pem',
pub_key_id = 'YOUR_PUBLIC_KEY_ID'
WHERE tenant_id = 10547 AND type = 0;
```
4. **测试验证**
- 重新尝试创建支付订单
- 查看日志确认使用公钥模式
#### 方案B修复自动证书配置
如果暂时无法获取公钥,可以:
1. **检查商户平台设置**
- 确保已开启API安全功能
- 申请使用微信支付公钥
2. **验证网络连接**
- 确保服务器可以访问微信支付API
- 检查防火墙和代理设置
3. **使用诊断工具**
```bash
GET /system/wechat-pay-diagnostic/diagnose/10547
```
### 📈 优势对比
| 配置方式 | 稳定性 | 网络依赖 | 配置难度 | 推荐指数 |
|---------|--------|----------|----------|----------|
| RSA公钥配置 | ⭐⭐⭐⭐⭐ | 无 | ⭐⭐ | 🔥🔥🔥🔥🔥 |
| RSA自动证书配置 | ⭐⭐⭐ | 高 | ⭐ | ⭐⭐⭐ |
| RSA手动证书配置 | ⭐⭐⭐ | 无 | ⭐⭐⭐⭐ | ⭐⭐ |
### 🎯 预期结果
配置完成后,您应该看到:
1. **日志输出**
```
=== 检测到公钥配置使用RSA公钥模式 ===
✅ 开发环境RSA公钥配置成功
```
2. **支付订单创建成功**
- 不再出现证书null错误
- 支付流程正常进行
3. **配置检查通过**
```
GET /system/wechat-pay-diagnostic/check/10547
返回:配置检查通过
```
### 📞 技术支持
如果仍有问题,请:
1. 使用诊断API获取详细信息
2. 查看完整的错误日志
3. 提供配置检查结果
4. 联系技术支持团队
---
**总结**:通过使用公钥模式,可以彻底解决 `X509Certificate.getSerialNumber() null` 错误,提供更稳定可靠的微信支付服务。

View File

@@ -0,0 +1,165 @@
# 微信支付证书问题修复指南
## 问题描述
错误信息:`创建支付订单失败创建支付订单失败Cannot invoke "java.security.cert.X509Certificate.getSerialNumber()" because "certificate" is null`
## 问题原因
这个错误通常发生在使用微信支付SDK的 `RSAAutoCertificateConfig`SDK尝试自动下载微信支付平台证书但失败导致证书对象为null。
常见原因包括:
1. 商户平台未开启API安全功能
2. 未申请使用微信支付公钥
3. 网络连接问题
4. 商户证书序列号错误
5. APIv3密钥配置错误
## 解决方案
### 1. 商户平台配置
#### 步骤1开启API安全功能
1. 登录 [微信商户平台](https://pay.weixin.qq.com)
2. 进入【账户中心】->【API安全】
3. 点击【申请使用微信支付公钥】
4. 按照指引完成申请流程
#### 步骤2下载证书文件
1. 在API安全页面下载商户证书
2. 获取以下文件:
- `apiclient_cert.pem` (商户证书)
- `apiclient_key.pem` (商户私钥)
3. 记录商户证书序列号
#### 步骤3设置APIv3密钥
1. 在API安全页面设置APIv3密钥
2. 密钥必须是32位字符串字母和数字组合
3. 妥善保管密钥,不要泄露
### 2. 开发环境配置
#### 证书文件放置
将证书文件放置到以下目录:
```
src/main/resources/dev/wechat/{tenantId}/
├── apiclient_key.pem # 必需:商户私钥
└── apiclient_cert.pem # 可选:商户证书(自动配置不需要)
```
例如租户ID为10550的证书路径
```
src/main/resources/dev/wechat/10550/
├── apiclient_key.pem
└── apiclient_cert.pem
```
#### 数据库配置
`payment` 表中配置以下信息:
- `mch_id`: 商户号
- `app_id`: 应用ID
- `merchant_serial_number`: 商户证书序列号
- `api_key`: APIv3密钥32位
### 3. 生产环境配置
#### 证书文件上传
将证书文件上传到服务器指定目录,通常是:
```
/www/wwwroot/file.ws/file/{相对路径}/
```
#### 数据库配置
`payment` 表中配置证书文件的相对路径:
- `apiclient_key`: 私钥文件相对路径
- `apiclient_cert`: 商户证书文件相对路径
### 4. 代码修复
系统已经实现了自动回退机制:
1. **优先使用自动证书配置**`RSAAutoCertificateConfig`
2. **自动回退到手动配置**:如果自动配置失败,会回退到 `RSAConfig``RSAPublicKeyConfig`
3. **详细错误诊断**:提供具体的错误信息和修复建议
### 5. 诊断工具
#### 使用证书诊断API
```bash
# 诊断特定租户的证书配置
GET /system/wechat-pay-diagnostic/diagnose/{tenantId}
# 获取解决方案
GET /system/wechat-pay-diagnostic/solutions
# 测试证书配置
POST /system/wechat-pay-diagnostic/test/{tenantId}
```
#### 查看诊断日志
在应用日志中查看详细的诊断信息:
```
=== 微信支付证书诊断报告 ===
租户ID: 10550
商户号: 1723321338
应用ID: wx1234567890abcdef
商户证书序列号: 2B933F7C35014A1C363642623E4A62364B34C4EB
APIv3密钥: 已配置(32位)
证书文件路径: dev/wechat/10550/apiclient_key.pem
证书文件存在: 是
配置验证结果: 通过
```
## 常见问题排查
### Q1: 404错误
**原因**商户平台未开启API安全功能
**解决**按照上述步骤1开启API安全功能
### Q2: 证书序列号不匹配
**原因**:数据库中配置的序列号与实际证书不符
**解决**
1. 在商户平台查看正确的序列号
2. 更新数据库中的 `merchant_serial_number` 字段
### Q3: APIv3密钥错误
**原因**密钥长度不是32位或包含非法字符
**解决**
1. 重新设置32位APIv3密钥
2. 确保只包含字母和数字
### Q4: 私钥文件不存在
**原因**:证书文件路径错误或文件未上传
**解决**
1. 检查文件路径是否正确
2. 确保文件已正确放置
### Q5: 网络连接问题
**原因**服务器无法访问微信支付API
**解决**
1. 检查网络连接
2. 确保防火墙允许HTTPS出站连接
3. 检查代理设置
## 最佳实践
1. **使用自动证书配置**:推荐使用 `RSAAutoCertificateConfig`,可自动管理平台证书
2. **定期检查证书有效期**:避免证书过期导致的问题
3. **妥善保管私钥**:确保私钥文件安全,不要泄露
4. **使用HTTPS**所有支付相关通信都应使用HTTPS
5. **监控日志**:定期查看支付相关日志,及时发现问题
## 技术支持
如果按照以上步骤仍无法解决问题,请:
1. 查看完整的错误日志
2. 使用诊断API获取详细信息
3. 检查微信商户平台的配置状态
4. 联系技术支持团队
## 相关文档
- [微信支付官方文档](https://pay.weixin.qq.com/doc/v3/merchant/4012153196)
- [API安全配置指南](https://pay.weixin.qq.com/doc/v3/merchant/4012153196)
- [证书和回调报文验证](https://pay.weixin.qq.com/doc/v3/wechatpay/wechatpay4_1.shtml)

View File

@@ -0,0 +1,198 @@
# 微信支付公钥模式配置指南
## 概述
如果您的后台系统使用了微信支付公钥模式,系统现在支持自动检测并优先使用公钥配置。这种模式比自动证书配置更稳定,不依赖网络下载平台证书。
## 配置步骤
### 1. 获取公钥文件
从微信商户平台下载或获取以下文件:
- 微信支付平台公钥文件(通常以 `.pem` 结尾)
- 公钥ID一个字符串标识符
### 2. 放置公钥文件
将公钥文件放置到对应租户的证书目录:
```
src/main/resources/dev/wechat/{tenantId}/
├── apiclient_key.pem # 商户私钥(必需)
├── apiclient_cert.pem # 商户证书(可选)
└── wechatpay_public_key.pem # 微信支付平台公钥(新增)
```
例如租户ID为10547的目录结构
```
src/main/resources/dev/wechat/10547/
├── apiclient_key.pem
├── apiclient_cert.pem
└── wechatpay_public_key.pem
```
### 3. 数据库配置
`sys_payment` 表中配置公钥相关字段:
```sql
UPDATE sys_payment SET
pub_key = 'wechatpay_public_key.pem',
pub_key_id = 'YOUR_PUBLIC_KEY_ID'
WHERE tenant_id = 10547 AND type = 0;
```
**字段说明**
- `pub_key`: 公钥文件名
- `pub_key_id`: 微信支付平台提供的公钥ID
### 4. 验证配置
运行测试来验证配置是否正确:
```bash
# 运行公钥配置测试
mvn test -Dtest=WechatPayPublicKeyTest#testPublicKeyConfiguration
```
## 配置优先级
系统会按以下优先级选择配置方式:
1. **RSA公钥配置**(最高优先级)
- 条件:数据库中配置了 `pub_key``pub_key_id`
- 优势:稳定、不依赖网络、配置简单
2. **RSA自动证书配置**
- 条件:公钥配置不可用时
- 优势:自动管理平台证书
- 劣势依赖网络连接和商户平台API安全设置
3. **RSA手动证书配置**(回退方案)
- 条件:自动配置失败时
- 需要:商户证书文件
## 示例配置
### 开发环境示例
**目录结构**
```
src/main/resources/dev/wechat/10547/
├── apiclient_key.pem
├── apiclient_cert.pem
└── wechatpay_public_key.pem
```
**数据库配置**
```sql
-- 查看当前配置
SELECT id, tenant_id, mch_id, app_id, merchant_serial_number,
pub_key, pub_key_id, api_key
FROM sys_payment
WHERE tenant_id = 10547 AND type = 0;
-- 更新公钥配置
UPDATE sys_payment SET
pub_key = 'wechatpay_public_key.pem',
pub_key_id = 'PUB_KEY_ID_0112422897022025011300326200001208'
WHERE tenant_id = 10547 AND type = 0;
```
### 生产环境示例
**证书文件路径**
```
/www/wwwroot/file.ws/file/wechat/10547/
├── apiclient_key.pem
├── apiclient_cert.pem
└── wechatpay_public_key.pem
```
**数据库配置**
```sql
UPDATE sys_payment SET
apiclient_key = '/wechat/10547/apiclient_key.pem',
apiclient_cert = '/wechat/10547/apiclient_cert.pem',
pub_key = '/wechat/10547/wechatpay_public_key.pem',
pub_key_id = 'PUB_KEY_ID_0112422897022025011300326200001208'
WHERE tenant_id = 10547 AND type = 0;
```
## 日志输出
配置成功后,您会在日志中看到:
```
=== 检测到公钥配置使用RSA公钥模式 ===
公钥文件: wechatpay_public_key.pem
公钥ID: PUB_KEY_ID_0112422897022025011300326200001208
公钥文件路径: /path/to/wechatpay_public_key.pem
✅ 开发环境RSA公钥配置成功
```
如果没有公钥配置,系统会尝试自动证书配置:
```
=== 尝试创建自动证书配置 ===
商户号: 1723321338
私钥路径: /path/to/apiclient_key.pem
序列号: 2B933F7C35014A1C363642623E4A62364B34C4EB
API密钥长度: 32
```
## 故障排除
### 1. 公钥文件不存在
**错误信息**
```
❌ 公钥文件不存在: dev/wechat/10547/wechatpay_public_key.pem
```
**解决方案**
- 检查文件路径是否正确
- 确认文件已放置在正确位置
- 验证文件名与数据库配置一致
### 2. 公钥ID错误
**错误信息**
```
❌ RSA公钥配置失败: Invalid public key ID
```
**解决方案**
- 检查公钥ID是否正确
- 确认公钥ID与公钥文件匹配
- 联系微信支付技术支持获取正确的公钥ID
### 3. 数据库配置缺失
**现象**:系统跳过公钥配置,直接尝试自动证书配置
**解决方案**
```sql
-- 检查当前配置
SELECT pub_key, pub_key_id FROM sys_payment WHERE tenant_id = 10547 AND type = 0;
-- 如果字段为空,进行配置
UPDATE sys_payment SET
pub_key = 'wechatpay_public_key.pem',
pub_key_id = 'YOUR_PUBLIC_KEY_ID'
WHERE tenant_id = 10547 AND type = 0;
```
## 优势对比
| 配置方式 | 稳定性 | 网络依赖 | 配置复杂度 | 推荐度 |
|---------|--------|----------|------------|--------|
| RSA公钥配置 | 高 | 无 | 低 | ⭐⭐⭐⭐⭐ |
| RSA自动证书配置 | 中 | 高 | 低 | ⭐⭐⭐ |
| RSA手动证书配置 | 中 | 无 | 高 | ⭐⭐ |
## 总结
使用公钥模式可以有效避免 `X509Certificate.getSerialNumber() null` 错误,因为它不依赖自动下载平台证书。建议优先使用此配置方式。
如果您已经有公钥文件和公钥ID按照本指南配置后系统会自动使用更稳定的公钥模式。

View File

@@ -0,0 +1,31 @@
-- 修复租户10547的公钥路径配置
-- 1. 查看当前配置
SELECT
id,
tenant_id,
mch_id,
pub_key,
pub_key_id
FROM sys_payment
WHERE tenant_id = 10547 AND type = 0;
-- 2. 修复公钥路径配置
UPDATE sys_payment SET
pub_key = 'wechatpay_public_key.pem'
WHERE tenant_id = 10547 AND type = 0;
-- 3. 验证修复结果
SELECT
id,
tenant_id,
mch_id,
pub_key,
pub_key_id,
CASE
WHEN pub_key = 'wechatpay_public_key.pem'
THEN '✅ 路径已修复'
ELSE '❌ 路径仍有问题'
END AS path_status
FROM sys_payment
WHERE tenant_id = 10547 AND type = 0;

View File

@@ -0,0 +1,63 @@
-- 微信支付公钥配置SQL脚本
-- 适用于租户ID: 10547
-- 1. 查看当前支付配置
SELECT
id,
tenant_id,
mch_id,
app_id,
merchant_serial_number,
pub_key,
pub_key_id,
api_key,
apiclient_key,
apiclient_cert
FROM sys_payment
WHERE tenant_id = 10547 AND type = 0;
-- 2. 更新公钥配置请根据实际情况修改公钥ID
UPDATE sys_payment SET
pub_key = 'wechatpay_public_key.pem',
pub_key_id = 'PUB_KEY_ID_0112422897022025011300326200001208' -- 请替换为实际的公钥ID
WHERE tenant_id = 10547 AND type = 0;
-- 3. 验证更新结果
SELECT
id,
tenant_id,
mch_id,
app_id,
merchant_serial_number,
pub_key,
pub_key_id,
CASE
WHEN pub_key IS NOT NULL AND pub_key != '' AND pub_key_id IS NOT NULL AND pub_key_id != ''
THEN '✅ 公钥配置完整'
ELSE '❌ 公钥配置不完整'
END AS config_status
FROM sys_payment
WHERE tenant_id = 10547 AND type = 0;
-- 4. 如果需要清除公钥配置(回退到自动证书模式)
-- UPDATE sys_payment SET
-- pub_key = NULL,
-- pub_key_id = NULL
-- WHERE tenant_id = 10547 AND type = 0;
-- 5. 检查所有租户的公钥配置状态
SELECT
tenant_id,
mch_id,
CASE
WHEN pub_key IS NOT NULL AND pub_key != '' AND pub_key_id IS NOT NULL AND pub_key_id != ''
THEN '公钥模式'
WHEN merchant_serial_number IS NOT NULL AND merchant_serial_number != ''
THEN '自动证书模式'
ELSE '配置不完整'
END AS payment_mode,
pub_key,
pub_key_id
FROM sys_payment
WHERE type = 0
ORDER BY tenant_id;