RailsでPayPal

active_paypal_adaptive_payment
自己紹介
• 水谷 裕生(みずたに ひろたか)
• Railsエンジニア
• Twitter: @icb54615
システム概要
• いわゆるマーケットプレイス
• サービスを提供する人と受ける人を結びつけ
  るプラットフォーム
• サービスを予約した際にPayPalで決済
• プラットフォーム事業者に金額の何割かの手
  数料を支払い
• 残りはサービス提供する人に支払い
• 予約期限までは予約のキャンセルが可能で、
  支払らった金額を返金
¥サービス料
                                 ¥手数料を引いた料
                                   金

             ¥返金
サービスを受ける人            プラットフォーム事業          サービスを提供する人
   Sender              Primary者
                              Receiver       Secondary Receiver
仕様
• Adaptive Payments APIを使用
• active_paypal_adaptive_payment gemを
  使用
• Pay APIでDelayed Chained Paymentsによ
  る支払い
• Refund APIで支払いの返金
• 予約期限が過ぎたらExecutePayment API
  でサービスを提供する人に支払い
Adaptive Payments API
• 支払いを他の口座に入金が可能
• 自分の口座から他の口座への送金が可能
• 一回の支払いで複数の口座への支払いが可能(Parallel
  Payments)
• 複数の口座への支払いを代理窓口として処理する事が可能
  (Chainned Payments)

注意点:
• ビジネスアカウントが必要
• 本番環境で運用するには、App IDをX.comから取得が必要
• Chainned Payments のような“advanced”な処理をする場合
  はPayPalの事前審査が必要
  ⇒審査に10-15日程度かかる場合がある
active_paypal_adaptive_payment

• Gemfileにgemを追加してbundle install
• 設定ファイルを追加
• PayPalが開発用に用意しているSandboxの
  アカウントを登録して、その値を設定
  ファイルに記述
Gemfile:
gem 'active_paypal_adaptive_payment'



config/initializer/paypal.rb:
unless Rails.env.production?
  ActiveMerchant::Billing::Base.mode = :test
end
PaypalGateway = ActiveMerchant::Billing::PaypalAdaptivePayment.new(
 :login     => "hirotaka_1338865312_biz_api1.example.com",
 :password => "1338863333",
 :signature => "GKo3jGgDxJIjdH5V9tmlOoZlBDOzAMqkRgLDpvlxuu….",
 :appid     => "APP-80W284485P519543T"
)
Pay APIでDelayed Chained
  Paymentsによる支払い
def pay
  primary_receiver   = {
                            :primary => true,
                            :email   => "primary_receiver@example.com",
                            :amount => 5000
                      }
 secondary_receiver = {
                            :primary => false,
                            :email   => "secondary_receiver@example.com",
                            :amount => 4000
                           }
 r = PaypalGateway.setup_purchase(
                                      :action_type => "PAY_PRIMARY",
                                      :receiver_list => [primary_receiver, secondary_receiver],
                                      :currency_code => "JPY",
                                      :error_language => "ja_JP",
                                      :return_url => url_for(:action=> :complete_payment),
                                      :cancel_url => url_for(:action=> :cancel_paypal_payment),
                                     )
 if !r.success? || !r["pay_key"]
   message = "ご迷惑おかけしております。システムエラーが発生しました。"
    redirect_to url_for :action => error, :notice => message and return
  end
  payment = Payment.new
  payment.pay_key = r["pay_key"]
  payment.status = r["payment_exec_status"]
  redirect_to PaypalGateway.redirect_url_for(r["pay_key"])
end
Refund APIで支払いの返金
 • Rufund APIをpayKeyで呼び出す
def cancel
  payment = Payment.find(params[:id])
 r = PaypalGateway.refund(
                              :pay_key => payment.pay_key,
                              :currency_code => "JPY"
                          )
  unless r.success?
    redirect_to :action => :error
  end
end
予約期限が過ぎたらExecutePayment
 APIでサービスを提供する人に支払い
• statusが”INCOMPLETE”を対象
• ExecutePayment APIをpayKeyで呼び出し
• runnerで定期的に実行
Payment.where(:status => "INCOMPLETE").each do |payment|
 r = PaypalGateway.execute_payment :pay_key => payment.pay_key
 if r.success? && r["payment_exec_status"]
   payment.status = r["payment_exec_status"]
 else
   raise "PayPal connection error or unexpected response"
 end
  payment.save
end
その他感想など
• いろいろな支払いの仕方ができるので、どのやり方が
  いいのか悩む
• active_paypal_adaptive_paymentのドキュメントが全
  部のAPIをカバーしていない
  – Pay APIに対応するメソッドがわからない。
    ActiveMerchant::Billing::PaypalAdaptivePayment::setu
    p_purchaseがPay APIを呼んでるのはソースを見て確認。
  – どんなオプションをわたすのがわからない。
  – あとAPIに渡すキーの名前が、例えばpayKeyがpay_keyだっ
    たり。
• PayPal Adaptive Payments Developer Guideは読み込
  まないといけないけど英語のみ
• App IDの申請も英語のみ

RailsでPaypal

  • 1.
  • 2.
    自己紹介 • 水谷 裕生(みずたにひろたか) • Railsエンジニア • Twitter: @icb54615
  • 3.
    システム概要 • いわゆるマーケットプレイス • サービスを提供する人と受ける人を結びつけ るプラットフォーム • サービスを予約した際にPayPalで決済 • プラットフォーム事業者に金額の何割かの手 数料を支払い • 残りはサービス提供する人に支払い • 予約期限までは予約のキャンセルが可能で、 支払らった金額を返金
  • 4.
    ¥サービス料 ¥手数料を引いた料 金 ¥返金 サービスを受ける人 プラットフォーム事業 サービスを提供する人 Sender Primary者 Receiver Secondary Receiver
  • 5.
    仕様 • Adaptive PaymentsAPIを使用 • active_paypal_adaptive_payment gemを 使用 • Pay APIでDelayed Chained Paymentsによ る支払い • Refund APIで支払いの返金 • 予約期限が過ぎたらExecutePayment API でサービスを提供する人に支払い
  • 6.
    Adaptive Payments API •支払いを他の口座に入金が可能 • 自分の口座から他の口座への送金が可能 • 一回の支払いで複数の口座への支払いが可能(Parallel Payments) • 複数の口座への支払いを代理窓口として処理する事が可能 (Chainned Payments) 注意点: • ビジネスアカウントが必要 • 本番環境で運用するには、App IDをX.comから取得が必要 • Chainned Payments のような“advanced”な処理をする場合 はPayPalの事前審査が必要 ⇒審査に10-15日程度かかる場合がある
  • 7.
    active_paypal_adaptive_payment • Gemfileにgemを追加してbundle install •設定ファイルを追加 • PayPalが開発用に用意しているSandboxの アカウントを登録して、その値を設定 ファイルに記述
  • 8.
    Gemfile: gem 'active_paypal_adaptive_payment' config/initializer/paypal.rb: unless Rails.env.production? ActiveMerchant::Billing::Base.mode = :test end PaypalGateway = ActiveMerchant::Billing::PaypalAdaptivePayment.new( :login => "hirotaka_1338865312_biz_api1.example.com", :password => "1338863333", :signature => "GKo3jGgDxJIjdH5V9tmlOoZlBDOzAMqkRgLDpvlxuu….", :appid => "APP-80W284485P519543T" )
  • 9.
    Pay APIでDelayed Chained Paymentsによる支払い
  • 10.
    def pay primary_receiver = { :primary => true, :email => "primary_receiver@example.com", :amount => 5000 } secondary_receiver = { :primary => false, :email => "secondary_receiver@example.com", :amount => 4000 } r = PaypalGateway.setup_purchase( :action_type => "PAY_PRIMARY", :receiver_list => [primary_receiver, secondary_receiver], :currency_code => "JPY", :error_language => "ja_JP", :return_url => url_for(:action=> :complete_payment), :cancel_url => url_for(:action=> :cancel_paypal_payment), ) if !r.success? || !r["pay_key"] message = "ご迷惑おかけしております。システムエラーが発生しました。" redirect_to url_for :action => error, :notice => message and return end payment = Payment.new payment.pay_key = r["pay_key"] payment.status = r["payment_exec_status"] redirect_to PaypalGateway.redirect_url_for(r["pay_key"]) end
  • 11.
    Refund APIで支払いの返金 •Rufund APIをpayKeyで呼び出す def cancel payment = Payment.find(params[:id]) r = PaypalGateway.refund( :pay_key => payment.pay_key, :currency_code => "JPY" ) unless r.success? redirect_to :action => :error end end
  • 12.
  • 13.
    Payment.where(:status => "INCOMPLETE").eachdo |payment| r = PaypalGateway.execute_payment :pay_key => payment.pay_key if r.success? && r["payment_exec_status"] payment.status = r["payment_exec_status"] else raise "PayPal connection error or unexpected response" end payment.save end
  • 14.
    その他感想など • いろいろな支払いの仕方ができるので、どのやり方が いいのか悩む • active_paypal_adaptive_paymentのドキュメントが全 部のAPIをカバーしていない – Pay APIに対応するメソッドがわからない。 ActiveMerchant::Billing::PaypalAdaptivePayment::setu p_purchaseがPay APIを呼んでるのはソースを見て確認。 – どんなオプションをわたすのがわからない。 – あとAPIに渡すキーの名前が、例えばpayKeyがpay_keyだっ たり。 • PayPal Adaptive Payments Developer Guideは読み込 まないといけないけど英語のみ • App IDの申請も英語のみ