PayPal IPN侦听器将不再起作用

时间:2013-06-17 23:11:59

标签: paypal paypal-ipn

首先,感谢您的关注。 来到概率。

我正在使用此IPN侦听器代码:

// IPN LISTENER
// intercetta le variabili IPN inviate da PayPal
$req = 'cmd=_notify-validate';     
// legge l'intero contenuto dell'array POST
foreach ($_POST as $key => $value) {
    $value = urlencode(stripslashes($value));
    $req .= "&$key=$value";
}

// intestazione, prepara le variabili PayPal per la validazione
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";  // www.paypal.com for a live site
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Connection: close\r\n\r\n";

// apre una connessione al socket PayPal
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

// converte le variabili inviate da IPN in variabili locali
$txn_id = filter_var($_POST['txn_id'], FILTER_SANITIZE_STRING);
$payment_status = filter_var($_POST['payment_status'], FILTER_SANITIZE_STRING);
$receiver_email = filter_var($_POST['receiver_email'], FILTER_SANITIZE_EMAIL);
$payer_email = filter_var($_POST['payer_email'], FILTER_SANITIZE_EMAIL);
$first_name = filter_var($_POST['first_name'], FILTER_SANITIZE_STRING);
$last_name = filter_var($_POST['last_name'], FILTER_SANITIZE_STRING);
$address_street = filter_var($_POST['address_street'], FILTER_SANITIZE_STRING);
$address_city = filter_var($_POST['address_city'], FILTER_SANITIZE_STRING);
$address_state = filter_var($_POST['address_state'], FILTER_SANITIZE_STRING);
$address_zip = filter_var($_POST['address_zip'], FILTER_SANITIZE_STRING);

// verifica l'apertura della connessione al socket
if (!$fp) {

    // se la connessione non avviene l'esecuzione dello script viene bloccata
print("connessione PayPal non avvenuta, si prega di riprovare piu' tardi");

    // in alternativa è per esempio possibile inviare un'email al venditore
} else {

    // elaborazione delle informazioni
    fputs ($fp, $header . $req);
    while (!feof($fp)) {
        $res = fgets ($fp, 1024);

        // azioni in caso di risposta positiva da parte di PayPal
        if (stripos($res, "VERIFIED") !== false) {
$myvariables = 1;
$anothermyvariables = "INSERT INTO MyDB ( paid, name, email, date) 
VALUES ('". $txn_id ."','" . $first_name ." ". $last_name .  "','" . $payer_email ."','". the_date('Y-m-d','','',FALSE) . "');";
$wpdb->query($anothermyvariables);
            }

        }

        // azione in caso di risposta negativa da parte di PayPal else
        if (stripos($res, "INVALID") !== false) {
$anothervariablesofmine = 2;
$paypalerr = "Pagamento non riuscito!"; // Payment not success!
        }

    }

    // chiusura della sorgente di dati
    fclose($fp);

之前确实有效,但现在没有...我已经测试了PayPal使用var_dumppayment_status=Completed返回我网站的变量。他们似乎没问题。

我已经测试过是否建立了连接并且它是否有效:

if (!$fp) {
ecc..
} else {
print("Connection Established");
etc....

问题来自变量stripos($res, "VERIFIED") stripos($res, "INVALID")var_dump同时返回bool (false)

查看沙箱配置文件历史记录(买方和卖方),所有交易结果均已完成。但令我疯狂的是,一周后效果很好...... 我搜索过可能是PayPal的IPN侦听器端口,主机或变量的一些变化,但似乎没有任何变化。正确?

我直接在购买表单页面中编写了IPN侦听器,这意味着IPN侦听器也被调用而没有$_POST个变量。对我来说,只有可能的回复是来自PayPal方面的IPN侦听器的垃圾邮件保护阻止了我,这可能吗? '因为没有cmd=_notify-validate也会调用监听器,但只是它不起作用(但是打了一个空白的电话,可能不太受PayPal的欢迎)。

编辑:

对不起,伙计们,重新调试(上帝保佑var_dump)。 在while循环中放置var_dump所以:

....
        while (!feof($fp)) {
        $res = fgets ($fp, 1024);
var_dump(stripos($res, "VERIFIED"));
print("<br> VERIFIED". stripos($res, "VERIFIED") ."<br>");
var_dump(stripos($res, "INVALID"));
print("<br> INVALID". stripos($res, "INVALID") ."<br>");
...

找到一个VERIFIED int(0)而不是bool (false)

我刚刚改变了

 if (stripos($res, "VERIFIED") !== false) {

 if (stripos($res, "VERIFIED") == 0) {

我在INVALID案例中也这么认为。

但我仍然不确定这是否正确。

那是问题吗?或者我可以改变别的东西吗?我是否必须同时使用if条件(if == 0if !== false)? PayPal刚刚更改了VERIFIED返回值?

2 个答案:

答案 0 :(得分:0)

对我来说有用的是删除连接关闭标头,并为PP的响应添加修剪。以下是标题:

$header  = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.paypal.com\r\n"; 
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

这是fsockopen:

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

以下是来自PP的回复修剪:

if (!$fp) {
// HTTP ERROR
  error_mail("Could not open socket");
//
} else {
  fputs ($fp, $header . $req);
  while (!feof($fp)) {
    $res = trim(fgets ($fp, 1024));
    }
//
// check the payment_status is Completed
// check that receiver_email is your Primary PayPal email
//
  if ((strcmp ($res, "VERIFIED") == 0) && ($payment_status == "Completed") && ($receiver_email == $valid_receiver_email)) {

这对我有用。

答案 1 :(得分:0)

我遇到了类似的问题,修复如下:

有时,当我的听众回复cmd = _notify-validate以检查新的IPN时,您将获得除了&#34;已验证&#34;之外的其他内容。或&#34;无效&#34;背部。

有时我会这样:

&#39; 8&#39; .CHR(13).CHR(10)&#39; VERIFIED&#39; .CHR(13).CHR(10)&#39; 0&#39 ;. CHR(13).CHR(10).CHR(13).CHR(10)

有时我会这样:

&#39; 00000008&#39; .CHR(13).CHR(10)&#39; VERIFIED&#39; .CHR(13).CHR(10)&#39; 00000000&#39 ;. CHR(13).CHR(10).CHR(13).CHR(10))

我想如果你检查这两个字符串除了&#34; VERIFIED&#34;或&#34;无效&#34;你会没事的。如果没有,请告诉我你从paypal返回的内容是你的stripos($ res,&#34; VERIFIED&#34;)和stripos($ res,&#34; INVALID&#34;)测试。

另外值得注意的是,我有时会从中间缓存或我的ISP或paypal中获取错误,因此您的代码需要能够通过以后对该IPN执行cmd = _notify-validate来从中恢复。 / p>

最后......多年来我一直在努力应对IPN系统。它总是有点不可靠,文档在几个地方严重错误,IPN落后于交易,通常是15分钟或更长时间。

我发现使用API​​的TransactionSearch和GetTransactionDetails方法要好得多。

此处的文档:

https://developer.paypal.com/docs/classic/api/merchant/GetTransactionDetails_API_Operation_NVP/

https://developer.paypal.com/docs/classic/api/merchant/TransactionSearch_API_Operation_NVP/

这些是可靠的,并且滞后少得多。我有一个cron作业,每15分钟运行一次,以检查使用这些方法的新事务。我每次收到IPN时都会运行新的事务检查。如果您想获得有关实施的进一步指导,请与我们联系。