paypalを使って電子書籍のダウンロード販売

2016/5/19 [16:17:41] (木) 天気

電子書籍元年が何度もきたおかげで、電子書籍(デジタルコンテンツ)のダウンロード販売がDRMもついてAmazonや楽天kobo、iBookstore、KADOKAWA☆BOOKWALKERに並べることができる時代となった。


また、電子書籍専門というわけではなく、デジタルコンテンツをダウンロード販売できるサイトも百花繚乱雨後筍で、コンテンツさえ用意できれば個人で簡単に販売ができる。


「デジタルコンテンツをダウンロード販売できるサイトを比較してみた」

http://writing-san.blog.jp/archives/32017213.html


また、ワードプレスにはダウンロード販売のためのプラグインまであって、販売チャンネルの選択肢はたくさんある。


「Easy Digital Downloads - ダウンロード販売サイトを簡単に作れるWordPressプラグイン」

http://netaone.com/wp/easy-digital-downloads/


集客力販売力、販売手数料や手間ひまを考えて自分に合うところにコンテンツを置けばいいし、そうすれば販売ページへのURLや購入ボタンをSNSや自分のサイトに貼りつけて告知できる。



ぶっちゃけ、わざわざ自分でダウンロード販売の仕組みとか作るのは時間と労力の無駄なのでオススメしない。

面白そうだ、という好奇心自己満足。それと、もしかすると、何らかの事情で他社サービスにコンテンツを置くわけにはいかないような場合に。


てことなので、以下はわたしの技術メモ。備忘録。

内容的には2010年の雑記とPayPalとのやり取りなどはほぼ同じ。

「paypalと電子書籍のダウンロード販売(その1)」

http://t2aki.doncha.net/?id=1277017233

「paypalと電子書籍のダウンロード販売(その2)」

http://t2aki.doncha.net/?id=1277130006

今回の雑記では自サバ側のこともメモしておく。



【じぶんちでの設定】

コンテンツをサーバーの所定のフォルダにアップロード。

サーバーのデータベースにコンテンツの商品登録。ここで商品にIDを付ける。

以下3つのスクリプトを用意

・ご購入ありがとうございますページのスクリプト

・IPN受信&データベース登録用のスクリプト

・ダウンロード用スクリプト



【PayPalでの購入ボタン作成・各種設定】

「トップ」→「販売ツール」のメニューにある「売り手の設定」から


→「PayPalボタン」

[今すぐ購入]サンプルボタンあたりを雛形に「ボタンの編集」で商品名や値段などを入れる。ここではオプションの商品ID(=データベースで決められたID)を入れるのを忘れずに。

ボタンを作ったら「コードをコピー」して自分のサイトの購入ボタンを設置したいところにコードをペーストする。


→「ウェブサイトの設定」(ウェブペイメントの設定)

・ウェブペイメントの自動復帰「オン」

・復帰URL:ご購入ありがとうございますページのURLを記入

・支払いデータ転送「オン」※IDトークンをコピーしておく

・暗号化されていないウェブペイメントの受領拒否「オフ」

・PayPalアカウントオプションサービス「オン」

・連絡先電話番号「オフ」

・エクスプレスチェックアウトの設定「いいえ」


→「即時支払い通知」(IPN)

・通知URL:IPNを受信するスクリプトのURL

・メッセージの配布:有効


→「PayPalボタンの言語コード化」

・「詳細オプション」→「UTF-8」



【PayPalとのやりとり】

image

ユーザーの動きは以下の3つ。

1)ユーザーがオレオレサーバーの購入ボタンをクリックすると

2)PayPalの決済ページに飛んでそこでお支払い

3)お支払いが終わるとオレオレサーバーの購入ありがとうございましたページに戻ってくる。


ユーザーのお支払い終了と同時にPayPalからオレオレサーバーに購入データが飛んでくる。


購入データは以下の2種類。

データを取得して解析するためのサンプルコードがPayPalに用意されていて、そのまんま利用させてもらう。


3)PDT(Payment Data Transfer)


図では赤い矢印がひとつだけど、データのやりとりの実際は。

→PayPalからオレオレサーバーへ

・ユーザーが購入ありがとうございますページにリダイレクトされてくる時に、トランザクションを持ってアクセスしてくる

→オレオレサーバーからPayPalへ

・トランザクションと管理ページの「支払いデータ転送」の項目に記載されているIDトークン、コマンドをPOSTでPayPalにリクエスト

→PayPalからオレオレサーバーへ

・POSTした内容が正しければ一行目に「SUCCESS」と書かれたデータを返してくる


このPDTデータは

SUCCESS

first_nameJane+Doe

lst_name=Smith

payment_status=Completed

など、1行にひとつ「ネーム=バリュー」形式、NVP形式のデータとなっている。


※ユーザーが支払いを終えて待たずにすぐブラウザを落としたりするとデータ取得できない。購入ありがとうございますページにリダイレクトされてやってきて初めてデータのやり取りが生じる。


PDTデータ取得&解析のサブルーチン

※HTMLデコードと文字コードをutf8にしているところ以外はサンプルコードのまんま。


sub paypal_pdt{
    my $self = shift;
    my $args = shift;

    return if( ! $args->{tx} );

    my $paypal = ’https://’ . $self->{paypal}->{server} . $self->{paypal}->{gate};
    my $query  = join(’&’, "cmd=_notify-synch", "tx=$args->{tx}", "at=$self->{paypal}->{auth_token}");

    my $ua  = new LWP::UserAgent;
    my $req = new HTTP::Request("POST", $paypal);
    $req->content_type("application/x-www-form-urlencoded");
    $req->content($query);
    my $res = $ua->request($req);

    return if($res->is_error);

    my @response = split("\n", $self->html_decode($res->content) );
    my $status = shift(@response);
    my %tx;
    if($status eq "SUCCESS"){
        foreach( @response){
            my ($key, $val) = split("=", $_);
            $val = Encode::decode(’utf8’, $val) if ! Encode::is_utf8($val);
            $tx{$key} = $val;
        }
        return \%tx;
    }
    elsif( $status eq ’FAIL’){
        return;
    }
    else{
        return;
    }
}


PDTデータのpayer_emailやitem_nameなどを「ご購入ありがとうございます」ページの「~様」や「~をご購入いただきありがとうございました」などの個別の表示に使う。

PDTデータのitem_number(商品ID)でダウンロード商品なのか、別の商品なのかを判定して、ダウンロード商品の場合はダウンロードURLを表示する。ダウンロードURLはユーザーのemailやtransactionidなど一意のものから作成している。



4)IPN(Instant Payment Notification)

ユーザーから見える言わば表側のPDTと違って、こちらは裏側。

ユーザーがお支払いを終えると管理ページで指定したURLにデータが飛んでくるので取りこぼしがない。

PDTはユーザーに見せるご購入ありがとうございますページに使う程度で、オレオレサーバーのデータベースに購入の記録を残すためにはこちら、IPNを使う。


図では赤い矢印がひとつだけど、データのやりとりの実際は。

→PayPalからオレオレサーバーへ

・購入データが送られてくる。いわゆるWEBのフォームデータで「&」で繋がれた「ネーム=バリュー」形式

→オレオレサーバーからPayPalへ

・送られてきた購入データにコマンドをひとつつけてPayPalにPOSTする

→PayPalからオレオレサーバーへ

・「VERIFIED」か「INVALID」か一行返ってくる。これ以外は調べる必要があるらしいが滅多になさそうだし、PayPalの管理画面で確認すれば良い。


IPNデータ取得&解析のサブルーチン

エラーはIPNのデータをつけてメールするように。

VIRIFIED(データが正しい)場合でも以下の4点を確認する。

・支払いのステータス「payment_status」が完了「Completed」であることを確認

・すでに完了した取引の悪用防止のために「txn_id」が過去のものと重複していないことを確認

・不正アカウントに支払いされないように「receiver_email」がPayPalアカウントに登録したメールアドレスであることを確認

・価格が変更されていないか確認(商品IDなども)

確認できたらオレオレサーバーのデータベースに必要情報を登録して、ユーザーにお礼とダウンロードURLを書いたメールを送信する(自分にも同じものを送信)


※データ確認の部分やメールの部分以外はサンプルコードのまんま。


sub paypal_ipn{
    my $self = shift;
    my $args = shift;

    my ($s,$ms,$h, $d,$m,$y) = localtime(time); ++$m; $y+=1900; my $ymd = sprintf qq{%s/%02d/%02d [%02d:%02d:%02d]}, $y, $m, $d, $h, $ms, $s;
    my $query;
    read (STDIN, $query, $ENV{’CONTENT_LENGTH’});
    if(! $query ){
        print qq{Content-type:text/plain\n\n};
        return;
    }
    $query .= ’&cmd=_notify-validate’;

    my $ua = new LWP::UserAgent;
    my $paypal = ’https://’ . $self->{paypal}->{server} . $self->{paypal}->{gate};
    my $req = new HTTP::Request("POST" , $paypal);
    $req->content_type("application/x-www-form-urlencoded");
    $req->content($query);
    my $res = $ua->request($req);

    my %ipn;
    my @pairs = split(/&/,$query);
    my $count = 0;
    foreach my $pair ( @pairs ){
        my ($key, $val) = split(/=/,$pair);
        $val =~ tr/+/ /;
        $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
        $val = Encode::decode(’utf8’, $val) if ! Encode::is_utf8($val);
        $ipn{$key} = $val;
        $count++;
    }

    my $err;
    if($res->is_error){
        $err = sprintf qq{%s\nHTTP ERROR: %s\n\n%s\n}, $ymd, $res->status_line, $query;
    }
    elsif( $res->content eq ’VERIFIED’){
        my $msg = $self->update_ipn({ipn=>\%ipn});
        if($msg){
            $err = sprintf qq{[VERIFIED and Error]%s\n%s\n\n%s\n}, $ymd, $msg, $query;
        }
        else{
            my $body = sprintf(qq{
%s様
「%s」ご購入ありがとうございます。

 %spaypal/%s?download=%s
こちらのURLからダウンロードしてください。

・ダウンロード回数は%s回
・ダウンロード期間は%s日
  となっています。

よろしくお願いいたします。
});
            $self->send_paypal_download({
                addr=>$ipn{’payer_email’},
                subject=>’【’ . $ipn{’item_name’} . ’】ダウンロードURLのお知らせ’,
                body=>$body
            });
            $self->send_paypal_download({
                addr=>$ipn{’root_email’},
                subject=>’【’ . $ipn{’item_name’} . ’】ダウンロードURLのお知らせ’,
                body=>$body
            });
        }
    }
    elsif( $res->content eq ’INVALID’){
        $err = sprintf qq{[INVALID]%s\n\n%s\n}, $ymd, $query;
    }
    else{
        $err = sprintf qq{[UNKNOWN ERROR]%s\n\n%s\n}, $ymd, $query;
    }
    if($err){
        $self->send_alert_mail({
            addr=>$self->{root_email},
            subject=>’[PAYPAL]IPN ERROR!!’,
            body=>$err
        });
    }
    print qq{Content-Type: text/plain\n\n};
    exit;
}



【ダウンロードについて】


ダウンロードはダウンロード用のスクリプトがファイルを返すようにしてある。

たとえば、わたしが自分だけで作ったコンテンツなんかはどうでもいいんだけど、表紙が依頼原稿だったり、アンソロジーでほかの人の原稿が入っていたりするとそうもいかない。回数や期間を無制限にするわけにはいかない。

なので、ファイルの置き場所=URLをそのままユーザーにお知らせできない。


ダウンロード用のスクリプトを噛ませて

・ダウンロードのURLは購入者ごとに違うものを作る

・ダウンロード回数を制御する

・ダウンロード期間を制御する

といったことを仕込んだ。


また、ダウンロードごとにIPやUserAgentを記録すれば、不正なアクセスやダウンロードできない事故などの問題解決にも役立つ。



以前の雑記にも書いたように、PayPalは管理ページに記録が残ってるし取引が生じたらいちいちメールも飛んでくるので、致命的な問題にはならないはず。サポートもびっくりするというか恐縮するぐらいに厚い。


残念なことに(法律的に?)日本では単純にクレジットカードだけで支払いはできなくなった(ペイパルへのアカウント・会員登録が必須となった)けど、個人での少額決済に手軽に使えるので助かるなあ。

出家で人生ロンダリング

2014/5/19 [17:31:48] (月) 天気

Twitterで見かけて、へえええと感心したというか驚いたのでメモしておく。


NHKのクローズアップ現代でやっていたらしい。出家させて戸籍を書き換えて逃げ切る、んだそうだ。

https://twitter.com/Lawcojp/status/468305308117237760

これはもう

「現代の坊主丸儲け」

「これが本当の駆け込み需要」

というネタでひとつよろしくお願いしたい。


みんなの党の渡辺元代表の「熊手」も同じか…。



杉良太郎が遠い目をして、そっから先は寺社奉行だからよ、おいらたちには手が出せないのさ、と。…んで、深々と涙ながらに頭を下げる娘が走り去るんだなあ【涙で滲んでテレビが見えない】



[05/19 18:01:29] 追記。

http://www.nhk.or.jp/gendai/kiroku/detail02_3496_all.html

↑クローズアップ現代の該当回ページ。なるほどなあ。


[更新]2014-05-24 12:28:22

究極の表現・天才芸

2014/5/19 [09:30:43] (月) 天気

桂枝雀という天才落語家がいた、という話をよく聞く。

わたしは落語マニアというワケではなく、大阪にいた頃や大学時代にTVで落語がかかってたら見る程度で落語について何か蘊蓄を語るようなこともできない。


Wikipediaには

「枝雀の顔を見ただけであー、おもろかったと満足していただけるような芸人になりたい。」

という発言が載っている。

わたしがTVのバラエティ番組だかで見た記憶はちょっと違っていて。もう少し具体的。


「舞台の袖から出て行ってですね、座りますでしょ、お客さんが見てるわけで、わたしがそこで「にかーっ」と笑うんです、そうするとお客さんもなんや面白くて「にかーっ」と笑うんです、それが究極の落語といいましょうか」


という話だったかな。

天才で理論派の枝雀がこんな内容のことを嬉しそうにしゃべっていた。


いやだからどうしたということじゃないんだけど。

ネットは本性が丸出しになる『ネットは丸裸メディア』やその周辺の記事を読んでなんか違和感あるなあと思ったんだけどうまく言葉にならないので、思い出したことをそのまんま。

人格とか本性って言語化できることがすべてなのかとか、テキストからよみとれることだけじゃないよなあとか…うーん、でも、たぶん関係のない話か。

桂枝雀名演集: 代書 つぼ算 (第1巻) (小学館DVD BOOK)

『桂枝雀名演集: 代書 つぼ算 (第1巻) (小学館DVD BOOK)』

小学館

告知認知周知

2011/5/19 [19:37:28] (木) 天気

読書記録・蔵書管理のサイトといっても、ひとりの本棚じゃ面白くない。以前のサイトは300人ほど会員がいたので、バリエーションもそれなりに。

でも、今回の全面リニューアル、URL変更では、現状まだ1/10の30人弱。2006年に公開した時点では、まだこの手の本、読書に特化したサイトというのは3つか4つ程度だったので、放置していてもバラバラと登録してくれるひとはいた。でも、今は同じようなサイトが溢れている。それも機能も豊富で使いやすいものばかりじゃありませんか。いくつか覗いてみたところ、みんな良く出来てるんで感心するばかり。http://doncha.net/ は、できることが少ない、言葉を変えればシンプルさだけが、ほかよりもいいところかな、と。いいんだか悪いんだかビミョーな判定だ。


しょうがないんで、Yahoo知恵袋とかOKwaveあたりに「回答者として書き込みつつ、URLを晒してみよう作戦」を。

うーむ。でも、Q&Aサイトってほとんど初めてみたけど、どうなんだろう。本気なのかなあ。ひとつのQAを、いったいどのぐらいのひとが見てるんだろう。こういうのって枯葉も山の賑わい、量は質に転化する、のが勝負。人数が少ないんじゃレベルも知れてる。これなら2ちゃんをみてる方が回答早いよなあ、というのがちらほら。

むずかしいんだろなあ。


メールアドレスを入れるだけ。登録は簡単なので、ここをご覧の数少ないみなさま、ぜひ登録を!。やってみると意外に面白いですよー。


どんなサイトなのか

http://doncha.net/about.pl

ナニができるの?

http://doncha.net/about.pl?c=help


[更新]2012-06-19 16:55:57

ロシアンライカ

2009/5/19 [21:55:15] (火) 天気

FED2。シャッター幕のシワ・ひび割れ・ピンホール。スーパーラバースプレーでタッチアップしたけど、やっぱり無理。

Zorki-4。シャッター速度のノブがスカスカで抵抗なく緩んでる。そのまま使おうと思ったけど、カメラを動かすだけでシャッター速度が変わるんじゃ無理。


てことで2台とも入院。

ヤフオクのFED2の方は修理を引き受けてくれそなところを探すところからで、結局、鈴木商店が頼めそう…仮見積りを出してもらって、本体を送って本見積もりがこれから。うううむ。仮見積り28850円てのは痛いぞ、ちくそお。こづかい分割返却ぢゃん。King-2で買ったばかりのZorki-4は保障期間が一年あるはず、なので送ってみる。

ヤフオクで9440円だったFED2が高くついたなあ。修理や保証のつく店で買えば15000円前後。保証もないオークションで買うべき類のカメラじゃなかった。


明日は朝からバリウムだ。


[更新]2026-02-02 08:40:08

<<2026/05>>
     12
3456789
10111213141516
17181920212223
24252627282930
31

【最近の10件】

日常読書映画アニメゲーム健康料理グルメカメラ写真ネタ仕事パソコンインターネットperlEPUB3電子書籍ActivityPub
検索: