PayPal的 webhook监听器收到HTTP 302响应并进行重试
在沙箱模式下,我在PHP中使用 /v1/notifications/webhooks 为事件 PAYMENT.CAPTURE.COMPLETED 创建钩子。一切正常。
我的监听器在预期时会通知,并且使用回传(postback)和X.509证书正确地进行验证。监听器的第一行是 http_response_code(200)。
但在账户的webhook通知日志中,大多数通知被标记为 FAIL_SOFT,或在第二次尝试时为 FAIL_HARD,两者返回的有效载荷都显示:
"status": "FAILURE",
"transmissions": [ {"webhook_url": " "http_status": 302, "reason_phrase": "Redirects are not allowed", } ]
这通常意味着服务器在告诉浏览器它暂时重定向了该URL,但监听器显然并非通过浏览器访问,因此PayPal不会感到意外地被触发重传,即使返回了HTTP 200。
有何建议?
我的“创建监听器”是:
$listenerURL = "https://example.com/php/mylistener.php/";
$url =
“https://api-m.sandbox.paypal.com/v1/notifications/webhooks”;
$content_type = "Content-Type: application/json";
$payload = json_encode([
"url" => $listenerURL,
"event_types" => [
[
"name" => "PAYMENT.CAPTURE.COMPLETED"
]
]
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
[$authorization, $content_type]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$response = curl_exec($ch);
解决方案
再仔细想来,我其实是在做不可能的事,虽然被PayPal的错误——HTTP 302("Redirects are not allowed")打乱了节奏。我在这里详细说明,以防其他人遇到同样的问题。
错误的根源在于我的“你的支付已成功”HTML页面。当浏览器通过订单和支付端点发起支付时,这个通知可以正常工作——这是通常的工作方式**。
但当成功支付尝试使用webhook监听器通知时**,HEADER语句(见下文)仍然把PayPal作为客户端,而不是用户的浏览器。结果是PayPal看到这个重定向但将其阻止。更令人不快的是,监听器本身已经完美工作(同时通过回传和证书验证),但PayPal将该重定向标记为FAIL_SOFT,然后是FAIL_HARD,导致中止重发。
createOrder -> capturePayment ->[以下之一]
** getOrderDetails -> getPaymentDetails->[通知用户,使用header("Location: " .成功页面的URL)]
*** webhook监听器-> getOrderDetails -> getPaymentDetails->[通知用户,使用 HEADER ("Location: " .成功页面的URL)]