未从Paypal IPN沙盒接收到响应

10
我正在将 PayPal 结账功能添加到我的网站上,但却在监听器方面出了问题。如果您不熟悉 PayPal IPN 系统,基本上 PayPal 会向您的脚本发送有关交易的消息,您需要添加一些信息并将其发送回去。如果 PayPal 收到正确的答复,它将回复“已验证”,否则它将说“无效”。
我成功完成了第一部分。我的代码能够接收来自 PayPal 的信息,添加额外的信息并将其发送回去。然而,在沙盒中我没有收到任何来自 PayPal 的“已验证”或“无效”的响应。我几乎是从 PayPal 网站上直接复制我的代码,所以我希望这应该是相当简单的事情,如果您能花一分钟时间查看我的代码,也许新的眼睛可以找出我的错误。
以下是代码。没什么特别的,它只是获取信息、调整信息、传递信息并读取响应(要么没有收到,要么没有意识到已经收到)。
<?php

$debug=true;

//Put together postback info

$postback = 'cmd=_notify-validate';

foreach($_POST as $key =>$value){
     $postback .= "&$key=$value";
}

// build the header string to post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($postback) . "\r\n\r\n";

$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);//open the connection

if(!$fp){ //no conn
    die();
}

//post data back
fputs($fp, $header . $postback);

while(!feof($fp)){

    $res=fgets ($fp, 1024);

    if((strcmp($res, "VERIFIED")) == 0){ //verified!
        if($debug){         
            $filename = 'debug/debug5_verified.txt'; //create a file telling me we're verified
            $filehandle=fopen($filename, 'w');
            fwrite($filehandle,'VERIFIED!');
            fclose($filehandle);
        }
    }
}

?>

提前感谢!


也许这个链接对你有帮助... http://stackoverflow.com/questions/14827497/unable-to-getting-response-from-paypal-ipn-sandbox - Nikhil Thombare
6个回答

11

改用HTTPS的URL,我不确定何时发生的,但最近我的所有测试脚本都在使用纯HTTP版本时失败了。他们似乎正在迁移。

我正在使用与你相同的PayPal示例代码:

    $fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);    
或者
    $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);

谢谢你的帮助!你能告诉我你是如何制作这个开关的吗? - user1070084
1
关于此更改的背景信息:https://www.x.com/content/bulletin-ip-address-expansion-paypal-services - Robert

9

我认为我找到了一个解决方案。事实证明,它并不是在连接ssl://sandbox时出现问题,而是在检索答案时遇到了问题。代码卡在了

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

我所做的只是将其替换为 bit:

$res=stream_get_contents($fp, 1024);

它第一次就起作用了!现在我可以继续我的生活。再次感谢你在这件事上的所有帮助。


如果你正在寻找正确的答案,对于一些人来说,使用ssl://和端口443是正确的。我曾经遇到同样的问题,切换到ssl协议并使用端口443解决了我的问题。在沙盒环境中,我得到了一个空响应。请注意,stream_get_contents解决方案对我无效,所以如果这对你不起作用,请尝试其他建议!尽管截至2012年6月8日,端口80仍然可以从现场运行。 - Dave Thomas
为什么这个解决方案有效?你是如何意识到这就是解决方案的? - nulll

3
也许原始代码缺少以下内容:$header .= "Connection: close\r\n\r\n"; 请注意,Paypal的样本代码使用HTTP/1.0,因此没有这一行。而HTTP/1.1是可以的,但可能需要这一行。
另一个问题是,沙箱可能不再支持端口80。我正在收到一个302重定向到https://www.sandbox.paypal.com

这也是我注意到的。两年前我设置了一个IPN,文档说我可以在沙盒中使用普通HTTP。但是今天我发现它返回302,我必须在端口443上使用SSL进行POST。 - thomthom

0

检查 PHP 版本 TLS Socket。应该使用 TLS 1.2 才能从沙盒账户获取响应。升级 PHP 版本到 5.5 以获取 TLS 1.2 Socket。

PayPal 已禁用 SSLv3 服务并更改为 TLS 1.2。

如果需要获取响应,则必须要求 PHP 版本支持 TLS 1.2,为了获得 TLS 1.2,可以将 PHP 升级到 5.5 或更高版本。

访问 链接


0

我注意到你发布的URL与下面的有所不同,是这个原因吗?

这是来自IPN测试帮助页面的:

检查您是否将响应发布到正确的URL,即https://www.sandbox.paypal.com/cgi-bin/webscrhttps://www.paypal.com/cgi-bin/webscr,具体取决于您是在Sandbox中进行测试还是生产环境中进行测试。

验证您的响应是否包含完全相同的IPN变量和值,以相同的顺序前缀为cmd=_notify-validate。

确保您对响应字符串进行编码,并使用与原始消息相同的字符编码。

编辑:抱歉我还想提一下HTTP和HTTPS的端口不同,80和443。我对Paypal API不是很熟悉,但可以研究一下,因为我看到您正在使用80端口。


谢谢你的帮助!我尝试了所有可能的组合,但仍无法解决问题,不过我会向您展示我尝试过的内容:主要是我更改了$fp变量,并且保持$header =."Host:...."不变或将其注释掉。我不确定我是否表达清楚,但在此之前,根据我的代码,我已成功连接到我要连接的网站,也就是说,$fp是有效的,因此条件if(!$fp)没有被满足。自从您的回复后,我尝试了每种组合,但都没有奏效。奇怪的是,$ fp=fsockopen('h ttp://w ww.san...com' 80,,, 30)不起作用(但删除“http”后它可以工作)。 - user1070084
你能尝试使用ssl://代替https://(同时保持端口443),看看是否有效吗? - Ace
再次感谢!虽然当我添加ssl://时,它无法发送IPN。它只是挂起并显示无法访问网站。 - user1070084
我找到了这个论坛帖子:http://www.phpbuilder.com/board/archive/index.php/t-10329375.html,它提到了你所面临的类似问题。我真心希望你能从那个帖子中找到解决方案,祝你好运,很抱歉我无法提供更多帮助! - Ace
感谢您的帮助,我今天早上成功找到了解决方案! - user1070084
显示剩余2条评论

0

PayPal测试服务器已移至:

$fp = fsockopen('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30);

3
来源在哪里?我在PayPal的网站上没有找到有关此URL更改的任何内容。他们网站上的PHP5.2 IPN示例使用sandbox.paypal.com。 - thomthom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接