Paypal IPN 返回 HTTP/1.1 200 OK

发布于 2024-09-12 16:01:28 字数 1386 浏览 1 评论 0原文

我正在测试使用 Web 支付标准和 HTML 变量将网站集成到 Paypal。

我编写了一个简单的 PHP 脚本来处理 IPN 通知。

根据 Paypal 文档,一旦您将收到的数据 ping 回 Paypal,Paypal 服务器就会以简单的“已验证”或“无效”响应进行响应。

在我的处理程序中,我正在对这两个关键字进行区分大小写的字符串比较,如果未找到这些已知关键字之一,则将其视为错误。

<?php
  $fp = fsockopen ($socket_url, 80, $errno, $errstr, 10);

  if (!$fp){
     // SOCKET ERROR
     return false;
  }
  else {
         fputs ($fp, $header . $req);
         $is_ok = false;

         while (!feof($fp)) {
             $res = fgets ($fp, 1024);

             if (strcmp("VERIFIED",$this->ipn_response)==0) {
                //do something ...
             }
             // if the IPN POST was 'INVALID'
             else if (strcmp ($res, "INVALID") == 0) {
                 fclose ($fp);
                 return false;
             }
             else {
                echo "Unknown response from Paypal: $res";
                fclose ($fp);
                return false;
            }
         }

         fclose ($fp);
         return true;
   }
?>

我的错误消息显示我收到来自 Paypal 的“HTTP/1.1 200 OK”响应。

来自 Paypal 的未知响应: 'HTTP/1.1 200 正常'

PayPal API 是否已更改,或者我做错了什么?

I am testing integrating a website to Paypal, using Web Payments standard and HTML Variables.

I have written a simple PHP script to handle the IPN notifications.

According to the Paypal documentation, the Paypal server responds with a simple 'VERIFIED' or 'INVALID' response, once you ping the received data back to Paypal.

In my handler, I am doing a case sensitive string comparison for those two keywords, if either one of these known keywords is not found, then it is treated as an error.

<?php
  $fp = fsockopen ($socket_url, 80, $errno, $errstr, 10);

  if (!$fp){
     // SOCKET ERROR
     return false;
  }
  else {
         fputs ($fp, $header . $req);
         $is_ok = false;

         while (!feof($fp)) {
             $res = fgets ($fp, 1024);

             if (strcmp("VERIFIED",$this->ipn_response)==0) {
                //do something ...
             }
             // if the IPN POST was 'INVALID'
             else if (strcmp ($res, "INVALID") == 0) {
                 fclose ($fp);
                 return false;
             }
             else {
                echo "Unknown response from Paypal: $res";
                fclose ($fp);
                return false;
            }
         }

         fclose ($fp);
         return true;
   }
?>

My error message shows that I am receiving an 'HTTP/1.1 200 OK' response from Paypal.

Unknown response from Paypal:
'HTTP/1.1 200 OK'

Has the PayPal API changed, or am I doing something wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

卸妝后依然美 2024-09-19 16:01:28

PayPal 的响应位于 HTTP 响应正文中。您需要先处理 HTTP 标头,然后才能获取正文。或者,继续阅读行,直到找到空行,下一行将是正文。

PayPal's response is in the body of the HTTP response. You need to process the HTTP headers before you can get at the body. Or, alternately, just keep reading lines until you find a blank line, and the next line will be the body.

迷乱花海 2024-09-19 16:01:28

抱歉,我原来的回复措辞真的很糟糕:)

fgets 只是逐行读取,第一行是 HTTP 响应。但是,您的代码永远不会有机会继续阅读,因为在处理第一行后您会“出错”。

我倾向于用类似的东西替换你的 while 循环:

    while (!feof($fp)) {
         $res = trim(fgets($fp, 1024));

         if (strcmp($res, "VERIFIED")==0) {
            //do something ...
         }
         else if (strcmp($res, "INVALID") == 0) {
             fclose ($fp);
             return false;
         }
     }

Sorry, my original response was really badly worded :)

fgets is only reading line by line, the first line being the HTTP response. Your code never gives the opportunity to continue reading, though, as you 'error out' after the first line is processed.

I'd be inclined to replace your while loop with something like:

    while (!feof($fp)) {
         $res = trim(fgets($fp, 1024));

         if (strcmp($res, "VERIFIED")==0) {
            //do something ...
         }
         else if (strcmp($res, "INVALID") == 0) {
             fclose ($fp);
             return false;
         }
     }
溺渁∝ 2024-09-19 16:01:28

正如@Mike所说,你必须阅读整个正文 - 在你的情况下,你只是测试 VERIFIEDINVALID 是否出现在回复的前 1024 个字节中,这可能是标题。

顺便说一句,您不需要使用 fsockopen(),大多数人都这样做,因为 PayPal 提供了一个使用它的示例,以便它可以在旧的盒子设置中工作。带有 HTTP POST 上下文的 CURL 或 file_get_contents 就可以很好地完成工作,这是我为 phunction PHP框架

public static function PayPal($email, $status = 'Completed', $sandbox = false)
{
    if (preg_match('~^(?:.+[.])?paypal[.]com$~', gethostbyaddr($_SERVER['REMOTE_ADDR'])) > 0)
    {
        $url = ($sandbox !== true) ? '' : '.sandbox';
        $result = self::CURL('https://www' . $url . '.paypal.com/cgi-bin/webscr/', array_merge(array('cmd' => '_notify-validate'), $_POST), 'POST');

        if ($result == 'VERIFIED')
        {
            $email = strlen($email) * strcasecmp($email, $_POST['receiver_email']);
            $status = strlen($status) * strcasecmp($status, $_POST['payment_status']);

            if (($email == 0) && ($status == 0))
            {
                return true;
            }
        }
    }

    return false;
}

As @Mike said, you've to read the whole body - in your case you're just testing if VERIFIED or INVALID appears in the first 1024 bytes of the reply, which is probably the header.

By the way, you don't need to use fsockopen(), most people do because PayPal provides an example using it so that it works in old box setups. CURL or file_get_contents with an HTTP POST context will do the job just fine, here is an example I coded for the phunction PHP framework:

public static function PayPal($email, $status = 'Completed', $sandbox = false)
{
    if (preg_match('~^(?:.+[.])?paypal[.]com$~', gethostbyaddr($_SERVER['REMOTE_ADDR'])) > 0)
    {
        $url = ($sandbox !== true) ? '' : '.sandbox';
        $result = self::CURL('https://www' . $url . '.paypal.com/cgi-bin/webscr/', array_merge(array('cmd' => '_notify-validate'), $_POST), 'POST');

        if ($result == 'VERIFIED')
        {
            $email = strlen($email) * strcasecmp($email, $_POST['receiver_email']);
            $status = strlen($status) * strcasecmp($status, $_POST['payment_status']);

            if (($email == 0) && ($status == 0))
            {
                return true;
            }
        }
    }

    return false;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文