fgets(): SSL: 现有连接被远程主机强行关闭
fgets(): SSL: An existing connection was forcibly closed by the remote host
我正在使用 PayPays 示例 IPN 代码进行测试,该代码应该 return valid
或 invalid
用于交易。我正在使用 PayPals IPN 模拟器进行测试,它应该发送一些虚拟数据,然后验证它 (returning "Valid")。
我正在测试两个独立的 Web 服务器,它们都安装并启用了 OpenSSL。
在我们的本地 Web 服务器上,我们收到此错误消息。
fgets(): SSL: An existing connection was forcibly closed by the remote host.
在我们的客户端网络服务器上,使用相同的代码,我们得到:
fgets() [<a href='function.fgets'>function.fgets</a>]: SSL: Connection reset by peer in ...../paypal_ipn.php on line 43
PayPal 似乎不再有此的非 SSL 版本。
paypal_ipn.php:
<?php
ini_set("log_errors", 1);
ini_set("error_log", "error.log");
// Send an empty HTTP 200 OK response to acknowledge receipt of the notification
header('HTTP/1.1 200 OK');
// Assign payment notification values to local variables
//$item_name = $_POST['item_name'];
//$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
// Build the required acknowledgement message out of the notification just received
$req = 'cmd=_notify-validate'; // Add 'cmd=_notify-validate' to beginning of the acknowledgement
$req .= '&'.http_build_query($_POST);
// Set up the acknowledgement request headers
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; // HTTP POST request
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
// Open a socket for the acknowledgement request
//$fp = fsockopen('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
//$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
if ($fp === FALSE) {
error_log("Could not open socket");
exit("Could not open socket");
}
// Send the HTTP POST request back to PayPal for validation
fputs($fp, $header . $req);
while (!feof($fp)) { // While not EOF
$res = fgets($fp, 1024); // Get the acknowledgement response
if (strcmp ($res, "VERIFIED") == 0) { // Response contains VERIFIED - process notification
// Send an email announcing the IPN message is VERIFIED
$mail_From = "IPN@example.com";
$mail_To = "Your-eMail-Address";
$mail_Subject = "VERIFIED IPN";
$mail_Body = $req;
file_put_contents("log.txt", "valid: " . $req, FILE_APPEND | LOCK_EX);
// Authentication protocol is complete - OK to process notification contents
// Possible processing steps for a payment include the following:
// Check that the payment_status is Completed
// Check that txn_id has not been previously processed
// Check that receiver_email is your Primary PayPal email
// Check that payment_amount/payment_currency are correct
// Process payment
}
else if (strcmp ($res, "INVALID") == 0) { //Response contains INVALID - reject notification
// Authentication protocol is complete - begin error handling
// Send an email announcing the IPN message is INVALID
$mail_From = "IPN@example.com";
$mail_To = "Your-eMail-Address";
$mail_Subject = "INVALID IPN";
$mail_Body = $req;
file_put_contents("log.txt", "invalid: " . $req, FILE_APPEND | LOCK_EX);
}
}
fclose($fp); // Close the file
?>
我不会使用 CURL,因为那是其他很多问题!谁能看出是什么导致了这两个(单独的)错误?
编辑:
我刚刚在另一台服务器上进行了测试 运行 XAMPP(几乎启用了所有功能),现在我得到了这个 'error':
PHP Warning: fgets(): SSL: The operation completed successfully.
然而,交易根本没有得到验证。
在为此苦苦挣扎了一天之后,我回到家,决定今天早上解决这个问题。
使用 fget / fputs 似乎有问题。我可以在浏览器中使用 post 数据浏览到验证 URL,并且可以看到我使用的 URL 工作正常。
由于其他一些问题,我无法使用 CURL,而且没有足够的时间来解决它们。
*解法*:
改用file_get_contents()
。这使事情变得更容易,并且不需要发送 headers 或其他任何东西。这完美无缺!
$url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?' . $req;
$res = file_get_contents($url);
我今天遇到了同样的问题,但几个小时后我终于找到了根本原因。使用 Paypal's original PHP code 非常好,但不幸的是,自从他们切换到 HTTPS 后,它就相当过时了。为了使用 fgets,您需要在 header 中包含 HOST。为了快速修复,这里是我使用的代码示例:
$parsed_url = parse_url('https://www.sandbox.paypal.com/cgi-bin/webscr'); // Development (sandbox) or production URL
$header = "POST $parsed_url[path] HTTP/1.1\r\n";
$header .= "Host: $parsed_url[host]\r\n";
希望对你有用。
我正在使用 PayPays 示例 IPN 代码进行测试,该代码应该 return valid
或 invalid
用于交易。我正在使用 PayPals IPN 模拟器进行测试,它应该发送一些虚拟数据,然后验证它 (returning "Valid")。
我正在测试两个独立的 Web 服务器,它们都安装并启用了 OpenSSL。
在我们的本地 Web 服务器上,我们收到此错误消息。
fgets(): SSL: An existing connection was forcibly closed by the remote host.
在我们的客户端网络服务器上,使用相同的代码,我们得到:
fgets() [<a href='function.fgets'>function.fgets</a>]: SSL: Connection reset by peer in ...../paypal_ipn.php on line 43
PayPal 似乎不再有此的非 SSL 版本。
paypal_ipn.php:
<?php
ini_set("log_errors", 1);
ini_set("error_log", "error.log");
// Send an empty HTTP 200 OK response to acknowledge receipt of the notification
header('HTTP/1.1 200 OK');
// Assign payment notification values to local variables
//$item_name = $_POST['item_name'];
//$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
// Build the required acknowledgement message out of the notification just received
$req = 'cmd=_notify-validate'; // Add 'cmd=_notify-validate' to beginning of the acknowledgement
$req .= '&'.http_build_query($_POST);
// Set up the acknowledgement request headers
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; // HTTP POST request
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
// Open a socket for the acknowledgement request
//$fp = fsockopen('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
//$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
if ($fp === FALSE) {
error_log("Could not open socket");
exit("Could not open socket");
}
// Send the HTTP POST request back to PayPal for validation
fputs($fp, $header . $req);
while (!feof($fp)) { // While not EOF
$res = fgets($fp, 1024); // Get the acknowledgement response
if (strcmp ($res, "VERIFIED") == 0) { // Response contains VERIFIED - process notification
// Send an email announcing the IPN message is VERIFIED
$mail_From = "IPN@example.com";
$mail_To = "Your-eMail-Address";
$mail_Subject = "VERIFIED IPN";
$mail_Body = $req;
file_put_contents("log.txt", "valid: " . $req, FILE_APPEND | LOCK_EX);
// Authentication protocol is complete - OK to process notification contents
// Possible processing steps for a payment include the following:
// Check that the payment_status is Completed
// Check that txn_id has not been previously processed
// Check that receiver_email is your Primary PayPal email
// Check that payment_amount/payment_currency are correct
// Process payment
}
else if (strcmp ($res, "INVALID") == 0) { //Response contains INVALID - reject notification
// Authentication protocol is complete - begin error handling
// Send an email announcing the IPN message is INVALID
$mail_From = "IPN@example.com";
$mail_To = "Your-eMail-Address";
$mail_Subject = "INVALID IPN";
$mail_Body = $req;
file_put_contents("log.txt", "invalid: " . $req, FILE_APPEND | LOCK_EX);
}
}
fclose($fp); // Close the file
?>
我不会使用 CURL,因为那是其他很多问题!谁能看出是什么导致了这两个(单独的)错误?
编辑:
我刚刚在另一台服务器上进行了测试 运行 XAMPP(几乎启用了所有功能),现在我得到了这个 'error':
PHP Warning: fgets(): SSL: The operation completed successfully.
然而,交易根本没有得到验证。
在为此苦苦挣扎了一天之后,我回到家,决定今天早上解决这个问题。
使用 fget / fputs 似乎有问题。我可以在浏览器中使用 post 数据浏览到验证 URL,并且可以看到我使用的 URL 工作正常。
由于其他一些问题,我无法使用 CURL,而且没有足够的时间来解决它们。
*解法*:
改用file_get_contents()
。这使事情变得更容易,并且不需要发送 headers 或其他任何东西。这完美无缺!
$url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?' . $req;
$res = file_get_contents($url);
我今天遇到了同样的问题,但几个小时后我终于找到了根本原因。使用 Paypal's original PHP code 非常好,但不幸的是,自从他们切换到 HTTPS 后,它就相当过时了。为了使用 fgets,您需要在 header 中包含 HOST。为了快速修复,这里是我使用的代码示例:
$parsed_url = parse_url('https://www.sandbox.paypal.com/cgi-bin/webscr'); // Development (sandbox) or production URL
$header = "POST $parsed_url[path] HTTP/1.1\r\n";
$header .= "Host: $parsed_url[host]\r\n";
希望对你有用。