WooCommerce插件中PayPal Webhook签名验证失败求助
PayPal Webhook签名验证失败的排查与修复
核心问题分析
你的代码中最关键的错误是手动构造了精简版的webhook_event,PayPal的签名验证要求必须提交完整的原始Webhook事件数据,任何对原始请求体的修改(比如删减字段、调整结构)都会导致签名不匹配,直接返回Failure。另外还有请求头大小写兼容、原始数据传递方式的潜在问题。
具体修复步骤
1. 修正Webhook事件数据的传递
删除手动构造$webhook_event的代码,直接使用完整的原始请求体解码数据,同时兼容请求头的大小写差异:
public function eh_verify_webhook_signature_paypal($headers, $raw_data, $webhook_id) { // 兼容请求头大小写,避免服务器返回小写头导致获取失败 $transmission_id = null; $transmission_time = null; $cert_url = null; $auth_algo = null; $transmission_sig = null; foreach ($headers as $key => $value) { $lower_key = strtolower($key); switch ($lower_key) { case 'paypal-transmission-id': $transmission_id = $value; break; case 'paypal-transmission-time': $transmission_time = $value; break; case 'paypal-cert-url': $cert_url = $value; break; case 'paypal-auth-algo': $auth_algo = $value; break; case 'paypal-transmission-sig': $transmission_sig = $value; break; } } // 直接使用原始请求体的完整解码数据,不做任何修改 $webhook_event = json_decode($raw_data, true); // 执行验证并返回结果 $verification_response = $this->perform_webhook_signature_verification( $transmission_id, $transmission_sig, $transmission_time, $webhook_event, $cert_url, $auth_algo, $webhook_id ); return $verification_response; }
2. 确保验证请求参数正确
在perform_webhook_signature_verification方法中,保证webhook_event传递的是完整原始事件:
$args = array( 'method' => 'POST', 'headers' => array( 'Authorization' => 'Bearer ' . $this->access_token, 'Content-Type' => 'application/json', ), 'body' => wp_json_encode( array( 'transmission_id' => $transmission_id, 'transmission_time' => $transmission_time, 'cert_url' => $cert_url, 'auth_algo' => $auth_algo, 'transmission_sig' => $transmission_sig, 'webhook_id' => $webhook_id, 'webhook_event' => $webhook_event, // 传递完整原始事件 ) ), );
3. 额外排查点
- 环境一致性:确认Access Token、Webhook ID与当前环境(沙箱/生产)完全匹配,禁止混用不同环境的凭证。
- 服务器时间同步:PayPal签名验证依赖
transmission_time,服务器时间与PayPal服务器时间差超过5分钟会导致验证失败,需确保服务器时间同步。 - 请求头完整性:检查日志确认是否正确获取到所有PayPal相关请求头,避免反向代理或服务器配置过滤了部分头信息。
验证与日志排查
修复后查看日志中的Response Data,若仍失败,PayPal会返回details字段说明具体错误(如INVALID_SIGNATURE、INVALID_TRANSMISSION_ID等),可根据错误信息进一步定位问题。
内容的提问来源于stack exchange,提问作者Nafid P
相关产品推荐
相关产品推荐

