fengketrade/doc/489错误诊断报告.md
2025-10-22 15:14:24 +08:00

299 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 建行支付错误诊断报告
## 📋 问题历史
### 问题1489错误已解决✅
**错误信息**
```
HTTP状态码489
响应内容:{"data":{},"reqFlowNo":"...","errCode":"exception01","errMsg":"系统异常"}
```
**根本原因**缺少双重BASE64编码
**解决方案**:按照 `doc/调用通讯接口可参考词demo1.java` 的实现增加双重BASE64编码
---
### 问题2CLD_ERR_00001 权限错误(当前问题❌)
**错误信息**
```json
{
"CLD_HEADER": {
"CLD_TX_CODE": "A3341TP01",
"CLD_TX_RESP": {
"CLD_DESC": "当前服务方无访问权限,请稍后重试!",
"CLD_CODE": "CLD_ERR_00001"
}
},
"CLD_BODY": null
}
```
**根本原因**:服务方编号 `YS44000009001853` 未开通 `A3341TP01` 接口访问权限
---
## 🔍 问题1诊断过程489错误
### 关键发现
对比 `doc/调用通讯接口可参考词demo1.java`第118-121行发现
```java
// 建行要求的加密流程
String enc_msg = RSAUtil.encrypt(msg, publicKey); // 第1次RSA加密 + BASE64编码
BASE64Encoder encoder = new BASE64Encoder();
enc_msg = encoder.encode(enc_msg.getBytes("UTF-8")); // 第2次再次BASE64编码
enc_msg = enc_msg.replaceAll("\r\n", ""); // 移除换行符
```
**我们之前只做了一次BASE64编码建行无法解密返回489错误**
### 修复方案
#### 1. 修改加密逻辑CcbHttpClient.php:64-73
```php
// 第一次加密和BASE64编码
$encryptedMessage = CcbRSA::encryptForCcb($message, $encryptPublicKey);
// 第二次BASE64编码按照建行demo要求
// demo1.java第120行: enc_msg = encoder.encode(enc_msg.getBytes("UTF-8"));
$encryptedMessage = base64_encode($encryptedMessage);
// 移除BASE64中的换行符
$encryptedMessage = str_replace(["\r", "\n", "\r\n"], '', $encryptedMessage);
```
#### 2. 修改解密逻辑CcbHttpClient.php:219-224
```php
// 第一次BASE64解码按照建行demo要求
// demo1.java第139行: enc_msg = new String(decoder.decodeBuffer(enc_msg),"UTF-8");
$cntDecoded = base64_decode($responseData['cnt']);
// 第二次解密和BASE64解码
$decryptedContent = CcbRSA::decryptFromCcb($cntDecoded, $this->config['private_key']);
```
#### 3. 验证结果
运行 `test_double_base64.php`
```
✅ 解密成功!解密内容与原文完全一致
✅ 签名验证成功!
✅ 双重BASE64编码逻辑正确
✅ 完全符合demo1.java的实现方式
```
**结论**489错误已解决现在能正常与建行通信了
---
## 🔍 问题2诊断CLD_ERR_00001权限错误
### 错误详情
- **错误代码**CLD_ERR_00001
- **错误描述**:当前服务方无访问权限,请稍后重试!
- **服务方编号**YS44000009001853
- **请求接口**A3341TP01订单推送
### 问题原因
建行系统配置问题,服务方未开通该接口的访问权限。可能原因:
1. **接口权限未开通**服务方编号在建行系统中未配置A3341TP01接口访问权限
2. **商户信息未备案**商户公钥、商户号、POS号等信息未在建行系统中正确配置
3. **环境不匹配**使用的API地址与服务方所在环境不匹配测试环境 vs 生产环境)
4. **服务方状态异常**:服务方被暂停或未激活
---
## ✅ 解决方案
### 立即行动:联系建行技术支持
**邮件/工单模板**
```
主题服务方YS44000009001853权限问题 - CLD_ERR_00001
您好,
我们在调用A3341TP01订单推送接口时遇到权限错误
【错误信息】
- 错误代码CLD_ERR_00001
- 错误描述:当前服务方无访问权限,请稍后重试!
- 服务方编号YS44000009001853
- 商户号105003953998037
- POS号068295530
- 分行号340650000
- 请求接口A3341TP01订单推送
【已完成的验证】
1. ✅ RSA加密解密逻辑正确已通过Java和PHP双重验证
2. ✅ 双重BASE64编码正确符合demo1.java要求
3. ✅ 能正常与建行API通信489错误已解决
4. ✅ 响应能正确解密和验证签名
【需要建行协助】
请帮忙检查并开通以下权限:
1. 确认服务方编号 YS44000009001853 的状态(是否已激活)
2. 为该服务方开通以下接口访问权限:
- A3341TP01订单推送
- A3341TP02订单状态更新
- A3341TP03订单查询
- A3341TP04退款接口
3. 确认以下商户信息是否已正确配置:
- 商户号105003953998037
- POS号068295530
- 分行号340650000
- 商户公钥BASE64
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6yZj5rUHz+plEbTMSxF6iRy5X
Td82LpKGkcRtJcNiHXAvOh/QvW6xc+GJSfvfM9pnRCyWkFrvFViOGnLUrjyoB0wa
/TEqWootEEKXSDacFyQ/QIJSK0+zMYTC2Md6gGA4YylJQuYZ1lWDoOLBt9pP93Qn
m0R2PEQ5a11HxwdvlQIDAQAB
4. 确认我们使用的环境(测试/生产)与服务方配置是否匹配
谢谢!
联系人:[你的姓名]
电话:[你的电话]
邮箱:[你的邮箱]
```
---
## 📁 相关文件
### 已修复的代码
1. **CcbHttpClient.php** - HTTP客户端
- ✅ 修复增加双重BASE64编码第64-73行
- ✅ 修复增加双重BASE64解码第219-224行
- ✅ 修复正确处理CLD_HEADER.CLD_TX_RESP错误响应第256-286行
- 使用统一的 `public_key` 加密请求
- 使用统一的 `private_key` 签名和解密
2. **CcbRSA.php** - 密钥处理
- ✅ 自动识别PKCS#1和PKCS#8格式
- ✅ 正确处理密钥PEM格式化
- ✅ 已通过测试验证
3. **CcbMD5.php** - 签名算法
- ✅ API签名使用大写MD5
- ✅ 支付签名使用小写MD5
- ✅ 已通过Java和PHP双重验证
### 测试脚本
1. **doc/demo/TestCCBEncryption.java** - Java验证脚本
- 验证了Java代码正确性
- 证明了demo密文问题
2. **test_double_base64.php** - 双重BASE64编码测试
- ✅ 验证了双重BASE64编码逻辑正确
- ✅ 确认加密解密流程完整
- ✅ 符合demo1.java的实现方式
3. **test_key_format.php** - PHP密钥格式测试
- 验证了PHP密钥加载正确性
- 确认PKCS#8格式支持
### 参考文档
1. **doc/调用通讯接口可参考词demo1.java** - 建行官方demo
- 🔑 关键参考第118-121行双重BASE64编码
- 🔑 关键参考第137-140行双重BASE64解码
---
## 📊 技术总结
### ✅ 已解决的问题
1. **489错误exception01**
- 原因缺少双重BASE64编码
- 解决按照demo1.java实现双重BASE64编码
- 状态:✅ 已解决
2. **PKCS#8私钥格式支持**
- 原因代码默认只支持PKCS#1
- 解决:自动检测密钥格式
- 状态:✅ 已解决
3. **错误响应解析**
- 原因只检查CLD_BODY未检查CLD_HEADER.CLD_TX_RESP
- 解决优先检查CLD_HEADER.CLD_TX_RESP
- 状态:✅ 已解决
### ❌ 待解决的问题
1. **CLD_ERR_00001权限错误**
- 原因:服务方未开通接口访问权限
- 解决:联系建行技术支持开通权限
- 状态:❌ 等待建行处理
### 🔧 代码验证结果
- ✅ RSA加密解密实现正确Java和PHP双重验证通过
- ✅ MD5签名算法正确
- ✅ 密钥格式处理正确支持PKCS#8
- ✅ 双重BASE64编码逻辑正确
- ✅ 能正常与建行API通信
- ✅ 响应解密和验证签名正确
---
## 🚀 下一步行动
### 立即执行
1. **联系建行技术支持**
- 使用上面的邮件模板
- 重点说明CLD_ERR_00001权限问题
- 请求开通A3341TP01等接口权限
2. **准备商户资料**
- 服务方编号YS44000009001853
- 商户号105003953998037
- POS号068295530
- 分行号340650000
- 商户公钥BASE64格式
### 建行回复后
根据建行技术支持的反馈:
- **如果需要补充资料** → 按要求提供商户证明、合同等文件
- **如果需要重新注册** → 按流程重新提交服务方申请
- **如果是环境问题** → 切换到正确的API地址
- **如果权限开通** → 重新测试接口,应该就能正常工作了
---
## 📞 联系信息
**建行生活技术支持**
- 联系方式:(填写建行提供的技术支持联系方式)
- 服务方编号YS44000009001853
- 商户号105003953998037
---
**报告生成时间**2025-10-22 14:55
**问题状态**
- ✅ 489错误已解决双重BASE64编码
- ❌ CLD_ERR_00001权限错误待建行处理
**代码状态**:✅ 已修复并验证,等待建行开通权限