diff --git a/addons/shopro/library/ccblife/CcbPaymentService.php b/addons/shopro/library/ccblife/CcbPaymentService.php index 016a8be..4fe48e3 100644 --- a/addons/shopro/library/ccblife/CcbPaymentService.php +++ b/addons/shopro/library/ccblife/CcbPaymentService.php @@ -267,27 +267,30 @@ class CcbPaymentService $encpub = $this->encryptPublicKeyLast30(); // 7. 组装最终支付串(传给建行收银台的URL参数) - // ⚠️ 注意:最终支付串需要对特殊字符进行URL编码 + // ⚠️ 重要修复:最终支付串不进行URL编码,与MAC签名字符串保持一致! + // 原因:escape编码的字段(PROINFO、REGINFO)如果再URL编码,会导致MAC验证失败 + // 例如:%u6F2B 会被编码成 %25u6F2B,与签名时的 %u6F2B 不一致 // 格式:参与MAC的参数 + 不参与MAC的参数 + MAC + PLATFORMID + ENCPUB - // 7.1 构建参与MAC的参数部分(需要URL编码) + // 7.1 构建参与MAC的参数部分(不URL编码,与签名字符串保持一致) $finalParts = []; foreach ($macParams as $key => $value) { - // 对值进行URL编码(建行收银台需要) - $finalParts[] = $key . '=' . urlencode($value); + // ✅ 不进行URL编码,保持与MAC签名字符串一致 + $finalParts[] = $key . '=' . $value; } // 7.2 添加不参与MAC的参数 if (!empty($nonMacParams)) { foreach ($nonMacParams as $key => $value) { - $finalParts[] = $key . '=' . urlencode($value); + // ✅ 不URL编码 + $finalParts[] = $key . '=' . $value; } } - // 7.3 添加MAC、PLATFORMID、ENCPUB(ENCPUB已经是base64,需要URL编码) + // 7.3 添加MAC、PLATFORMID、ENCPUB $finalParts[] = 'MAC=' . $mac; $finalParts[] = 'PLATFORMID=' . $this->config['service_id']; - $finalParts[] = 'ENCPUB=' . urlencode($encpub); + $finalParts[] = 'ENCPUB=' . $encpub; // ✅ ENCPUB是BASE64,不需要额外编码 // 7.4 拼接最终支付串 $finalPaymentString = implode('&', $finalParts);