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で正しい回答が得られないときは、思い切って本番環境で確認してみてください。