# 建行支付错误诊断报告 ## 📋 问题历史 ### 问题1:489错误(已解决✅) **错误信息**: ``` HTTP状态码:489 响应内容:{"data":{},"reqFlowNo":"...","errCode":"exception01","errMsg":"系统异常"} ``` **根本原因**:缺少双重BASE64编码 **解决方案**:按照 `doc/调用通讯接口可参考词demo1.java` 的实现,增加双重BASE64编码 --- ### 问题2:CLD_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权限错误待建行处理 **代码状态**:✅ 已修复并验证,等待建行开通权限