ひまつぶし雑記帖

HTTP Signatureをlolipopレンタルサーバーで作成

2023/8/22 [09:42:59] (火) 天気

ActivityPubでPOSTするには電子署名が必要。
というエントリを書いたけど、WEBでサーバー同士でやりとりしたり、WEBサービスのAPIを利用したり、電子署名が必要なのはActivityPubに限らず。

ちらほら書いてきたように、lolipopレンタルサーバーにはperlで電子署名をする時によく使われるモジュール「Crypt::OpenSSL::RSA」がインストールされていない。
ということは。lolipopではHTTP Signatureを作ることができない「Cryptが使えないんじゃ話にならない」ということになる。

しょうがないんで、ローカルにcpanから「Crypt::OpenSSL::RSA」をインストールして、ActivityPubにPOSTする時はローカルのスクリプトを使う、という急場しのぎ。
これはこれで、投稿するのにひと手間あった方が事故も起こさなくていいかな、と思ってやってたんだけど、やっぱりサーバー上だけでやれるならラクちんなことは確か。

なもんで、グーグル先生にお願いしてみたら
「Crypt-Perl-0.38」https://metacpan.org/pod/Crypt::Perl
↑pure perlのCryptモジュールがあった。

インストール時にコンパイルが必要なモジュールはOSやファイル構成、環境に依存するけど、PurePerlというのはperlだけで作られているので、perlさえあればサーバーにそのままアップロードして使える。

さっそくダウンロードして展開。テストスクリプトで試したところ、依存関係で必要なモジュールがあったのでそいつらもダウンロードして展開。

Class-Accessor-0.51
Bytes-Random-Secure-Tiny-1.011
Convert-ASN1-0.34
Crypt-Format-0.12
(あと、たぶん以前amazonのAPIがらみでインストール済みのpure perlのDigest::SHAも必要)
当然ながら(?)これらのモジュールもpure perlなので、コンパイル不要、展開するだけで使える。

サーバーの適当なところ、例えば「lib」というディレクトリを作って展開したファイル群をアップロードするだけ。
lib/Bytes/
lib/Class/
lib/Convert/
lib/Crypt/ 
スクリプトで use lib 'lib' などとやればlolipopレンタルサーバーでもCrypt RSAが使えるようになる。

いや。ぶっちゃけ。これらモジュールの作者のみなさんには大感謝。大袈裟じゃなく狂喜乱舞小躍りだった。ほんとうにありがとうございます。
マジperl使いすげー。perl話者が減ってるだろう昨今、凄腕のperl使いはワシントン条約で保護すべき存在。

使い方は「 RSAモジュールで公開鍵と秘密鍵 」とほぼ同じ。

秘密鍵を使う
my $privatekey = Crypt::Perl::RSA::Parse::private($private-pem);
公開鍵を使う
my $publickey  = Crypt::Perl::RSA::Parse::public($public-pem);

Signatureを作る。

my $sign = $privatekey->sign_RS256($sign-str);
encode_base64($sign, "");


Signatureを検証する。

my $decoded = decode_base64($sign);
$publickey->verify_RS256($sign-str, $decoded);



あとは。
こうすると、思いつきから投稿放流までが直結するので、事故を起こさない自制心が必要となるです、はい。
image

»電子書籍制作代行についてはこちら

ActivityPubを使ってFediverseにたどり着く

2023/7/12 [02:17:04] (水) 天気

いや、なんのこっちゃだけど。
2023年、ツイッター亡き後の世界となった。ネット空間には祖国を奪われた難民たちで溢れかえり…というB級サイバーパンクSFの設定。

そこで再評価されることになった、実は古より存在するFediverseというネットの連合空間。ActivityPubという共通の言語で繋がるネット世界、ということになった。

てことで、「いっちょかみ」できるかなあ、とここ数日あれこれ検索しまくって試して、とりあえずmastdonで検索して仲間として検索結果に出るところまではたどり着いた。
image 
最小限のActivityPub、いわゆるお一人様で、もちろん喋ることもフォローなどアクションをすることもできない。ただ、連合空間に顔を出した、だけなんだけど。

「mastodonなどに認識してもらえる」のがまずはゴールだったんで、ここまでやったことをメモ。
(すべてはネットで検索して得られたもので、先人たちに大感謝)

ActivityPubに参加するため用意するもの
サーバーやドメインをもっていることが前提。わたしはいつものlolipopサーバー。

どうやら以下の5つがあればActivityPubに顔を出すことはできる、っぽい。
nodeinfo(json)
まず最初サーバー情報のありかをこれで返す。

{                                                                                                                                                           
    "links":[
    {
        "rel": "https://nodeinfo.diaspora.software/ns/schema/2.1",
        "href": "https://tokoroten.doncha.net/nodeinfo/2.1"
    }
    ]
}



nodeinfo2.1(json)
サーバーの情報、でいいのかな。ここにGETでアクセスされて、ウチはactivitypubやってますよ、ユーザーは1人ですけどね、というのを返す。

{                                                                                                                                                            
  "openRegistrations": false,
  "protocols": [
    "activitypub"
  ],
  "software": {
    "name": "tokoroten",
    "version": "0.1.0"
  },
  "usage": {
    "users": {
      "total": 1
    }
  },
  "version": "2.1"
}



host-meta(xml)
webfingerのURLを返す。uriは検索対象のユーザー名の文字列に置換される。

<?xml version="1.0"?>                                                                                                                                        
<XRD xmlns="https://docs.oasis-open.org/ns/xri/xrd-1.0">
<Link rel="lrdd" type="application/xrd+xml" template="https://tokoroten.doncaha.net/.well-known/webfinger?resource={uri}" />
</XRD>



webfinger(json)
host-metaで得られたwebfingerのURLにGETでアクセスされるのでユーザー情報のエンドポイントを返す。

具体的にはこんなGETリクエストが飛んでくる。
https://tokoroten.doncaha.net/.well-known/webfinger?resource={uri}

https://tokoroten.doncaha.net/.well-known/webfinger?resource=@t2aki@tokoroten.doncha.net

{                                                                                                                                                            
  "subject": "acct:t2aki@tokoroten.doncha.net",
  "links": [
    {
      "rel": "self",
      "type": "application/activity+json",
      "href": "https://tokoroten.doncha.net/t2aki"
    }
  ]
}



とりあえず確認するには、
「WebFinger」https://webfinger.net/
↑たとえばこんなページがあるので、ここの検索窓にユーザー名を入れて、以上の情報が表示されたらwebfingerは正しく設定されている。

actor(json)
webfingerで取得したユーザーのURLにアクセスするとこの情報を返す。

{                                                                                                                                                            
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1"
  ],
  "id": "https://tokoroten.doncha.net/t2aki",
  "type": "Person",
  "url": "https://tokoroten.doncha.net/t2aki",
  "inbox": "https://tokoroten.doncha.net/t2aki/inbox",
  "outbox": "https://tokoroten.doncha.net/t2aki/outbox",
  "followers": "https://tokoroten.doncha.net/t2aki/followers",
  "following": "https://tokoroten.doncha.net/t2aki/following",
  "name": "t2aki",
  "preferredUsername": "t2aki",
  "summary": "@t2aki@tokoroten.doncha.net",
  "icon": {
      "type": "Image",
      "mediaType": "image/jpeg",
      "url": "https://tokoroten.doncha.net/images/prof-image.jpg"
  },
  "pubKicKey": {
      "id": "https://tokoroten.doncha.net/t2aki#main-key",
      "owner": "https://tokoroten.doncha.net/t2aki",
      "publicKeyPem": "-----BEGIN PUBLIC KEY-----\n略==\n-----END PUBLIC KEY-----",
      "type": "Key"
  }
}



nodeinfoやhost-metaはわかってないまま設置。
たぶん、webfingerでユーザー情報のURLを返して、そのURLにアクセスするとユーザー情報を得ることができますよ、というやりとりがあればまずは第一関門突破だと思われる。

HTTPでリクエストの投げ合いをして相互理解を深める。WEBの基本。

と、わかったようなことを書いたけど、ここにいたるまでハマりまくった。

サイトの構成をどうすればいいのか、そもそもそこから。
結論。考える必要はまったくなかった。
ActivitiyPubはディレクトリ構造とか拘束しないというか全然関係ない。全部jsonやxmlの設定ファイルでリクエストに返答できればいいだけだった。

アクセスされて、ActivityPubを構成するファイルを返す時のヘッダは以下がMUST

Content-Type: application/activity+json; charset=utf-8


てことは動的にヘッダをつけて返答する必要があるのか、ということで、スクリプトで対応。そのために.htaccessのrewriteruleで振り分けることにした。※1

.htaccess

RewriteEngine On                                                                                                                                             
RewriteCond %{QUERY_STRING} ^resource=(.*)$
RewriteRule webfinger.* script-finger%1 [L]
RewriteRule nodeinfo$ script-nodeinfo0 [L]
RewriteRule nodeinfo/2\.1$ script-nodeinfo [L]
RewriteRule host-meta$ script-hostmeta [L]
RewriteRule t2aki$ script-actor [L]


ここでのハマり。
apacheのrewriteruleはそのままだと「クエリを含まない」
fingerはresourceというクエリをつけてやってくる。そのクエリが分からないんじゃ何を求められてるのかわからない。それを解決するにはRewriteCondでクエリを判定させてやれば良い、てことにたどり着くのに2時間弱。

この先、フォローしたり投稿したりするには公開鍵秘密鍵で署名する必要があって、わたしの脳みそで理解できるレベルではない。そもそもlolipopではCrypt::OpenSSL::RSAのモジュールが使えないのでないものねだり。

手元、ローカルで作って手作業で鍵を作ってリクエストを投げる、ということを考えるしかなさそう。それもHTTPのヘッダ構成を調べる必要があって、高いハードルを見上げすぎて首を痛めるレベル。
とはいえ、せっかくだし、もう少し頑張ってみるかなあ。

※1
検索していてビックリしたのが静的ファイルだけでActivityPub実装してるかたいらっしゃった。
NetlifyとSupabaseでほぼ静的なActivityPubサーバ

今回まででとても参考になったサイト
Fediverse入門―非中央集権型SNSサーバを作ろう!
田舎の昼のサイレンbotをActivityPubで実装する(マストドンにアカウントを認識してもらう編)
ActivityPubの実装についてのメモ
本当に助かりました。多謝!!!

さっそく、ひとり言掲示板 「ところてんx10」 が役に立った、ぞ。

[2024/09/04 22:55:57]
nodeinfo→nodeinfo2.1のフェーズを追記。

»電子書籍制作代行についてはこちら

twitterが使えなくなった

2023/6/29 [01:44:56] (木) 天気

twitterのapiが昨日あたりから死んでる。認証で弾かれて使えない状態。
ていうか。APIの仕様が変わったらしくあちこち阿鼻叫喚の様相。呆れたというかツイッターにはうんざりげんなり。

twitterは、web本棚で本棚に本を登録した時に書名をツイートしたり、本棚アカウントにリプライして、自分の本棚を検索したり、といったことで利用している・していた。

ガラケーの時に、自分の本棚を開いても、検索したりする状況で、あのチマチマした画面が使いにくくてうっとーしーったらありゃしない。なもんで、ツイッターを利用することにした。

…という経緯でもあるんで、ガラケーが終了してスマホ前提なら画面、UI的なことは、それほど問題じゃない。web本棚のツイートについて確認してみるとほぼ利用実態もない。公開しているサービスの一部を取り止めにするのは、サービスレベルの低下だろ、と言われるとごめんなさい、だけど、この際、いろいろ不明、不透明なツイッター依存は取り止めにするしかない。

PC版
image
スマホ版
image
趣味は読書2 https://doncha.net/
このWEB本棚で、ツイッターを使う、ツイッターのAPIを使ってる部分をばっさり削除してまわった。
何度も言ってる、というか何度も自画自賛するんだけど。
このWEB本棚は実によくできていて、役割分担単位でのモジュール設計のおかげで、ツイッターが絡んでるところを排除するのもスグだった。これを作った17年前の自分を褒めてあげたい。

んで、身も蓋もないことをぶっちゃけると。
このWEB本棚は「あれ?これって読んだっけ?持ってなかったっけ?」
の確認をどこでもしたいという、かなりしょぼいところが始まり。
なので、元々は「既読・未読」の分類だけ。そのほかの機能はオマケ。

読んだことさえ忘れることがあるんで、買っただけで積んでる本はまったく覚えてない。本屋さんで書棚を眺めていて、を!これは面白そうじゃん!と思って、あれ?ひょっとしてもう読んでたり買ってたりしてないか?実際、部屋には同じ本が2冊あったりするわけで。
それにはネットでアクセスできる自分の本棚が重宝する。
という自分都合でやってるということもあるからこそ、20年近くも続いてる。

ツイッターは行政なんかの公的機関も通信インフラとして使ってる。
私企業に依存してるととんでもないことになる良い例というか悪い例というか。FacebookもLINEも同じ穴のなんちゃら。
ツイッターの今の状態はとても健全とは思えないんで、政府・行政は自前、内製で使いやすい通信インフラを構築する時じゃないかな。

[06/29 12:17:18]追記
とか、のんきなコトを書いてる場合じゃなかった。

2011年11月に公開した同人誌応援サイト「創作文芸見本誌会場HappyReading」の方は、サイトを閉鎖せざるを得なかった。
Twitterアカウントでログインして本を登録するサイトなんだけど、ログインできなくなってるよ、と嫁さんに聞かされてビックリ。OAuth認証は生きてると聞いてたのに、それもダメになったのか。てことは利用しようにも利用できない状態。ほんと困った、というか弱った。なんでまたそんな根本的な部分を使えなくするんだか。
しかたがないので、トップページにお知らせを上げて、サイトの閉鎖作業。

WEB本棚の方はメールアドレスで登録、ログインすることにしてるんだけど、実はこれもあやしい、かな。メールアドレスは個人情報にあたるので本当ならPマークなんてのが必要となる、はず。ただ、このサイトを「業」としてやってない、個人の趣味の範囲だから大丈夫かなあ、と思ってるんだけど、ツッコミというか突っ込まれどころかもしれん、か。

いろいろ面倒な時代になったなあ。

»電子書籍制作代行についてはこちら

AmazonPA-API5に移行で大騒ぎや

2020/1/26 [10:47:47] (日) 天気

amazonのAPIが2020年にバージョン5になります。
https://affiliate.amazon.co.jp/help/node/topic/GZBFW3F79Y7FADBL

…というのは薄っすら意識はあったものの、1/23に届いたメールタイトルに驚愕

「IMPORTANT UPDATE - 
Upgrade to PA API 5.0 before PA API 4.0 shuts down on March 9, 2020」

この「PA API 4.0 shuts down on March 9,2020」はさすがに見逃さなかった。
これまでずっと使い続けていたAPIのまさかの終了のお知らせだ。

去年2019年は、売上のないアカウントはAPIの使用制限がかかるようになり(売上のないアカウントは実質使えなくなり)困ったなあ、と思いつつも、たまーーーに、ポツリとクリック→購入があって使える日もあったんだけど、今回のAPIの変更は、そんな呑気なことを言ってるヒマはない。
まったく使えなくなるのだ。

てことで対応しなきゃまずい。とてもまずい。かなりまずい。
慌ててamazonのwebサービスドキュメントページをざっくり確認。
https://webservices.amazon.com/paapi5/documentation/

ver4とver5ではまったく違う。別人となる。
https://webservices.amazon.com/paapi5/documentation/migration-guide/whats-new-in-paapi5.html
取得するデータが、今までずっと変わらずXMLだったのに、ver5からはJSONになる!!びっくりマークをつけてもつけたりないぐらい驚天動地だ。
…てことは、現状使っている自作のスクリプトは全面的に書き換えが必要となる。

SDKを使ってお手軽に、とか思って探してみたところ、ver5に用意されているSDKは、Java、Node.js、Python、PHPの4つ。なんでperlがないねんっ!!
確かamazonはフロントのWEB側はperlだったはずだろう。今どきのWEBサービスには珍しくperlのサンプルもずっと用意してくれていたってのに、だ(残るはPaypalぐらいか)

JavaもNode.jsもわからんちんだし、Pythonもこれからの主役はこれか、ぐらいの遠巻き。
PHPがどうにか少しはいじれるので、サンプルをダウンロードして、perlに移植してみた。
サンプルに入っているDefaultApi.phpでエンドポイントやオペレーション名を拾って、WithoutSDKのサンプルコードで署名込みのヘッダーを作れるようにした。
PHPはどこからグローバルというか、スコープというのか知らんけど、把握するのにあっちこっち行かなきゃわからないから好きじゃなかったんだ、てのを再認識。

さて、これでそれっぽいリクエストを作れるようになったはずなんだけど。
売上のないアカウントなので、試せない。
売上のないアカウントには用はないamazonだ。

作ったスクリプトを使って。
ローカルのPCでリクエストを投げると
439 TooManyRequests というステータスと、JSONでエラーメッセージが返ってくる。
試しにレンタルサーバーに上げてそこからリクエスト投げると
503 とHTMLのエラーページが返ってくる。
どうやらどちらも売上のないアカウントだから相手にされない、ということっぽい。

一応、レスポンスのサンプルは公式ページにある。
でもなあ、こういうのって実際に何が返ってくるのか確認できなきゃ難しいんだよなあ。

てことで、大慌てで昨日一日ごそごそやってみた感想というか所感というかなんちゅーかほんちゅーか。

 
APIとかクロールとかで検索するとPython本が上位にずらーっと。
インストールぐらいしていっちょかみしといたほうがええか…。

まあ、最悪はamazonのデータを利用してサービスを公開していて安定稼働している他サイトからデータをいただくというクズなことをすれば、わたしのサービスが止まることもないんだけどね。うーむ。
image 

»電子書籍制作代行についてはこちら

書誌情報データを求めて三千里

2019/4/3 [09:18:16] (水) 天気

一昨日、新元号の発表があった4月1日に国立国会図書館の書誌データAPIが解禁となった。
今までも検索などに使えていたけど、データベースとしてガツガツ使うには登録が必要だったり面倒くさかったのが、4月1日からは誰でも自由に使ってもかまわんぜ!になった。

てことで、今さら国立国会図書館の書誌データAPIをごそごそ覗いてみた。

国立国会図書館サーチについて>API仕様の概要 
https://iss.ndl.go.jp/information/api/riyou/

わたしの、というかわたしが公開しているサイトの使い方は前にも書いた通り。
「ISBNをキーにして書誌データと書影URLを取得したい」
たとえば、スティーヴン・キングの『シャイニング』
ISBNは978-4167705633

これを国立国会図書館のAPIで探すには以下
https://iss.ndl.go.jp/api/opensearch?isbn=978-4167705633
→書誌情報のXMLが返ってくる
https://iss.ndl.go.jp/api/openurl?isbn=978-4167705633
→検索結果ページが返ってくる
https://iss.ndl.go.jp/api/sru?operation=searchRetrieve&maximumRecords=10&query=isbn%3d9784167705633
→書誌情報XMLが返ってくる(このsruはさらに細かく検索方法の指定もできる)

うちの場合、必要な書誌情報はopensearchで十分。
著者についてももろもろ考慮されて(同性同名や読みなど)おり、データのクオリティは信用できる。さすが。
https://www.ndl.go.jp/jp/data/faq/author.html

蔵書のある図書館の情報なども取得できるので、位置情報と合わせて「目当ての本がある最寄りの図書館」なんて検索も実装できるし、その手のアプリがすでにあるのは、国会図書館のデータが元ネタじゃないかな。

だけど、書影がないのはほんと残念。
本棚を眺める楽しみのひとつ、というか欠かせないのが表紙だもんなあ。
基本的な書誌情報は国立国会図書館で、書影・表示画像はamazonなどのショップサイトのURLを別途取得…とか1冊の本のために2回も外部にリクエストしてるとサイトの表示がもたつく原因になってしまう。

てことで、うちのサイトのデータ取得方法は現状のままとする。
国会図書館のデータはまた何か別の用途で利用させてもらおう。しっかりとしたデータは見ていて気持ちいい(データオタク)


ちなみに。
「一般社団法人 日本出版インフラセンター」という版元主導のところも3月25日に書誌データベースのサイトをオープンしたけど、APIもなく、手入力でポチポチ検索できるだけ、なのでスルー。
image

»電子書籍制作代行についてはこちら

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

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

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

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

「デジタルコンテンツをダウンロード販売できるサイトを比較してみた」
https://writing-san.blog.jp/archives/32017213.html

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

「Easy Digital Downloads - ダウンロード販売サイトを簡単に作れるWordPressプラグイン」
https://netaone.com/wp/easy-digital-downloads/

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


ぶっちゃけ、わざわざ自分でダウンロード販売の仕組みとか作るのは時間と労力の無駄なのでオススメしない。
面白そうだ、という好奇心自己満足。それと、もしかすると、何らかの事情で他社サービスにコンテンツを置くわけにはいかないような場合に。

てことなので、以下はわたしの技術メモ。備忘録。
内容的には2010年の雑記とPayPalとのやり取りなどはほぼ同じ。
「paypalと電子書籍のダウンロード販売(その1)」
https://t2aki.doncha.net/?id=1277017233
「paypalと電子書籍のダウンロード販売(その2)」
https://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にしているところ以外はサンプルコードのまんま。


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を書いたメールを送信する(自分にも同じものを送信)

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



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

ダウンロードはダウンロード用のスクリプトがファイルを返すようにしてある。
たとえば、わたしが自分だけで作ったコンテンツなんかはどうでもいいんだけど、表紙が依頼原稿だったり、アンソロジーでほかの人の原稿が入っていたりするとそうもいかない。回数や期間を無制限にするわけにはいかない。
なので、ファイルの置き場所=URLをそのままユーザーにお知らせできない。

ダウンロード用のスクリプトを噛ませて
・ダウンロードのURLは購入者ごとに違うものを作る
・ダウンロード回数を制御する
・ダウンロード期間を制御する
といったことを仕込んだ。

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


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

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

»電子書籍制作代行についてはこちら

profile

profile

 
doncha.net
contact:
»運営者
@t2aki@tokoroten.doncha.net

ため池

[2024/10/04 12:47]
『須永朝彦小説選』須永朝彦 山尾悠子選
「木犀館殺人事件」
#読書ドン

[2024/10/04 12:13]
道具は使い方ひとつ、使う側の思惑がすべてだよねえ

[2024/10/04 12:11]
High quality concept art,a vampire stands,gohtic guest room,moonlight filtering through high window, rim light,wide angle,sharp focus,highly detailed,digital art illustration, ...

@t2aki@tokoroten.doncha.net

検索
<<2024/10>>
  12345
6789101112
13141516171819
20212223242526
2728293031

リンク

WINDOWS版サウンドノベル
おかえりください PC WINDOWS版サウンドノベル
『おかえりください』体験版

[5 Page] »
1 2 3 4 5

TOTAL:2990

2024 (13)
1 (2)
2 (2)
3 (1)
5 (1)
7 (2)
8 (2)
9 (3)
2023 (53)
1 (1)
2 (5)
3 (1)
4 (1)
5 (3)
6 (9)
7 (9)
8 (6)
9 (5)
10 (3)
11 (2)
12 (8)
2022 (16)
1 (1)
3 (2)
6 (2)
7 (1)
8 (4)
9 (2)
10 (1)
11 (2)
12 (1)
2021 (12)
1 (3)
2 (1)
6 (1)
8 (2)
9 (1)
10 (1)
11 (2)
12 (1)
2020 (18)
1 (2)
2 (6)
4 (1)
6 (1)
7 (2)
8 (2)
12 (4)
2019 (17)
1 (3)
2 (4)
3 (2)
4 (2)
5 (1)
6 (1)
8 (1)
10 (1)
12 (2)
2018 (21)
1 (3)
2 (2)
3 (2)
4 (1)
5 (1)
6 (6)
8 (1)
9 (1)
10 (2)
12 (2)
2017 (32)
1 (2)
2 (1)
4 (2)
5 (1)
6 (6)
7 (3)
8 (5)
9 (3)
10 (2)
11 (2)
12 (5)
2016 (41)
1 (5)
2 (5)
3 (2)
4 (3)
5 (4)
6 (6)
7 (2)
8 (2)
9 (3)
10 (1)
11 (4)
12 (4)
2015 (99)
1 (11)
2 (12)
3 (9)
4 (6)
5 (8)
6 (8)
7 (3)
8 (5)
9 (16)
10 (6)
11 (1)
12 (14)
2014 (112)
1 (16)
2 (5)
3 (6)
4 (12)
5 (16)
6 (19)
7 (9)
8 (6)
9 (4)
10 (8)
11 (6)
12 (5)
2013 (145)
1 (24)
2 (15)
3 (18)
4 (23)
5 (14)
6 (11)
7 (7)
8 (11)
9 (5)
10 (4)
11 (6)
12 (7)
2012 (103)
1 (1)
2 (1)
3 (4)
4 (3)
5 (7)
6 (26)
7 (17)
8 (5)
9 (8)
10 (10)
11 (11)
12 (10)
2011 (54)
1 (4)
3 (7)
4 (4)
5 (14)
6 (6)
7 (3)
8 (3)
9 (1)
10 (4)
11 (2)
12 (6)
2010 (70)
1 (12)
2 (7)
3 (6)
4 (6)
5 (3)
6 (10)
7 (6)
8 (4)
9 (3)
10 (4)
11 (3)
12 (6)
2009 (144)
1 (15)
2 (12)
3 (12)
4 (6)
5 (15)
6 (6)
7 (10)
8 (9)
9 (17)
10 (12)
11 (14)
12 (16)
2008 (148)
1 (10)
2 (6)
3 (10)
4 (11)
5 (13)
6 (10)
7 (13)
8 (19)
9 (18)
10 (12)
11 (13)
12 (13)
2007 (106)
1 (7)
2 (5)
3 (3)
4 (7)
5 (5)
6 (9)
7 (8)
8 (13)
9 (18)
10 (11)
11 (8)
12 (12)
2006 (158)
1 (28)
2 (28)
3 (25)
4 (7)
5 (9)
6 (7)
7 (12)
8 (13)
9 (10)
10 (7)
11 (6)
12 (6)
2005 (350)
1 (31)
2 (26)
3 (26)
4 (27)
5 (29)
6 (30)
7 (32)
8 (30)
9 (30)
10 (32)
11 (29)
12 (28)
2004 (292)
1 (24)
2 (24)
3 (29)
4 (27)
5 (28)
6 (25)
7 (26)
8 (24)
9 (12)
10 (19)
11 (26)
12 (28)
2003 (318)
1 (22)
2 (25)
3 (21)
4 (28)
5 (28)
6 (28)
7 (28)
8 (29)
9 (26)
10 (29)
11 (28)
12 (26)
2002 (317)
1 (29)
2 (26)
3 (26)
4 (25)
5 (28)
6 (30)
7 (27)
8 (21)
9 (25)
10 (27)
11 (28)
12 (25)
2001 (277)
1 (17)
2 (21)
3 (23)
4 (20)
5 (31)
6 (18)
7 (26)
8 (25)
9 (29)
10 (19)
11 (24)
12 (24)
2000 (53)
6 (9)
7 (4)
8 (2)
9 (3)
10 (1)
11 (15)
12 (19)
1999 (3)
7 (1)
10 (2)
1998 (18)
9 (9)
10 (7)
11 (2)