Paypalの即時支払い通知(IPN)の確認について

しょうもないことで躓いていたのでメモを残しておきます.


基本的には,注文管理ガイドのp.29〜とp.53〜を読めば分かるはず.
ただ,Sandbox環境ではポストバックのURLがhttps://www.paypal.com/cgi-bin/webscrではなくhttps://www.sandbox.paypal.com/cgi-bin/webscrに変更する必要があった.
IPN通知にtest_ipn変数が含まれているなら自動的にSandbox環境になるのだろうと思い込んでいたが,これは確認不足でhttps://www.paypal.com/cgi-bin/webscr?cmd=p/sell/ipn-test-outsideに書いてあった.
そして,Sandbox環境ではSSLの認証エラーが出てしまうので,証明書の検証は無効にした.本来はやってはイケないだろうがSandboxなので良しとしました.
検索している途中,文字コードの設定などについて書いてあるページhttp://d.hatena.ne.jp/poad1010/20100930/1285849044も参考にしたのですが,特に関係無いようでした.


以下sinatraでIPNの確認を行うコード

require 'sinatra'
require 'net/http'

post '/paypal_ipn' do
  raw_params = request.env["rack.input"].read.to_s + "&cmd=_notify-validate"

  # sandboxを使うときはSSLエラーが出るので証明書の検証をしない
  if params[:test_ipn]
    https = Net::HTTP.new("www.sandbox.paypal.com", 443)
    https.verify_mode = OpenSSL::SSL::VERIFY_NONE
  else
    https = Net::HTTP.new("www.paypal.com", 443)
  end
  https.use_ssl = true
  res = https.post("/cgi-bin/webscr", raw_params)

  if res.body == "VERIFIED"
    # 確認成功した場合の処理
    # 注文管理ガイドのp.29〜を参照
  elsif res.body == "INVALID"
    # 確認失敗した場合の処理
  else
    # その他の場合の処理
  end
end