4

Web Payments 標準と HTML 変数を使用して、Web サイトを Paypal に統合することをテストしています。

IPN 通知を処理する単純な PHP スクリプトを作成しました。

Paypal のドキュメントによると、受信したデータを Paypal に pingすると、Paypal サーバーは単純な ' VERIFIED ' または ' INVALID ' 応答を返します。

私のハンドラーでは、これら 2 つのキーワードの大文字と小文字を区別する文字列比較を行っています。これらの既知のキーワードのいずれかが見つからない場合は、エラーとして扱われます。

<?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 OK」

PayPal API が変更されましたか、それとも何か間違っていますか?

4

3 に答える 3

2

PayPal の応答は、HTTP 応答の本文にあります。本文に到達する前に、HTTP ヘッダーを処理する必要があります。または、代わりに、空白行が見つかるまで行を読み続け、次の行が本文になります。

于 2010-08-04T15:31:11.963 に答える
1

@Mikeが言ったように、全体を読む必要があります。あなたの場合は、応答の最初の1024バイト(おそらくヘッダー)に表示されるかどうVERIFIEDかをテストしているだけです。INVALID

ちなみに、fsockopen()PayPalは古いボックス設定で機能するように使用例を提供しているため、ほとんどの人が使用する必要はありません。CURLまたはHTTPPOSTコンテキストを使用すると、問題なく機能します。これは、私がphunctionPHPフレームワークfile_get_contents用にコーディングした例です。

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;
}
于 2010-08-04T17:28:27.277 に答える
1

申し訳ありませんが、私の最初の応答は本当にひどい言葉でした:)

fgets は 1 行ずつ読み取るだけで、最初の行は 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;
         }
     }
于 2010-08-04T15:28:37.350 に答える