11
This commit is contained in:
165
docs/WECHAT_PAY_CERTIFICATE_FIX.md
Normal file
165
docs/WECHAT_PAY_CERTIFICATE_FIX.md
Normal 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)
|
||||
Reference in New Issue
Block a user