PayPalでダウンロード販売する法
個人でちょっとしたダウンロード販売を行いたいと思ったとき、便利な決済サービスが PayPalです。
・初期費用、登録審査など一切不要。個人でも簡単に登録できる。
・カード決済の手数料が安い。他のカード決済サービスと比較しても、かなり安い部類。
PayPalを使えば、誰でも簡単にカード決済付きネットショップが開設できる!
そう思って PayPalの仕組みを調べてみたところ、やはり実現することが難しい機能も幾つかありました。
PayPalの使い方については、あちこちのサイトにも書かれているので、ここでは要望の割に実現するのが難しいであろう、
・支払いデータ転送(PDT)
・即時支払い通知(IPN)
の使い方をメモしておきます。
いずれもの機能も、活用するためには PHP等で処理を行うページを作る必要があります。
※ここで説明している仕組み(IPN)を実現したのが「らくらくダウンロード」というサイトです。
※ >> http://www.easypay.jp/
※ 無料で利用できるので、まずはお試しあれ。(2010/07/01追記)
※また、誰でも簡単に設置できるカートも用意しました。
* jCart日本語版 >> [id:rikunora2:20100723]
※ この「らくらくダウンロード+jCart」で、本当に、誰でも、無料で、お手軽に
※ ダウンロードショッピングサイトができちゃいます! (2010/07/23追記)
PayPalを用いてダウンロード販売サイトを作ろうと思ったとき、まず直面するのは、
「PayPalで決済を済ませたお客さんを、ダウンロードのページに導くことができない」
という問題です。
通常、インターネット上のダウンロード販売は、こんな流れになっています。
[1:買い物かご] -> [2:カード決済] -> [3:ダウンロードページ]
PayPalの場合、[1:買い物かご]は自分のホームページ、[2:カード決済]はPayPalサイト、ということになるでしょう。
問題となるのは、PayPalの場合、[2:カード決済] -> [3:ダウンロードページ] の道筋をどうするか、ということです。
PayPalの決済を終えた先に、「ありがとうございました」ページを用意することまではできます。
しかし、その際に、何を買った、どのお客さんが「ありがとうございました」ページに来たのか、簡単に区別することができないのです。
これだと(自動的な方法で)ダウンロード販売を実現することができません。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
* PDT -- Payment Data Transfer
ダウンロード販売には欠かせない、[2:カード決済]で決済したお客さんの情報を [3:ダウンロードページ] にまで持ってくる機能、
それが「支払いデータ転送(PDT)」です。
通常、PayPalにアカウントを作った直後の状態では、この PDT機能は有効になっていません。
PDTを有効にするには、PayPalの管理画面にログインして、
[マイアカウント]->[個人設定]->[販売の設定]->[ウェブ ペイメントの設定]
に行って、次の設定を行います。
・自動復帰: オン
・復帰URL: ここに[3:ダウンロードページ]となるURLを入力します。
たぶん https://hoge.moge.co.jp/download.php みたいになると思います。
・支払いデータ転送: オン
「支払いデータ転送」の下に、IDトークン: という長い暗号のような文字列が出ています。
この「IDトークン」は、DTPで不正なアクセスを拒否するために使用します。
肝心のダウンロードページですが、PayPalからの決済情報を受け取るサンプルが、以下のURLに用意されています。
* Code Samples -- Payment Data Transfer
>> https://www.paypal.com/us/cgi-bin/webscr?cmd=p/xcl/rec/pdt-code
このサンプルを元に開発するのが早いと思います。
サンプルとほとんど同じものですが、以下に私が試したPHPソースを張っておきます。
// 決済完了、ダウンロード // PDTの仕組みを使ってPayPal決済情報を受け取る. // 内容については責任持たないので、利用は自己責任で。 // read the post from PayPal system and add 'cmd' $req = 'cmd=_notify-synch'; $tx_token = $_GET['tx']; $auth_token = "* サイトで発行されるIDトークンをここに貼り付ける *"; $req .= "&tx=$tx_token&at=$auth_token"; // post back to PayPal system to validate $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; $fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30); // テストサイト // $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30); // 本番 // $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30); // できれば HTTPS にした方が、セキュリティが高まる. if (!$fp) { // HTTP ERROR echo "ERROR: HTTP error, [" . $errno . "] " . $errstr . "\n"; exit(1); } fputs ($fp, $header . $req); // read the body data $res = ''; $headerdone = false; while (!feof($fp)) { $line = fgets ($fp, 1024); if (strcmp($line, "\r\n") == 0) { // read the header $headerdone = true; } else if ($headerdone) { // header has been read. now read the contents $res .= $line; } } // parse the data $lines = explode("\n", $res); $keyarray = array(); if (strcmp ($lines[0], "SUCCESS") == 0) { for ($i=1; $i毎度ありがとうございました。
\n"; var_dump( $keyarray ); // どんなパラメータが来るのか、ダンプしてみる. ?>;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
* IPN -- Instant Payment Notification
とりあえず、上の PDTでダウンロード販売は実現できるのですが、
これだけだとお客さんがダウンロードに失敗したときや、決済の直後にブラウザを切ってしまい、
ダウンロードページに行かなかったときに、連絡を行うことができません。
そこで、たとえお客さんが途中でブラウザを切ってしまっても、確実に決済完了した信号を受け取る仕組みが必要となります。
それが、「即時支払い通知(IPN)」です。
IPN というのは、お客さんが PayPalの決済を行ったことを、直接ショップにお知らせする機能です。
* 即時支払い通知(IPN) Instant Payment Notifications
>> https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro
なので、IPNのお知らせを自動的に受け取れば、次のような流れでダウンロード販売が実現できます。
お客さん [1:買い物かご] -> [2:カード決済] -> (ここでお客さんがブラウザを閉じた)
ショップ ->[4: IPNお知らせを受信] -> [5: お客さんにメールを送る]
お客さん ->[6: メールを受け取る] -> [7: メールの指示に従って、ダウンロードページへ]
それでは、[4: IPNお知らせを受信]は、どのようにすれば良いのでしょうか。
IPNお知らせは、http、つまり Webへのアクセスという形でやってきます。
なので、IPNお知らせを受信するための、専用のWebページを作る必要があります。
このページに、IPNお知らせを受け取るための PHPで書かれたサンプルが用意されていますので、
まずはこのサンプルをコピーしてきて修正するのが早道でしょう。
* Implementing an IPN Listener
>> https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_admin_IPNImplementation
[4: IPNお知らせを受信] -> [5: お客さんにメールを送る]
というところは PHPなどで自作する必要があります。
サンプルとほとんど一緒なんですけど、以下に、IPNお知らせ受信ページのPHPソースを張っておきます。
以下のコードでは、受信した情報をログファイルに書き出しています。
// PayPalのIPN機能を受けるハンドラー // これによって決済完了を知ることができるのだ. // 内容については責任持たないので、利用は自己責任で。 define("IPNLOGFILE", "* ここにログファイル名を書く *"); $PAYPAL_SITE = "www.paypal.com"; // 本番サイト // $PAYPAL_SITE = "www.sandbox.paypal.com"; // テストサイト // Read the post from PayPal and add 'cmd' $req = 'cmd=_notify-validate'; if(function_exists('get_magic_quotes_gpc')){ $get_magic_quotes_exits = true; } // Handle escape characters, which depends on setting of magic quotes // POSTで受けた値を、そのまま GET形式に書き直す => これをPayPal側のサイトに返す. foreach ($_POST as $key => $value){ if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1){ $value = urlencode(stripslashes($value)); } else { $value = urlencode($value); } $req .= "&$key=$value"; } // Open LogFile $log = fopen( IPNLOGFILE, "a"); // 追記オープン if( ! $log ){ print "ERROR: Open Log File, " . IPNLOGFILE ; exit(1); } // Post back to PayPal to validate $header = "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; $fp = fsockopen( $PAYPAL_SITE, 80, $errno, $errstr, 30 ); // PAYPAL_SITE の 80 番ポートに接続、タイムアウトを30秒に設定 // エラーがあれば $errno, $errstr に入る。 // Process validation from PayPal if (! $fp) { // HTTP ERROR fwrite( $log, "ERROR: Cannot open ". $PAYPAL_SITE . " [". $errno . "] " . $errstr ); exit(1); } fputs( $fp, $header . $req ); // こちらから応答を返す. // そして、その結果を待つ. while( ! feof( $fp ) ) { $res = fgets( $fp, 1024 ); // その応答結果を受け取る. // 戻りは "VERIFIED" か "INVALID" のいずれかになる. // 成功の場合. if (strcmp ($res, "VERIFIED") == 0) { // * TODO * ここでいろんなチェックを行うこと. // Check the payment_status is Completed // Check that txn_id has not been previously processed // Check that receiver_email is your Primary PayPal email // Check that payment_amount/payment_currency are correct // POSTパラメータを書き出す. $text = ""; foreach ($_POST as $key => $value){ $text .= $key . " = " .$value ."\n"; } fwrite( $log, $text ); } // 失敗の場合、とにかく値をログに書き出す. else if (strcmp ($res, "INVALID") == 0) { // POSTパラメータを書き出す. $text = ""; foreach ($_POST as $key => $value){ $text .= $key . " = " .$value ."\n"; } fwrite( $log, $text ); } // else{ // 内容以外の行は読み飛ばす. // } } fclose( $fp ); fclose( $log ); exit( 0 );
上の IPNお知らせを受信ページが完成したら、PayPalから受信ページに向かって信号を送るように設定します。
PayPalの管理画面にログインして、
[マイアカウント]->[個人設定]->[販売の設定]->[即時支払い通知の設定]
に行って、「通知URL」という項目に、上で作った IPNお知らせを受信ページのURLを入力します。
そして「IPNメッセージを受信する(有効)」にチェックを入れましょう。
これで、PayPal上で決済が行われるたびに、自作のIPNお知らせを受信ページに向かって、お知らせが送られてくるはずです。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
* 開発者用サイト -- Sandbox
上のような仕組みを実際に試してみるには、クレジットカードを使って何かお買い物をしなければなりません。
それはやってられないよ、というときのために、PayPalでは開発専用のテストサイトを用意しています。
* PayPal sandbox -- 開発者用サイト
>> https://developer.paypal.com/
開発するには、こちらのサイトのアカウントを取得しましょう。
IPN の仕組みをテストするには、
[左側メニュー] -> [Test Tools] -> [Instant Payment Notification (IPN) Simulator.]
ここから、IPNお知らせ信号を擬似的に送ることができます。
[IPN handler URL] に、自作のお知らせを受信ページを入力して、
[Transaction type] は、適当なもの、eCheck - complete とかを選んで、後は見よう見まねでやってください。
PDT, IPNの情報がまとまって書いてあるページは、意外に少なかった。(探し方が悪かったのかもしれないが)
例えば、ここに載っていた。
* Paypal「PDT」「IPN」を使った決済とバックエンドの統合(2)
>> http://blog.katsuma.tv/2007/06/paypal_pdt_ipn_code.html