PayPalでカード決済するプログラムをMindで作ったときの感想

　初めてオンライン販売のクレジットカードの決済手段（販売側のほう）として PayPal を使った。

　真正面から個別のクレジットカード会社と契約するのは弊社のような零細会社では無理で、普通は第三者による決済代行のサービスを利用することになる。
　Googleで調べると、決済代行サービス自体かなりの数があることが分かる。SONYとか楽天とかの有名どころもやっている。また決済手段としてクレジットカード以外に銀行振り込み、電子マネー、コンビニ支払いなど多くのメニューを持っているサービスが多い。

　しかし、うちのような規模ではその代行会社の多くがこれまた敷居が高い。よくあるのは「まず営業マンが伺ってお話をさせていただきます」とか「システムの設置に１ヶ月」というようなもので、当然、初期費用など結構かかかる。そのようなところを除外していくと PayPal が数少ない有力なサービスだということが分った。またこれは他のサービス会社も同じだと思うが、クレジットカードの情報は販売者には渡らず代行サービス内で処理され、こちらには「支払いが終った」ことだけが通知されるので購入者にとって安心な仕組みだと思う。

　私は２年ほど前に購入者として一度だけ使ったことがあるだけで、販売者側についてはまったく知識が無く、手続きとか技術的なことの調査にずいぶ時間がかかった。
　初期費用が不要な点が良い。売り上げから手数料を取られるが特に高いとは思わなかった。

　まず、PayPalの販売者としての登録は、購入者アカウント（これは元々持っていた）を拡張する形で手続きができた。つまり購入者でもあるし、販売者でもある‥という扱いになる。もちろん、購入者としての個人名とは別に、販売会社として、会社名・住所その他のプロフィールを登録する。
　販売者としての登録では個人としての証明（免許証など）のほか、法人の登記簿謄本の提示が必要だが（これは当然だと思う）すべてスキャナ画像の送付によるオンライン手続きができ比較的簡単で審査も短日数で完了した。

　ここまでは順調。

　しかしそのあとの技術的な作業がかなり大変で、今回のオンライン販売（ライセンスキーを即時発行）を実装するのに合計１ヶ月ほどかかった（商品自体のソフト開発にかかった日数といい勝負になってしまった(^^;）。
　大変だったのは以下のようなものだった。


　　（（**いろいろ文句を書いているが、結論から言うとまったく問題なく動いており、良く出来たシステムだと思う**））


　PayPal はとにかく開発者向けの情報提供がうまくない。一見すると各種情報が整備されているように見えるけれど、たとえば管理パネル（ダッシュボード）からの情報誘導とドキュメントでの誘導がまるで違うとか、日本語のドキュメントを読んでいると途中から英文になるとか。

　本家の情報が心許ないので Google で検索する。相当多くの件数がヒットするが８割がたの情報が既に古い。たとえば誰かのブログで「PayPalのこのページを読め」と書いてあっても多くが Not Found。大事なドキュメントの多くをURL変えてしまったようだ。
　ここ数ヶ月で大きな変更があったのかもしれないが開発者向けサイトではそのことの説明が無い。
　Googleで見つけたブログの中には「こんなもの使えるか」と怒っている記事を複数見たが、気持ちはよく分った(^^;
　私も途中でメゲそうになり、やはり安価でできるのはここしかないこともあり、もうここまで来たらやってやろう‥という感じで続けた。

　弊社ではWebサイトのCGIは当然ながらMindで作っていて、今回のPayPalがらみのトランザクションも当然Mindで書いた。
　しつこいようだが、最初から仕様がはっきり分っていればMindで作りこむのはそれほど大変ではないのだが、ネットで調べたり試行錯誤でようやく分ることが多くそれが大変だった。

　以下はやってみて分かった主なもの。

　　●サンドボックスと本番サイト

　開発段階では決済処理を何回も繰り返して動作確認するが、本当にクレジットカードで決済したのでは大変なことになるため、PayPalでは開発者向けに「サンドボックス」という擬似的なシステムを用意していて、それを使ってプログラムの動作確認ができる。（その中に、擬似的な販売者と購入者を設置する）
　１点だけ本番とサンドボックスとで挙動が違う部分があった。購入者がボタンを押してPayPalサイトに飛んだとき、「PayPalにログイン」と「クレジットカード決済」の２種類を選ぶようになっている。支払い時の敷居を低くしたいので後者のクレジットカード単独決済を使いたいのだが、サンドボックス環境ではそちらのパスから入っても最後はPayPalのアカウント登録のほうに強制誘導されてしまった。
　PayPalのサポートに聞いたところ本番環境なら単独決済が可能とか。たしかにその通りだった。それはいいのだが、テストでは本物のカード支払いを何回するはめになった（わざと価格を100円とか安価にして実験したが）。PayPalのサポートの人が言うには、「今はキャンペーン期間なのでカード単独決済が可能」という話だった。PayPalの側として購入者にも正規アカウントを作って欲しいと思うのは分るのだが、販売者としてはカード単独決済があることは重要で、まだ続いて欲しいと思っている。

　　●「API」という用語の意味

　購入ボタンを押すと一旦PayPalサイトに遷移する。そこでクレジットカード情報を入力し、支払いが終ると販売者のサイトに戻って来る仕組み（「復帰URL」というものを登録しておけば呼び出される）がある。
　その復帰URLにCGIを置いておき、その中から逆にPayPalのサーバをコールバックすると各種情報（支払い者の名前やメールアドレスなど）が得られる仕組みになっている。
　私の感覚ではこれは立派なAPIなのだが、しかし PayPal が言う「API」は別のもので、RESTを使ったもっと本格的なものを指す（たとえば販売会社のサイトからPayPalサイトへ遷移せず決済ができる）ようで、ドキュメントなどもそちらのほうが多く存在している。このことを理解するのに結構時間がかった。

　販売社のサイトに自動的なオンライン販売を組み込むには、ダッシュボードでボタン登録できる「いますぐ購入」ボタン、および「決済完了時に復帰URLを呼び出してもらう」ことの組み合わせが一番分りやすい仕組みだと思う（PayPalが「API」という仕組みに比べて）。この分りやすいほうを「ウェブペイメントスタンダード」と言うようだが、こんな単純なことを理解するのにずいぶんかかった(^^;
　トランザクションを処理する方法は３種類ぐらい存在していて、今回使ったのが一番簡単な方法なのにもかかわらず、その処理方法の詳細説明が不足しているように思った。（ドキュメントの多くが複雑なほうを解説している）
　ちなみに、「復帰URLを動的に呼び出してもらう」ことさえもせず、単に「いますぐ購入」ボタンを設置するだけでも販売は行えるようで、そういう最も手抜きの方法であっても販売者に購入情報のメールは届くので、メールで受け取るなど人手に頼って良いのならその方法で最低限の販売業務は可能。しかし、自動処理でデジタルデータを渡すなどするには復帰URLとの組み合わせが必須となる。

　　●HTTP/1.1 と Hostフィールド が必須

　ブログなどで見つけたサンプルプログラムでは PayPalサーバを呼び出すときのプロトコル（HTTPのリクエストヘッダ）に HTTP/1.0 を使っているものが多かったが現実はそれではエラーで、HTTP/1.1 が必須。同様にリクエストヘッダ内に Host: フィールドが必須らしい。

　　●https(SSL) 必須

　上記と同様、ブログの記事では「httpでもいいけどセキュリティのことを考えるとhttpsのほうか望ましい」というようなものを多く見たが、現実は https 必須だった。
　Mind では 以前はLinux版のものはSSLサポートしていたのだが、Mind Version 8 をリリースする際に Windowsの側と仕様を合わせるため SSLを削ってしまった。（こんなことなら削るんじゃなかった）
　仕方ないので社内用としてSSLが使えるMindのライブラリを再度作った。

　　●(Linuxの) OpenSSL は最新版が必要

　弊社のWebサーバや手持ちのサーバはOSが若干古く搭載している OpenSSL は 0.9.8e で少し古いものの、これでWebのSSLサービスをおこなってきた。しかし、PayPalとの通信ではSSLの通信開始時にエラーになる。ためしに別のサーバ（OpenSSL 1.1.0系）で動かしたところOK。
　当初、PayPal側が TLS1.1 を要求するために（古いOpenSSLは1.1は非対応）エラーになっているのかと思ったがOpenSSLを最新にしたら TLS1.0 でもつながる。このへんはよく分らない。

　　●PDTとIPNのこと

　先に書いたように購入手続きが終わってこちらのサーバの「復帰URL」に設置したCGIが呼び出される仕組みをPDTと言う。一方、それとは独立して（購入者のWeb操作とは別に）PayPalからこちらのサーバを呼ぶ仕組みが別途あり、それはIPNと呼ばれる。
　「なんで２つも通知手段があるのか」と当初思ったのだが、購入者はPayPal決済後にブラウザを閉じる可能性がありそのために購入者のブラウザアクセスとは別に、単独で PayPal→販売会社 への通知手段が必要らしい。
　しかし「全体の決済が終わっていないのにブラウザを閉じる人なんているのか？」と疑問に思ったが、実際にやってすぐ分った。
　購入者が最後のボタンを押ししばらく待つと「決済が終わりました」という画面(PayPalによる)が表示されるのだが、実はそこではまだ全部は終わっておらず、さらにしばらく待って販売会社のサイトに戻って来て「ご購入ありがとうございました」の(販売会社の)画面が表示さてようやく全部が終る‥という、少々まぎらわしい挙動をするからだ。（最初の段階でPayPalとしては決済終了だが、その時点ではまだ販売会社に情報が伝わっていない）。
　このために途中離脱される可能性は有りそうで、そのためIPNが必要というのは分かった。
　つまり２つの手段で似たような情報が販売会社に渡されることになる（実際やってみると、どちらが先に到着するかはマチマチのよう）。これまた少し面倒なことで、早いもの勝ちで処理をおこない、後から来た通知は（ログには残すが）二重販売にならないようにしないといけない。