简体   繁体   English

PayPal IPN侦听器回发失败

[英]PayPal IPN Listener failing on postback

First time here and I am completely stumped after days of trying to resolve the problem. 第一次来这里,经过数天试图解决问题,我完全被迷住了。 Here's the background to this problem... 这是此问题的背景...

I have a PayPal IPN listener script. 我有一个PayPal IPN侦听器脚本。 In fact I have two versions of it because the first didn't work so I tried another but that didn't work either. 实际上,我有两个版本,因为第一个不起作用,所以我尝试了另一个版本,但也没有起作用。 Both of the IPN listener scripts I obtained from PayPal... 我从PayPal获得的两个IPN侦听器脚本...

paypal_notifyA.php paypal_notifyA.php

From... developer . 来自...开发人员。 paypal . 贝宝。 com /docs/classic/ipn/gs_IPN/ com / docs / classic / ipn / gs_IPN /

The script stops at... 脚本停在...

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

<?php require_once("../lib/PHPMailer/PHPMailerAutoload.php"); ?>

<?php
// Paypal IPN

// 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
$invoiceID          = $_POST['invoice'];
$paymentStatus      = $_POST['payment_status'];
$productID          = $_POST['item_number'];
$paymentAmount      = $_POST['mc_gross'];
$paymentCurrency    = $_POST['mc_currency'];
$txnID              = $_POST['txn_id'];
$receiverEmail      = $_POST['receiver_email'];
$payerEmail         = $_POST['payer_email'];
$response           = $_POST['response'];

// Build the required acknowledgement message out of the notification just received  
$req = 'cmd=_notify-validate';                  // Add 'cmd=_notify-validate' to beginning of the acknowledgement
foreach ($_POST as $key => $value) {            // Loop through the notification NV pairs
    $value = urlencode(stripslashes($value));   // Encode these values
    $req  .= "&$key=$value";                    // Add the NV pairs to the acknowledgement
}

// 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";

// The PayPal IPN Simulator fails on the line below...
// Open a socket for the acknowledgement request
$fp = fsockopen('tls://www.sandbox.paypal.com', 443, $errno, $errstr, 30);  // paypal.com (LIVE) - sandbox.paypal.com (TEST)

// 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

        $testStage = "Got past Verified!";
        require_once("../emails/ipn_test.php");

        // DO MY OWN VERIFIED STUFF HERE

// ***** INVALID RESPONSE ***** 
} else if (strcmp ($res, "INVALID") == 0) { // Response contains INVALID - reject notification

    // DO MY OWN INVALID STUFF HERE
}

}
fclose($fp);  // Close the file
?>

paypal_notifyB.php paypal_notifyB.php

From... github . 来自... github。 com /paypal/ipn-code-samples/blob/master/paypal_ipn.php com /paypal/ipn-code-samples/blob/master/paypal_ipn.php

The script stops at... 脚本停在...

$res = curl_exec($ch); $ res = curl_exec($ ch);

And reports the following in the error log... 并在错误日志中报告以下内容...

Can't connect to PayPal to validate IPN message: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure 无法连接到PayPal以验证IPN消息:错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:sslv3警报握手失败

<?php require_once("../lib/PHPMailer/PHPMailerAutoload.php"); ?>

<?php
// Paypal Notify

// Start session
session_start();

// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don't require logging.
define("DEBUG", 1);

// Set to 0 once you're ready to go live
define("USE_SANDBOX", 1);

define("LOG_FILE", "./ipn.log");


// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
    $keyval = explode ('=', $keyval);
    if (count($keyval) == 2)
        $myPost[$keyval[0]] = urldecode($keyval[1]);
}

// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
if(function_exists('get_magic_quotes_gpc')) {
    $get_magic_quotes_exists = true;
}

foreach ($myPost as $key => $value) {
    if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
        $value = urlencode(stripslashes($value));
    } else {
        $value = urlencode($value);
    }
    $req .= "&$key=$value";
}

// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
if(USE_SANDBOX == true) {
    $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
    $livetestEmail = "info-facilitator@flysoftware.com";
} else {
    $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
    $livetestEmail = "info@flysoftware.com";
}

$ch = curl_init($paypal_url);
if ($ch == FALSE) {
    return FALSE;
}

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, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);

if(DEBUG == true) {
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}

// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.

$cert = __DIR__ . "./cacert.pem";
curl_setopt($ch, CURLOPT_CAINFO, $cert);

// PayPal IPN Simulator fails on the line below and reports following error...
// Can't connect to PayPal to validate IPN message: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
$res = curl_exec($ch);

if (curl_errno($ch) != 0) { // cURL error

    if(DEBUG == true) { 
        error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
    }
    curl_close($ch);
    exit;
} else {
        // Log the entire HTTP response if debug is switched on.
        if(DEBUG == true) {
            error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
            error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
        }
        curl_close($ch);
}

// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp

$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));

if (strcmp ($res, "VERIFIED") == 0) { // Response is verified

    $testStage = "Got past Verified!";
    require_once("../emails/ipn_test.php");

    // DO MY OWN VERIFIED STUFF HERE

// ***** INVALID RESPONSE ***** 
} else if (strcmp ($res, "INVALID") == 0) { // Response contains INVALID - reject notification

    // DO MY OWN INVALID STUFF HERE

    if(DEBUG == true) {
        error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
    }

}
?>

When I try both scripts in the PayPal IPN Simulator, both report... 当我在PayPal IPN模拟器中尝试两个脚本时,两个报告...

IPN was sent and the handshake was verified. IPN已发送,握手已验证。

However, both scripts don't communicate back to PayPal and the "If VERIFIED" condition is never reached. 但是,两个脚本都不会与PayPal通信,并且永远不会达到“如果已验证”条件。 It is therefore irrelevant there is not yet backend code after this condition - just trying to get the listener to work for now! 因此,在这种情况之后还没有后端代码是无关紧要的-只是试图让监听器暂时工作!

I have talked to my web host and they stated they disabled SSLv3 in the hope that was causing the problem. 我已经与我的网络托管商进行了交谈,他们说他们禁用了SSLv3,以希望引起问题。 It made no difference and both scripts continue to fail at the point where they communicate back to PayPal. 这没有什么区别,并且两个脚本在它们再次与PayPal通信时仍继续失败。 My host claims it is not "their" fault and that it is a problem with PayPal. 我的房东声称这不是“他们的”错误,并且与PayPal有关。 This is despite pointing my host in the direction of relevant SO threads (that I can't post because do not have the reputation). 尽管我将主机指向相关的SO线程(尽管我没有声誉,所以无法发布)。

stackoverflow . 堆栈溢出 。 com / questions/35030756/paypal-ipn-openssl-error14077410ssl-routinesssl23-get-server-hellosslv3-aler com /问题/ 35030756 / paypal-ipn-openssl-error14077410ssl-routinesssl23-get-server-hellosslv3-aler

stackoverflow . 堆栈溢出 。 com / questions/34955346/paypal-ipn-handshake-issues com /问题/ 34955346 / paypal-ipn-握手问题

And this page from PayPal... 贝宝的这个页面...

paypal-knowledge . 贝宝知识。 com / infocenter/index?page=content&id=FAQ1766&expand=true&locale=en_US com / infocenter / index?page = content&id = FAQ1766&expand = true&locale = zh_CN

I hope someone can help me resolve this or at least confirm it is "my" scripts at fault or the server is at fault, because I'm getting nowhere!! 我希望有人能帮助我解决这个问题,或者至少确认它是“我的”脚本有问题还是服务器有问题,因为我无处可去!

PS I'm very new to PHP. PS我对PHP非常陌生。

Faced same problem but here using Java servlet to catch IPN notification. 面临同样的问题,但是这里使用Java servlet来捕获IPN通知。 After receive lots of parameters, response status 200 OK is sent back. 收到大量参数后,将响应状态200 OK发送回。 Then, a new HTTP request is formed keeping all parameters as received at first step and adding an extra command 'cmd' -- things look quite similar to your php code. 然后,形成一个新的HTTP请求,保留第一步中接收到的所有参数,并添加一个额外的命令“ cmd”-事情看上去与您的php代码非常相似。

As I see, fsockopen tries to connect to 'tls://www.sandbox.paypal.com', whereas I am using ' https://www.sandbox.paypal.com/cgi-bin/webscr '. 如我所见,fsockopen尝试连接到“ tls://www.sandbox.paypal.com”,而我正在使用“ https://www.sandbox.paypal.com/cgi-bin/webscr ”。 You may follow this tutorial which was quite helpful http://www.geekality.net/2011/05/28/php-tutorial-paypal-instant-payment-notification-ipn 您可能会遵循本教程,该教程非常有帮助http://www.geekality.net/2011/05/28/php-tutorial-paypal-instant-payment-notification-ipn

VERIFIED was received finally. 终于收到了验证。 One thing to note that, due to https, there were a certificate expire warning for which I had to disable ignore cookies in Apache http client. 需要注意的一件事是,由于https,有一个证书过期警告,为此我必须在Apache http客户端中禁用忽略cookie。

Hope this post eases some of your pain. 希望这篇文章减轻您的痛苦。 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM