paypalのテスト環境で何度も『INVALID』判定を食らいましたので、その忘備録を記します。
paypalipnへのリクエストプログラムは、Paypal「PDT」「IPN」を使った決済とバックエンドの統合(2)を参考にさせていただきました。
<?php ing.com/mypage/' //PayPalシステムからポストを読み込み、「cmd」を追加 $req = 'cmd=_notify-validate'; foreach ($_POST as $key => $value) { $value = urlencode(stripslashes($value)); $req .= "&$key=$value"; } $header .= "POST /cgi-bin/webscr HTTP/1.0rn"; $header .= "Content-Type:application/x-www-form-urlencodedrn"; $header .= "Content-Length:" . strlen($req) ."rnrn"; $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30); //$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);使えなかった //$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);使えない //$fp = fsockopen("ssl://www.paypal.com", 443, $errno, $errstr, 30);//本番環境 // ポストされた変数をローカル変数に割り当て //$item_name = $_POST['item_name']; $item_number = $_POST['item_number1']; $payment_status = $_POST['payment_status']; $payment_amount = $_POST['mc_gross']; $payment_currency = $_POST['mc_currency']; $txn_id = $_POST['txn_id']; $receiver_email = $_POST['receiver_email']; $payer_email = $_POST['payer_email']; if (!$fp) { // HTTP ERROR } else { fputs ($fp, $header .$req); while (!feof($fp)) { $res = fgets ($fp, 1024); if (strcmp ($res, "VERIFIED") == 0) { // payment_statusがCompletedであることを確認 // txn_idが現在までに処理されていないか確認 // receiver_emailがお客様のPayPal主メールアドレスであることを確認 // payment_amountとpayment_currencyが正しいことを確認 // 支払いを処理 }else if (strcmp ($res, "INVALID") == 0) { } } fclose ($fp); ?> ?>
文字のエンコード設定
PayPalのサイトで(勿論、SandBoxでテストしているならSandBoxで)、設定を変えないとShift_JISになってしまうのですが、
「マイアカウント」
「個人設定」
と進み、「販売の設定」の欄にある「言語のエンコード」を選択して「ウェブサイトの言語」を「日本語」にします。
そして、「詳細オプション」に進みます。
この「詳細オプション」に落とし穴があって、
「エンコード方式」を「UTF-8」
「PayPalから送信されたデータと同じエンコード方式を使用しますか(IPN、ダウンロード可能なログ、メールなど)?」を「はい」
にすると、前の画面の「ウェブサイトの言語」の設定が何故か「西欧言語(英語を含む)」になってしまいます。
これに気づかずに、IPN通知をポストバックしてみたら、ものの見事にINVALIDとなってしまいました。
(UTF-8て日本語使えるのにね。3バイトとかの文字もあるけど)
そこで、先ほどの「詳細オプション」では、
「エンコード方式」を「Shift_JIS」
「PayPalから送信されたデータと同じエンコード方式を使用しますか(IPN、ダウンロード可能なログ、メールなど)?」を「いいえ。次のエンコード方式を使用します。」
その下のプルダウンで「UTF-8」を選択して「保存」とします。
参考記事PayPalのIPNでハマった
最終ポイント
しかし、上記を含め全て修正したつもりなのになぜかsandbox.paypal.comへのリクエストでINVALID判定。
最後に仕方なく、本番環境で(paypal.com)リクエストしたら、valided判定になりました。
なので、結論としては、paypalapiの最終チェックは、本番環境でないとわからないということでした。
sandboxで正しい回答が得られないときは、思い切って本番環境で確認してみてください。