Paypal IPN HTTP/1.1 - 根本不提供任何响应,它是一个空字符串

5 php paypal paypal-ipn

这种无法解释的可能影响或将影响成千上万的网站管理员.

问题是Paypal没有对此请求给出响应.下面是我使用的示例代码以及程序员的评论:

"PayPal根本没有对此请求做出任何响应,空字符串来自它.您可以询问PayPal团队,除了'Host'和'HTTP/1.1'之外还应该添加什么来正确处理响应.可能吗是'cmd'命令应该有另一个值吗?我的期望是PayPal将仅在2013年2月打开HTTP/1.1协议,因为它们在他们的电子邮件中说明.我不确定相同的脚本和主机如何处理不同的协议.脚本现在没有使用HTTP/1.1和我们存档的代码,原因可能是在PayPal方面.我正在关注PayPal如何查询IPN脚本,似乎它进入了某种循环,什么时候有HTTP 1.1设置.你仍然可以在ipnlogz.txt中看到它 - '07%3A39%3A41' - 即我订单的'07:39:41'日期 - 它重复了5次!为什么?谁知道......它只是意味着PayPal尝试IPN这个脚本5次并没有成功.只有当我将HTTP更新为1.0时才会出现来自PayPal的'验证'响应 重新上传脚本.在此之后,PayPal仍然在查询它.似乎当HTTP = 1.1时,PayPal正在正确地获取所有内容,但没有正确响应; 然后由于某种原因回来为同一笔付款创建另一个回复.使用HTTP 1.0,它就像一朵花:一个请求,一个响应,一切正常.我不知道它有什么问题......

PS.我们不是在谈论'无效'回复."INVALID"响应实际上是成功的一部分 - 但在HTTP 1.1的情况下,PayPal根本不提供任何响应,它是一个空字符串."

<?php

$req = 'cmd=_notify-validate';
$r='';

foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
$r.="{$key}: {$value}\n";
}

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.paypal.com\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
#I also tried: $fp =fsockopen('ssl://www.paypal.com',443,$err_num,$err_str,30);

if (!$fp) {
$r.="----\nHTTP ERROR\n";
// HTTP ERROR
} else {

$r.="----\nReceived IPN request\n";

fputs ($fp, $header . $req);

while (!feof($fp)) {
$res = fgets ($fp, 1024);
}
fclose ($fp);

if (strcmp ($res, 'VERIFIED') == 0) {

$proceed=TRUE;

}
else{
$proceed=FALSE;
}
}

?>
Run Code Online (Sandbox Code Playgroud)

PS.这是notify_url我们使用的脚本的一部分:

<input type="hidden" name="notify_url" value="{$main_url}/index.php?action=ipn&amp;user_id={$user_id}" />
Run Code Online (Sandbox Code Playgroud)

当它在沙盒中测试时,它正在工作..

Rob*_*ert 12

改变这个:

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.paypal.com\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
#I also tried: $fp =fsockopen('ssl://www.paypal.com',443,$err_num,$err_str,30);
Run Code Online (Sandbox Code Playgroud)

对此:

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.paypal.com\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Connection: close\r\n\r\n";
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
Run Code Online (Sandbox Code Playgroud)

还有这个:

if (strcmp ($res, 'VERIFIED') == 0) {
Run Code Online (Sandbox Code Playgroud)

对此:

if (strcmp (trim($res), 'VERIFIED') == 0) {
Run Code Online (Sandbox Code Playgroud)

并且它几乎可以保证工作.

您当前的设置失败,因为PayPal在fsockopen乐意接受的响应中发送一个Connection:keep-alive标头,因此它保持连接打开.
而诸如cURL之类的HTTP库将自动关闭连接.

我的一般建议是; 如果您不想控制通过该线路到PayPal的每一位,请使用HTTP库(如cURL),而不是fsockopen,它只是一个普通的TCP连接.
(PayPal有使用cURL的示例代码,可在https://www.paypal.com/ipnhttps://www.paypal.com/pdt获得)


小智 -1

我也遇到这个问题了,PP不承认有问题。我不知道该怎么办,但四个月后顾客就会生气。

您应该做出的一项更改是:

$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n"; // wrong  
$header .= "POST cgi-bin/webscr HTTP/1.1\r\n"; // right (according to PP)
Run Code Online (Sandbox Code Playgroud)