Paypalで支払いを受ける

ユビレジPaypal支払いを受け付けるようにしました、という話。意外と簡単で、意外とめんどくさい。

当初、支払いの受付は銀行振込のみでした。支払いを受けるシステムを作るのがめんどくさいというのが、その理由。いきなり爆発的に利用者が増えるというのも想定してないし。で、そろそろ利用者がけっこう増えてきたのとか、まあ今後の展開も考えて、Paypalで支払いを受け付けるようにしようと思いました。

日本国内で気軽に利用できるのは、Web Payments Standardというやつ。Webサイトに「Paypalで支払う」みたいなボタンが付きます。よく見るのはソフトウェアのライセンスなんかを買うやつですが、実はこれに「Subscription」というのが指定できて、毎月一定額を自動で支払ってもらうことが可能です。

システムとしてどういう変更が必要かというと、

  1. サービスのWebサイトに「Paypalで支払う」みたいなボタンを付ける
  2. Paypalから支払いがあったことを通知してもらうためのURLを用意して、そっちで誰が支払ったかとかをトラッキングする

の2点。わかってしまえば簡単である*1。最後に、PayPalのサービスで自由度が低い点をどうしたのかという話。

それでは始めましょう。

テスト環境

いきなり本番環境で、自分のクレジットカードに課金とかテストするのは嫌なので、テスト環境で始めます。テスト環境は、PayPal Sandboxというのが用意されているので、こちらでアカウントを作ることから始める。

なにが必要か。

  1. テスト環境アカウントを作る
  2. テスト環境アカウントにログインして、「テスト用店舗アカウント」を作る
  3. テスト環境アカウントにログインして、「テスト用クライアントアカウント」を作る

で、「テスト用店舗アカウント」で、テスト環境にログインして、そこでボタンを作ったりなんだりすれば良い。買うのをテストするときは、「テスト用クライアントアカウント」でログインする。

わかってしまえば簡単。

注意としては「テスト用クライアントアカウント」は米国にしておいたほうが良かったような気がすること。クレジットカード番号とか、意味わかんなくなっちゃった。

支払いボタン作成

Paypalのサイトで作ります。「テスト用店舗アカウント」で作るとテスト環境用になりますし、本番環境のアカウントで作ると本番用になります。Webサイトの側では、Rails.envとか見て切り替えるしかないと思う。

ボタンはPayPalのWebサイトのウィザードで作るだけなので、説明は省略。

日本語を使うと化けた気がします。

支払い通知用URLの作成

支払いがあったときに、適当なURLにPOSTして通知してくれるメカニズムがあるので、それを使います(IPNとか言います)。

IPNのListenerのURLは固定でやることもできますが、ボタン作成時にURLを指定することもできます。今回は、普通にアカウントのidを含めることにしました。本当は予測不可能なURLにしたほうが良いでしょうが、本当にPayPalから来たリクエストかどうか、ちゃんと確認できるようになってるので、あんまり問題はないかなぁ。と。

これもドキュメントを読めばすぐわかる話なので、詳細は省略。

  • 当然、PayPalからリクエストを受けられるようにしておく必要があるので、開発環境だとリバースプロキシとSSHのポート転送を組合せるなりなんなりする
  • テスト環境と本番環境では、リクエストの検証のURLが違うので、例によってRails.envとか見て切り替える

PayPalを使う上での制限

Subscriptionは、メールマガジンとかそういう系統のサービスで利用されることを想定しているみたいで、実はWebサービスに使っても問題がないかは微妙だったりする。

例えば、有料プランに2種類あったりして、高いほうのプランと安いほうのプランの切り替えとか、いったい何が起きるのか、という話。「課金額の変更は次の月から!」らしいんだけど、切り替え直後でサービスの内容を変更するのとかどうすれば良いのか悩んでしまう。切り替え直後で変更するようにすると、一時的に高くして課金直前直後で安いほうに切り替えられると困る(このへんがどうなっているかについて、PayPalには資料がない:わざとかもしれないけど)。即時に切り替えないようにすると、ちょっとサービスとしていまいちになってしまう。こういう話。

ユビレジの場合は、いろいろ考えて「気にしない!」ことにした。高いほうのプランと安いほうのプランで、システム上の制限は設けないことにする。そのうえで、本来なら制限を越えるような利用については監視して、人手で警告なりアカウント削除なりすることで対応しようと思う。(これができるようなプラン設定になっていないといけないし、そういう風に設定したという話。)

スケールするかは微妙なところで、すぐにしんどくなりそうな気もするけど、まあしんどくなってから考えれば良いよね。

*1:私がやろうとしてつまづいてたところを整理しただけの記事