【问题标题】:PayPal IPN Listener won't work anymorePayPal IPN 监听器将不再工作
【发布时间】:2013-06-14 01:05:16
【问题描述】:

首先,感谢您的关注。 问题来了。

我正在使用这个 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)。 将 var_dump 放入 while 循环中:

....
        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 返回值?

【问题讨论】:

    标签: paypal paypal-ipn


    【解决方案1】:

    对我有用的是删除连接关闭标头,并为从 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)) {
    

    这对我有用。

    【讨论】:

      【解决方案2】:

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

      有时,当我的听众发回 cmd=_notify-validate 以检查新的 IPN 时,您会得到除“已验证”或“无效”以外的其他内容。

      有时我会明白:

      '8'.chr(13).chr(10).'VERIFIED'.chr(13).chr(10).'0'.chr(13).chr(10).chr(13)。 chr(10)

      有时我会明白:

      '00000008'.chr(13).chr(10).'VERIFIED'.chr(13).chr(10).'00000000'.chr(13).chr(10).chr(13)。 chr(10))

      我认为,如果您检查除“VERIFIED”或“INVALID”之外的这两个字符串,您会没事的。如果没有,请告诉我您从 paypal 获得的结果是什么,这些结果导致您的 stripos($res, "VERIFIED") 和 stripos($res, "INVALID") 测试失败。

      另外值得注意的是,我有时会从中间缓存或我的 ISP 收到错误,或者 paypal 只是超时.. 所以您的代码需要能够通过稍后对该 IPN 执行 cmd=_notify-validate 来从中恢复。

      最后...多年来,我一直在为 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/

      这些都是可靠的,并且延迟更少。我有一个每 15 分钟运行一次的 cron 作业,以使用这些方法检查新事务。每次收到 IPN 时,我都会运行新的交易检查。如果您需要有关实施的进一步指导,请告诉我。

      【讨论】:

        猜你喜欢
        • 2016-06-29
        • 2014-02-12
        • 1970-01-01
        • 2016-07-17
        • 2015-12-21
        • 2012-07-08
        • 2013-09-29
        • 2015-09-14
        • 2016-04-29
        相关资源
        最近更新 更多