# 微信支付公钥模式配置指南

## 概述

如果您的后台系统使用了微信支付公钥模式，系统现在支持自动检测并优先使用公钥配置。这种模式比自动证书配置更稳定，不依赖网络下载平台证书。

## 配置步骤

### 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，按照本指南配置后，系统会自动使用更稳定的公钥模式。
