#289 PayPal Recurring Billing pro
- Download:
- source codeProject Files in Zip (137 KB)
- mp4Full Size H.264 Video (60.2 MB)
- m4vSmaller H.264 Video (30 MB)
- webmFull Size VP8 Video (34 MB)
- ogvFull Size Theora Video (73.9 MB)
エピソード141[動画を見る, 読む]から何回かのエピソードで、RailsアプリケーションでのPayPalのいろいろな利用方法を紹介してきました。その中で取り上げられなかったトピックが、繰り返される支払いの処理です。今回のエピソードでは既存のアプリケーションにこの機能を組み込むときの手順を紹介します。
対象とするアプリケーションは、前回のエピソードで使用したラマのキスを売るサイトです。ホーム画面を以下に示します。
ラマ・キスのアプリケーションはいくつかのプランを提供しますが、いずれも1ヶ月単位のsubscription(定期会員プラン)です。あるプランに登録するときにはクレジットカード情報を入力する必要がありますが、顧客の中にはクレジットカード情報を直接入力するよりもPayPalを介して支払いをしたいという方もいるでしょう。理由は、クレジットカードを持っていない、クレジットカードによる支払いには手数料が余分にかかる、サイトを信用できないのでクレジットカード情報を入力したいくない、などがあるでしょう。そこで潜在顧客をなるべく失わないようにするために、PayPalによる支払いのオプションも追加することにします。
PayPalでテストアカウントを作成する
PayPalは最初は少し取っ付きにくいかも知れません。同じようなサービスをいくつも提供していて、どれを選べばいいかがわかりにくくなっています。たとえばこのページには繰り返される支払いを処理する6種類の異なる方法が表示されています。我々のサイトではすでにクレジットカードによる支払いを受け付けていて、単に代替の支払い手段としてPayPalを使用するだけなので、Express Checkoutを選択するのがいいでしょう。
次に選択しなくてはいけないのが、Express Checkoutをアプリケーションに統合する方法として何を利用するかということです。エピソード144ではActive Merchantを利用しましたが、単にPayPalを統合するためだけには大げさで、繰り返しの支払いにも対応していません。繰り返しの支払いをサポートするActive Merchantのフォークもいくつかありますが、今回はActive Merchantは利用しないことにします。
もう一つの選択肢はPayPalのAPIと直接通信する方法です。もしこの方法を選択する場合は、作業を始める前にName-Value Pair API PDF documentのExpress Checkout APIについてのセクションが役に立つので一読することをお勧めします。APIと直接通信するということは、アプリケーションに外部依存関係が必要ないということですが、同時により作業が多くなることを意味します。
今回のエピソードで利用するソリューションは、あまり知られていないですが、Nando VieiraによるPayPal-Recurringというgemです。これはName-Value APIを使用し、それと通信するために使いやすいRubyインターフェースを提供します。gemのソースコードは読みやすくていねいな解説がついているので、PayPalとどのような通信をしているのかを調べる必要が出てきたとしても、ソースコードの対応する部分を読むことができます。
PayPal-Recurringのインストール
PayPal-Recurringは他のgemと同じようにインストールします。アプリケーションのGemfile
に参照情報を追加してbundle
コマンドを実行します。
source "http://rubygems.org" gem "rails", "3.1.1" gem "sqlite3" # Gems used only for assets and not required # in production environments by default. group :assets do gem "sass-rails", "~> 3.1.4" gem "coffee-rails", "~> 3.1.1" gem "uglifier", ">= 1.0.3" end gem "jquery-rails" gem "stripe" gem "paypal-recurring"
テスト用アカウントを設定する
PayPal-Recurringは使用する前に設定が必要なので、新たに初期化ファイルを作成してそこに設定情報を入れます。しかしその前に、PayPalのsandboxにテスト用アカウントを設定する必要があります。すでにアカウントの登録をおこなったので、ログインして必要な2つのテストアカウントを設定します。「設定済みアカウントを作成する」をクリックすると、作成用のページに案内されます。
最初に購入者用のアカウントをbuyer@asciicasts.com
というメールアドレスで作成します。アカウントの種類で「購入者」を選択し、メールアドレスの最初の部分を入力し、お試し用のお金をいくらか与えます。フォームに数字のパスワードがあるので、後ほどこのユーザでログインするときに使うためにこれをコピーしておきます。
販売者としてseller@asciicasts.com
を使用しますが、アカウントは「販売者」ではなく「Website Payments Pro」を選択します。販売者にお金を与える必要はありませんが、与えられた数字のパスワードはコピーしておきます。
購入者と販売者の両方のアカウントができて、PayPalがそれぞれにログイン用のメールアドレスを以下のように設定しました。
ただし、PayPal-Recurringではこの販売者のアドレスは利用しません。別のアドレスを得るために左のメニューからAPI Credentialsのリンクをクリックします。すると次のページに、利用するcredentialが表示されます。
初期化ファイルでは、この情報を使ってPayPal-Recurringを設定します。
PayPal::Recurring.configure do |config| config.sandbox = true config.username = "seller_1318669800_biz_api1.asciicasts.com" config.password = "1318669837" config.signature = "AFcWxV21C7fd0v3bYYYRCpSSRl31A1bAwEaPIqEwy9MooKcQYeYYQw0m" end
このファイルには秘密情報が含まれていて、本番稼働サーバでは同じ設定を使わないため、このファイルを.gitignore
ファイルに追加しておきます。
アプリケーションにExpress Checkoutを追加する
アプリケーションでExpress Checkoutを利用できるようにする方法はいくつかあります。チェックアウトボタンを使うか、ラジオボタンを2つ使って支払いをPayPalとクレジットカードのどちらでおこなうか選択させることもできます。今回はこれらの方法を組み合わせて使用します。最初に、新しく作成したsubscriptionビューのメールフィールドのすぐ上に次のコードを追加します。
<div class="field"> <%= radio_button_tag :pay_with, :card, true %> <%= label_tag :pay_with_card do %> <%= image_tag "visa.png" %> <%= image_tag "mastercard.png" %> <%= image_tag "discover.png" %> <%= image_tag "american_express.png" %> <%= image_tag "jcb.png" %> <% end %> <%= radio_button_tag :pay_with, :paypal %> <%= label_tag :pay_with_paypal do %> <%= image_tag "paypal.png" %> <% end %> </div> <div id="paypal_checkout" style="display:none"> <%= image_tag("https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif") %> </div>
このコードはページに2つのラジオボタンを追加します。1つ目には各種のクレジットカードの画像を付け、2つ目にはPayPalアイコンをつけます。それに加えて、PayPalのチェックアウトボタンを設定し、デフォルトではhiddenにしておきます。ユーザがPayPalを選択した場合はこのボタンを表示し、メールとクレジットカードのフィールドと送信ボタンを隠します。これはPayPalで支払いをおこなうユーザがもはやこれらを入力する必要がないからです。そのためにこれらのフィールドを、id
をbilling_fields
に設定したdiv
でラップすることにより、アプリケーションのJavaScriptがそれらを探して修正できるようにします。
<div id="billing_fields"> <div class="field"> <%= f.label :email %> <%= f.text_field :email %> </div> <% if @subscription.stripe_card_token.present? %> Credit card has been provided. <% else %> <div class="field"> <%= label_tag :card_number, "Credit Card Number" %> <%= text_field_tag :card_number, nil, name: nil %> </div> <div class="field"> <%= label_tag :card_code, "Security Code on Card (CVV)" %> <%= text_field_tag :card_code, nil, name: nil %> </div> <div class="field"> <%= label_tag :card_month, "Card Expiration" %> <%= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month"} %> <%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year"} %> </div> <% end %> <div id="stripe_error"> <noscript>JavaScript is not enabled and is required for this form. First enable it in your web browser settings.</noscript> </div> <div class="actions"> <%= f.submit "Subscribe" %> </div> </div>
ここでフォームをリロードすると新しく設定したラジオボタンが表示されます。
これでユーザは支払い方法をクレジットカードかPayPalから選択できるようになりました。次に、選択した支払い方法によってPayPalのチェックアウトボタンとクレジットカードフィールドを表示あるいは隠すためのCoffeeScriptコードを書きます。このアプリケーションにはすでにこのフォームに関連してCoffeeScriptコードがあり、ページのDOMの読み込みが完了したときにsetupForm関数が呼び出されるようになっています。この関数を修正して、PayPalによる支払いが選択されたときにはチェックアウトボタンを表示してクレジットカードフィールドを隠し、クレジットカードのラジオボタンがクリックされたときにはチェックアウトを隠してクレジットカードフィールドを表示するようにします。
setupForm: -> $("#pay_with_paypal").click -> $("#paypal_checkout").show() $("#billing_fields").hide() true $("#pay_with_card").click -> $("#paypal_checkout").hide() $("#billing_fields").show() true $("#new_subscription").submit -> $("input[type=submit]").attr("disabled", true) if $("#card_number").length subscription.processCard() false else true
ページをリロードしてPayPalでの支払いを選択すると、チェックアウトボタンが表示されてクレジットカードフィールドは隠されます。クレジットカードのラジオボタンをクリックすると、フィールドが再度表示され、ボタンが隠されます。
PayPalボタンはまだ何にも関連づけられていないので、これから修正します。ボタンを、まだ作成していないpaypal_checkout_path
にリンクして、選択されたプランのid
を渡します。これはPayPalに対してユーザがどのプランに登録するかを伝えなくてはいけないからです。
<div id="paypal_checkout" style="display:none"> <%= link_to image_tag("https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"), paypal_checkout_path(:plan_id => @subscription.plan_id) %> </div>
routesファイルにpaypal_checkout_path
を作成し、SubscriptionsController
に新規に作成する paypal_checkout
アクションを指定します。
Saas::Application.routes.draw do root to: "plans#index" resources :subscriptions resources :plans get "paypal/checkout", to: "subscriptions#paypal_checkout" end
新規に作成したrouteを名前付きrouteにしなかったことに注意してください。Railsは指定したパスに基づいてこれを自動的に処理してくれます。
SubscriptionsController
に新たにpaypal_checkout
アクションを作成します。
def paypal_checkout plan = Plan.find(params[:plan_id]) ppr = PayPal::Recurring.new( return_url: new_subscription_url(:plan_id => plan.id), cancel_url: root_url, description: plan.name, amount: plan.price, currency: "USD" ) response = ppr.checkout if response.valid? redirect_to response.checkout_url else raise response.errors.inspect end end
このアクションでは渡されたplan_id
パラメータを持ったプランを探して、新規のPayPal::Recurring
オブジェクトを生成して新しい支払いを作成します。このオブジェクトが受け取るパラメータは、見れば意味がわかるでしょう。そしてそのオブジェクトに対してcheckout
を呼び出してPayPal APIを起動するとレスポンスが返されます。レスポンスが有効であれば、レスポンスのcheckout_url
にリダイレクトします。これはユーザがログインできるPayPalのURLです。レスポンスが無効だった場合はエラーをraise
して、何が悪かったかをチェックできるようにします。
新しいsubscriptionフォームでPayPalボタンをクリックすると、PayPal Sandboxサイトのログインページに導かれます。注文の概要セクションで選択したプランの名前を見ることができるので、コードはうまく動作しているようです。
先に設定した購入者のテスト用アカウントの情報を使ってこのページにログインできます。これによって、処理しようとしているトランザクションを確認するためのページが表示されます。それに同意すると、アプリケーションの新しいsubscriptionページに戻されますが、URLには2つの新しいパラメータがついています。一つはtoken
というもので、もう一つはPayerID
です。PayPalでの支払いを完了するにはこれらが必要なので、Subscription
モデルに新規フィールドを追加してそれらを保存できるようにします。PayerID
パラメータがあったらsubscriptionのpayment_customer_token
をその値に設定し、一時的なトークンをpaypal_payment_token
として保存します。
def new plan = Plan.find(params[:plan_id]) @subscription = plan.subscriptions.build if params[:PayerID] @subscription.paypal_customer_token = params[:PayerID] @subscription.paypal_payment_token = params[:token] end end
paypal_payment_token
は一時的なものにすぎないので、仮の属性としてSubscription
モデルに追加します。
attr_accessor :stripe_card_token, :paypal_payment_token
もう一つのパラメータのpayment_customer_token
はより永続的なものなので、subscriptionsテーブルに保存します。新しいフィールドを追加するためのmigrationを作成し、rake db:migrate
を実行してデータベースへの追加をおこないます。この対応をおこなっている間に、この処理の一環としてPayPalから与えられて後で保存する必要があるもう一つのトークンがあります。これもpaypal_recurring_profile_token
として今保存しておきます。
$ rails g migration add_paypal_to_subscriptions paypal_customer_token:string paypal_recurring_profile_token:string
新しいsubscriptionページを見るとpaypal_customer_token
とpaypal_payment_token
の2つのフィールドがsubscriptionオブジェクトに保存されていますが、これらは新しいsubscriptionを作成するためにフォームでPOST送信される必要があります。新たに2つのhiddenフィールドをフォームに追加してこれらの値を保存し、フォームが送信されたときにそれらが送られるようにします。
<%= f.hidden_field :paypal_customer_token %> <%= f.hidden_field :paypal_payment_token %>
ユーザがPayPalにログインしたあとにsubscriptionフォームに戻ると、クレジットカードフィールドが再度ページに表示されます。ビューのコードには、Stripeの支払いが済んでいたらこれらのフィールドを隠すロジックがすでに組み込まれているので、これを拡張してPayPalトークンが存在するかどうかもチェックすることにします。
<% if @subscription.stripe_card_token.present? || @subscription.paypal_payment_token.present? %> Payment has been provided. Click &ldquo;Subscribe&rdquo; to complete the subscription. <% else %> <!-- Credit card fields omitted. --> <% end %>
ページをリロードすると、クレジットカードフィールドは隠されています。しかし支払い方法のフィールドの方は、ユーザがPayPalで支払うことがすでにわかっているのに、まだ表示されていています。同じ方法でチェックしてこれらを隠すことができますが、その前にロジックをモデルに移動してコードを少し整理します。subscriptionモデルに新たにpayment_provided?
メソッドを作成し、ビューでそれを使用してこれらのフィールドを表示するかどうかを決定するようにします。
def payment_provided? stripe_card_token.present? || paypal_payment_token.present? end
同じくこのメソッドを使って、支払いが済んでいたら支払いオプションを隠します。
<% unless payment_provided? %> <div class="field"> <%= radio_button_tag :pay_with, :card, true %> <%= label_tag :pay_with_card do %> <%= image_tag "visa.png" %> <%= image_tag "mastercard.png" %> <%= image_tag "discover.png" %> <%= image_tag "american_express.png" %> <%= image_tag "jcb.png" %> <% end %> <%= radio_button_tag :pay_with, :paypal %> <%= label_tag :pay_with_paypal do %> <%= image_tag "paypal.png" %> <% end %> </div> <% end %>
またクレジットカードフィールドを隠すコードもこれを使って整理します。
<% if @subscription.payment_provided? %> Payment has been provided. Click &ldquo;Subscribe&rdquo; to complete the subscription. <% else %> <!-- Credit card fields omitted. --> <% end %>
再度ページをリロードすると、支払い方法を選択する部分は隠されていて、あとはメールアドレスを入力して「subscribe」をクリックすればsubscriptionが完了するという状態です。
実はユーザはメールアドレスも入力する必要はありません。返された一時的トークンを使えば、PayPalにログインするときに入力した情報からチェックアウト時に必要な情報、つまりメールアドレスを取得することができます。
def new plan = Plan.find(params[:plan_id]) @subscription = plan.subscriptions.build if params[:PayerID] @subscription.paypal_customer_token = params[:PayerID] @subscription.paypal_payment_token = params[:token] @subscription.email = PayPal::Recurring.new(token: params[:token]).checkout_details.email end end
subscriptionフォームが、PayPalサイトから戻ってページが読み込まれるときにPayPalにリクエストを送信して、ログイン時に使用したメールアドレスを取得します。
最後は、ユーザがsubscribeをクリックしたときの支払い処理の扱いです。ここまでで実際の支払いはまだ発生していません。ユーザが支払いを承認しましたが、我々のところにはまだお金は届いていません。Subscriptionモデル内にはすでにStripeを介してクレジットカードによる支払いを処理するsave_with_payment
メソッドがあります。このメソッドを修正して、PayPalによる支払いも処理するようにします。save_with_payment
のコードはStripe専用になっているので名前をsave_with_stripe_payment
に変更します。その上で新規に、save_with_stripe_payment
メソッドかあるいは新規に作るsave_with_paypal_payment
メソッドのいずれかを呼び出す、より汎用的なsave_with_payment
メソッドを作成します。
def save_with_payment if valid? if paypal_payment_token.present? save_with_paypal_payment else save_with_stripe_payment end end end
次にこのsave_with_paypal_payment
メソッドを新規に作成します。繰り返しの支払いをおこなうためには2つのことが発生する必要があります。最初の支払いをリクエストし、そして繰り返しのプロフィールを作成して支払いが毎月おこなわれるようにします。最初の支払いをリクエストするコードは次のようになります。
def save_with_paypal_payment ppr = PayPal::Recurring.new( token: paypal_payment_token, payer_id: paypal_customer_token, description: plan.name, amount: plan.price, currency: "USD" ) response = ppr.request_payment if response.errors.present? raise response.errors.inspect end # 2. Make recurring profile end
このコードは新規にPayPal::Recurring
オブジェクトを生成し、token
やpayer_id
のような情報を渡して、支払いをリクエストします。これはSubscriptionsController
にあるpaypal_checkout
メソッドのコードに似ています。PayPalに渡される情報、特にdescription
とamount
が一致するということが重要です。そこでそれを専用のモデルに抽出することでPayPal::Recurring
オブジェクトが複数のモデルやコントローラに散らばらないようにします。
PaypalPaymentクラスへのリファクタリング
PayPal::Recurring
オブジェクトを生成するコードをリファクタリングして、app/models
の下に新しく置くPaypalPayment
クラスに移動させます。新たにActiveRecordモデルを作成しないので、このクラスは/lib
ディレクトリの下に入ると思われるかも知れませんが、モデルは常にActiveRecordから継承しなくてはいけないわけではありません。もしクラスがアプリケーション固有の情報を表している場合、そして今回のクラスはほとんどSubscription
とやり取りするだけなのでそれに該当しますが、ここに置くのがもっとも適しています。処理の対象であるsubscriptionオブジェクトをinitialize
メソッドに渡してインスタンス変数に割り当てます。
class PaypalPayment def initialize(subscription) @subscription = subscription end end
ではリファクタリングを始めます。これが終わったときには、コードは今よりもずっときれいになってほとんどのPayPal固有のロジックは新規に作成するPaypalPayment
クラスに入るはずです。
まず最初に、Subscription
モデルのsave_with_paypal_payment
メソッドのコードを、PaypalPayment
クラス内に新規に作成するmake_recurring_payment
メソッドの中に移動します。このクラスで新規のPaypalPayment
オブジェクトを複数回生成することになるので、これを簡略化するためにpaypal用のメソッドも作成しておきます。
def paypal PaypalPayment.new(self) end def save_with_paypal_payment paypal.make_recurring end
save_with_paypal_payment
から取り除いたコードは、新規のmake_recurring_payment
メソッドの中に移します。
def make_recurring ppr = PayPal::Recurring.new( token: @subscription.paypal_payment_token, payer_id: @subscription.paypal_customer_token, description: @subscription.plan.name, amount: @subscription.plan.price, currency: "USD" ) response = ppr.prequest_payment if response.errors.present? raise response.errors.inspect end # 2. Make recurring profile end
Subscription
クラス内にいないため、トークンとプランを@subscription
インスタンス変数から取得しなくてはいけないことに注意してください。
PayPal::Recurring
の呼び出しはすべて、SubscriptionController
から抽出して新しいPaypalPayment
クラスに移動します。まず最初にnew
アクションのこの行、
@subscription.email = PayPal::Recurring.new(token: params[:token]).checkout_details.email
を以下と置き換えます。
@subscription.email = @subscription.paypal.checkout_details.email
これで、トークンをparams
からではなく、subscription
オブジェクトから取得するようになりました。次にcheckout_details
メソッドを書きます。
<p>すでに<code>PaypalPayment</code>クラス内のメソッド間で重複部分が見られますが、これをリファクタリングする前にすべてをまずここに集めて、それから整理することにします。次に取り組むコードはSubscriptionsControllerのpaypal_checkoutメソッドです。</p> ``` /app/controllers/subscriptions_controller.rb def paypal_checkout plan = Plan.find(params[:plan_id]) ppr = PayPal::Recurring.new( return_url: new_subscription_url(:plan_id => plan.id), cancel_url: root_url, description: plan.name, amount: plan.price, currency: "USD" ) response = ppr.checkout if response.valid? redirect_to response.checkout_url else raise response.errors.inspect end end
このコードのほとんどをPaypalPayment
クラスに抽出することができますが、subscription
を渡さなくてはいけないので、plan
から新たに作成します。新たに作成するメソッドから取得する情報はチェックアウト用URLだけなので、名前をcheckout_url
にします。
上のコードの中にはモデル層からはアクセスできない情報がいくつかあります。具体的にはnew_subscription_url
とroot_url
です。これらをコントローラからのパラメータとしてoptions
ハッシュで渡します。
def paypal_checkout plan = Plan.find(params[:plan_id]) subscription = plan.subscriptions.build redirect_to subscription.paypal.checkout_url( return_url: new_subscription_url(:plan_id => plan.id), cancel_url: root_url) end
新しいcheckout_url
モデルは以下のようになります。
def checkout_url(options) ppr = PayPal::Recurring.new( description: plan.name, amount: plan.price, currency: "USD" ).merge(options) response = ppr.checkout if response.valid? redirect_to response.checkout_url else raise response.errors.inspect end end
Paypal Paymentクラスを整理する
PayPal関連のコードをすべてPaypalPayment
クラスに移しましたが、3つの主要なメソッド間ではかなりの重複があります。これを整理するために、クラス内に新規にprivateのprocess
メソッドを作成します。このメソッドは、引数としてPayPal::Recurring
オブジェクトから呼び出したいメソッドとオプションのハッシュをとり、response
オブジェクトを返します。このオブジェクトから必要に応じてメソッドを呼び出すことができます。これによってクラス内の重複の大部分を排除できます。この作業が終わるとPaypalPayment
クラスは次のようになります。
class PaypalPayment def initialize(subscription) @subscription = subscription end def checkout_details process :checkout_details end def checkout_url(options) process(:checkout, options).checkout_url end def make_recurring process :request_payment # 2. Make recurring profile end private def process(action, options = {}) options = options.reverse_merge( token: @subscription.paypal_payment_token, payer_id: @subscription.paypal_customer_token, description: @subscription.plan.name, amount: @subscription.plan.price, currency: "USD" ) response = PayPal::Recurring.new(options).send(action) raise response.errors.inspect if response.errors.present? response end end
PayPalの処理のいくつかに関して必要以上の情報を渡していますが、PayPal-Recurring gemが要らない情報をフィルタリングしてくれるので問題ありません。
make_recurringメソッドを完成させる
リファクタリングが終わったので、再度make_recurring
メソッドに集中して、繰り返しのプロファイルを作成するためのコードを書かなくてはいけません。リファクタリングをおこなったおかけでこの作業は簡単です。必要なのは、process
を呼び出してアクションとしてcreate_recurring_profile
を、支払いの頻度を定義するいくつかのオプションと一緒に渡すだけです。
def make_recurring process :request_payment process :create_recurring_profile, period: :monthly, frequency: 1, start_at: Time.zone.now end
PayPal-Recurringにどのようなオプションを渡して何をできるかについて興味があるなら、 関連するソースコードファイルを見て調べることができます。各オプションがリストになっていて、PayPal Name-Value Pair APIの対応するオプションがわかるように関連づけられています。
まだSubscriptionモデルのsave_with_paypal
メソッドで作業が残っています。recurring profileを作った後にPayPalから返されるprofile_id
を保存できるようにして、完成させます。ここで呼び出されるmake_recurring
メソッドはprofile_id
を含むresponse
を返すので、これをデータベースに保存します。先にpaypal_payment_token
フィールド用のためのmigrationを作成したときに、合わせてpaypal_recurring_profile_token
フィールドを作ったので、この値をそこに保存できます。
def save_with_paypal_payment response = paypal.make_recurring self.paypal_recurring_profile_token = response.profile_id save! end
繰り返しのPayPalの支払いを行うのに必要なコードがすべて完成したので、うまく動作するか試してみましょう。ホームページでI’m in Heaven”プランを選択してsubscriptionページで「PayPal」ラジオボタンをクリックすると、PayPalのサイトにリダイレクトされます。先に作ったテスト用のユーザ名とパスワードでログインできます。ログインして支払いを行うことを確認すると元のサイトにリダイレクトされてsubscriptionが完了します。
「Subscribe」ボタンをクリックすると、PayPalを介して新規のsubscriptionが正しく作成されます。
PayPalに関する今回のエピソードは以上です。通常よりも長くなってしまいましたが、これでも機能はまだ完全ではありません。プール金額が不十分な顧客やsubscriptionをキャンセルした顧客の処理も必要だからです。それらについては将来のエピソードでカバーするかもしれません。