yamotonalds's blog

Webアプリケーション開発における技術メモが中心です。たまにWebサービス、興味を持ったデバイス、自作PCに関する話題もあるかも。Amazon好きなのでAmazon.co.jpアソシエイト使ってます。

ActiveMerchantでPayPal決済

PayPal決済を導入したのでその作業メモ。

各バージョンは以下の通り。

  • rails 3.2.13
  • activemerchant 1.34.0
  • vcr 2.5.0

 

最初、ウェブペイメントスタンダードが楽そうに見えたのだけれど決済後すぐに処理を行う必要があったのでエクスプレスチェックアウトに変更した。

ウェブペイメントスタンダードでも「即時支払い通知(IPN)」を使えばできるみたいだけど実装やテストが面倒になりそうだった。それに比べるとエクスプレスチェックアウトはActiveMerchantで簡単に実装できた。

 

大体は次のサイトに書かれている通りに実装すればOK。

Cody Fauser - PayPal Express Payments with ActiveMerchant

 後、config/environment.rbに次の記述を追加しておく。

ActiveMerchant::Billing::PaypalExpressGateway.default_currency = "JPY"

しかしこのままだとPayPalのページに遷移した際に商品名や金額が表示されない。試行錯誤の上、setup_purchaseを次のように変更した。

setup_response = gateway.setup_purchase(product.price * 100,
  ip: request.remote_ip,
  return_url: return_url,
  cancel_return_url: cancel_return_url,
  allow_note: false,
  no_shipping: true,
  items: [{
    name: product.name,
    number: product.id,
    quantity: 1,
    amount: product.price * 100,
  }],
)

 itemsで商品名や金額を指定することでPayPalのページにそれらが表示される。金額を100倍しているのはJPYを指定していても下2桁はセントだか銭だかの扱いになるようだから。100倍すると意図した日本円の金額になる。

 

有効なオプションのリストと説明が見つからなかったのでActiveMerchantのソースコードを読んで対応した。どこかに書いてあったのだろうか…。

デバッグは次のページのようにログ出力を有効にすると通信の内容がわかって楽だった。

http://nhw.pl/wp/2010/10/04/activemerchant-dumping-traffic-between-your-app-and-payment-gateway

 具体的には以下の記述をconfig/development.rbに追加する。

ActiveMerchant::Billing::PaypalExpressGateway.wiredump_device = File.new(File.join([Rails.root, "log", "paypal.log"]), "a")
ActiveMerchant::Billing::PaypalExpressGateway.wiredump_device.sync = true

 

テストは少し面倒だった。setup_purchaseの後、PayPalのページで支払いに同意しないと以降の処理でエラーになるからだ。

あまり良い方法ではないかもしれないがVCRと手作業を組み合わせることで自動テストを実行できるようにした。

手順は以下の通り。

  1. setup_purchaseをVCRで記録し、PayPalのページのURLを出力しておく。(IPアドレスは自分のグローバルIPにしておく。)
  2. ブラウザで先ほど出力したURLを開き、支払いに同意する。
  3. purchase等、以降の処理をVCRで記録する。(setup_purchaseは1で記録したものを使用する。)

これで一連の決済トランザクションをVCRで記録できたことになる。

 

ActiveMerchantを使うことで簡単にPayPal決済を実装できた。

決済直後に処理を行う必要が無く、 確認が目視でもOKならウェブペイメントスタンダードがHTMLコードを貼付けるだけなので一番楽だと思う。