实时模式下的 PayPal IPN 和 [SSL_ERROR_SYSCALL, errno 60]
Posted
技术标签:
【中文标题】实时模式下的 PayPal IPN 和 [SSL_ERROR_SYSCALL, errno 60]【英文标题】:PayPal IPN in LIVE mode and [SSL_ERROR_SYSCALL, errno 60] 【发布时间】:2018-06-23 10:50:56 【问题描述】:问题标题中简要说明了我的问题。我知道不仅我有同样的问题,而且很多人都面临它。因此,在问我的问题之前,我使用了对所有 *** 的搜索,并阅读了很多此类问题的答案。我尝试了这里提供的所有解决方案选项,但没有一个能帮助我解决这个问题。
我使用一个简单的 php 脚本 (ipnlistener) 来接收 IPN,因此有关此交易的信息被输入到我的数据库中,并向买家发送邮件,其中包含下载文件的链接。 在沙盒测试模式下一切正常 - 数据输入数据库并将邮件发送给买家。我还检查了 IPN 模拟器,也没有收到任何错误 - 它发出消息“IPN 已发送并且握手已验证。”
但是,一旦我切换到 LIVE 模式,我就会在日志中看到以下条目:“SSL_ERROR_SYSCALL, errno 60”并且在此脚本执行停止,直到下一次尝试发送 IPN,这也以同样的错误结束。
下面是我使用的 ipnlistener.php 的代码:
<?php
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$paypal_post = array();
foreach ($raw_post_array as $keyval)
$keyval = explode ('=', $keyval);
if (count($keyval) == 2)
$paypal_post[$keyval[0]] = urldecode($keyval[1]);
//extract vars
extract($paypal_post, EXTR_OVERWRITE);
// build request
$req = 'cmd=' . urlencode('_notify-validate');
$ipn_vars = 'cmd=' . urlencode('_notify-validate');
foreach ($paypal_post as $k => $v)
$v = urlencode($v);
$req .= "&$k=$v";
// sort array keys (only after building $req var which will be used to send curl to paypal)
ksort($paypal_post);
foreach ($paypal_post as $k => $v)
$ipn_vars .= "\n$k=" . urldecode($v);
// paypal mode
$paypal_mode = 1;
// sandbox on/off
if($paypal_mode == 1)
$paypal_url = 'https://www.paypal.com/cgi-bin/webscr';
//for IPN-simulator:
//$paypal_url = 'https://ipnpb.paypal.com/cgi-bin/webscr';
// else is production site
else
$paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
//for IPN-simulator:
//$paypal_url = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $paypal_url);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
$res = curl_exec($ch);
//Check if any error occured
if(curl_errno($ch))
error_log("Got " . curl_error($ch); . " when processing IPN data");
else
if (strcmp (trim($res), "VERIFIED") == 0)
//here is the code for adding information to the database, downloading the link for downloading the file and sending the mail to the buyer.
else if (strcmp (trim($res), "INVALID") == 0)
//here is the code to send mail to the seller, if the transaction has not been verified
?>
如您所见,在此代码中,CURL 选项中的证书检查是 DISABLED (false),但我仍然收到错误“errno 60”!
好的。我从这个链接下载了最新的当前证书文件:https://curl.haxx.se/docs/caextract.html 并根据本教程在 CURL 选项中的证书检查上设置为启用:http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/,更改这些行:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
并添加证书文件的完整路径(当然,我指出了放置它的文件的真实路径):
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . '/cert/cacert.pem');
但我仍然不断收到相同的错误:SSL_ERROR_SYSCALL, errno 60!
请告诉我 - 我的代码有什么问题?我的错误是什么?我还能如何解决我的问题?
PS:另外,我的服务器配置完全符合要求:TLS v1.2,OpenSSL 1.0.1k
【问题讨论】:
确认你的 cacert.pem 路径是 true 路径;当前工作目录 (getcwd()
) 可能会更改。例如,通过$_SERVER['DOCUMENT_ROOT'] . "/cert/cacert.pem"
提供路径可能会更好,即使当前工作目录发生更改,它也将成立。
我不知道这是否会有所作为,但在我的一个 Paypal 实例中,我在 VERIFY
行上方也有一行 curl_setopt($ch, CURLOPT_SSLVERSION, 6);
。这有帮助吗?
@Martin 谢谢你的回答!当然,我指出了文件的真实路径,他把它放在了这个表格里:/pub/home/cert/cacert.pem
。我也试过这个方法$_SERVER['DOCUMENT_ROOT']
,并把curl_setopt($ch, CURLOPT_SSLVERSION, 6)
这一行添加到CURL选项中,但错误依然存在。
@Martin 奇怪的是,即使我在 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
和 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
这几行的 CURL 选项中关闭证书检查,我仍然会收到相同的错误:errno 60
。天呐??
一些谷歌搜索似乎表明这是您安装 OpenSSL 的某种问题;而不是使用 Paypal 或您的 PHP 设置。我已经更新了你的标签。
【参考方案1】:
好的。有一段时间我不得不从这个问题上分心,因为我正在从事另一个项目。但我找到了解决方案。一切都变得很简单,它根本不在证书中,也不在 cURL 设置中。
最近似乎 PayPal 更改了在 LIVE 模式下检查 IPN 的链接,现在在参数 $paypal_url = 'https://www.paypal.com/cgi-bin/webscr';
中链接不是以“www”开头,而是以“ ipnpb”。也就是说,代码中的这一行应该是这样的:$paypal_url = 'https://ipnpb.paypal.com/cgi-bin/webscr';
之前此链接仅用于 IPN-Simulator,现在用于 LIVE 模式!
对于 Sandbox,也希望使用 https://ipnpb.sandbox.paypal.com/cgi-bin/webscr
而不是 https://www.sandbox.paypal.com/cgi-bin/webscr
,但目前它在两个版本中都可以使用。
另外需要注意的是,在购买按钮<form action ="https://www.paypal.com/cgi-bin/webscr" method ="post"/>
的形式中,链接还是必须和“www”一起使用,不能和“ipnpb”一起使用>”。
当我更正代码 ipn.php 脚本中的链接时 - 这一切都对我有用!
更多详细信息请点击此处:https://www.paypal-notice.com/en/IPN-Verification-Postback-to-HTTPS/
【讨论】:
以上是关于实时模式下的 PayPal IPN 和 [SSL_ERROR_SYSCALL, errno 60]的主要内容,如果未能解决你的问题,请参考以下文章
Paypal Sandbox IPN: 14077410:sslroutines:ssl23_get_server_hello:sslv3 警报握手失败
PayPal IPN OPENSSL 错误:14077410:SSL 例程:SSL23_GET_SERVER_HELLO:sslv3 警报握手失败