PayPal IPN 处于实时模式和 [SSL_ERROR_SYSCALL,errno 60]



我的问题在问题的标题中简要指出。我知道我不仅有同样的问题,而且很多人都面临这个问题。因此,在提出我的问题之前,我使用了搜索所有堆栈溢出并阅读了很多此类问题的答案。我尝试了这里提供的所有解决方案选项,但没有一个帮助我解决这个问题。

我使用一个简单的php脚本(ipnlistener)来接收IPN,因此有关此交易的信息被输入我的数据库,并向买方发送邮件,其中包含下载文件的链接。 在沙盒测试模式下一切正常 - 数据输入数据库并将邮件发送给买方。我还检查了 IPN 模拟器,也没有收到任何错误 - 它发出消息">IPN 已发送并已验证握手"。

但是一旦我切换到实时模式,我在日志中就会收到以下条目:">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 选项中的证书检查被禁用(false),但我仍然收到错误"errno 60">

还行。我从以下链接下载了最新的当前证书文件:https://curl.haxx.se/docs/caextract.html 并根据本教程在 CURL 选项中的证书检查中设置为 ENABLED: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

好的。有一段时间,我不得不从这个问题上分心,因为我正在从事另一个项目。但我找到了解决方案。事实证明一切都很简单,它根本不在证书中,也不在 cURL 设置中。

从最近看来,PayPal更改了在实时模式下检查 IPN 的链接,现在在参数$paypal_url = 'https://www.paypal.com/cgi-bin/webscr';链接不是以">www"开头,而是以">ipnpb"开头。也就是说,代码中的这一行完全应该是这样的:$paypal_url = 'https://ipnpb.paypal.com/cgi-bin/webscr';以前,此链接仅用于IPN模拟器,但现在它用于实时模式!

对于沙盒,也希望使用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/

相关内容

最新更新