【发布时间】:2012-12-28 07:03:00
【问题描述】:
有几种语言的官方代码示例,但找不到适用于 Rails 的代码示例。
【问题讨论】:
有几种语言的官方代码示例,但找不到适用于 Rails 的代码示例。
【问题讨论】:
有一些 PayPal gem,其中至少一个 (paypal-sdk-rest) 包含 PayPal::SDK::Core::API::IPN.valid? 方法。
使用方法如下:
class YourController < ApplicationController
skip_before_action :verify_authenticity_token, only: :your_action
def your_action
verified = PayPal::SDK::Core::API::IPN.valid?(request.raw_post)
if verified
# Verification passed, do something useful here.
render nothing: true, status: :ok
else
# Verification failed!
render nothing: true, status: :unprocessable_entity
end
end
end
【讨论】:
我在这里发布了一个 Rails 控制器的工作代码示例。它进行验证。希望对你有用。
class PaymentNotificationsController < ApplicationController
protect_from_forgery :except => [:create] #Otherwise the request from PayPal wouldn't make it to the controller
def create
response = validate_IPN_notification(request.raw_post)
case response
when "VERIFIED"
# check that paymentStatus=Completed
# check that txnId has not been previously processed
# check that receiverEmail is your Primary PayPal email
# check that paymentAmount/paymentCurrency are correct
# process payment
when "INVALID"
# log for investigation
else
# error
end
render :nothing => true
end
protected
def validate_IPN_notification(raw)
live = 'https://ipnpb.paypal.com/cgi-bin'
sandbox = 'https://ipnpb.sandbox.paypal.com/cgi-bin'
uri = URI.parse(sandbox + '/webscr?cmd=_notify-validate')
http = Net::HTTP.new(uri.host, uri.port)
http.open_timeout = 60
http.read_timeout = 60
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.use_ssl = true
response = http.post(uri.request_uri, raw,
'Content-Length' => "#{raw.size}",
'User-Agent' => "My custom user agent"
).body
end
end
代码的灵感来自Railscast 142 和这篇文章来自Tanel Suurhans
【讨论】:
live = 'https://ipnpb.paypal.com/cgi-bin' sandbox = 'https://ipnpb.sandbox.paypal.com/cgi-bin' uri = URI.parse(sandbox + '/webscr?cmd=_notify-validate')
DWilke 的 Paypal IPN gem 可以在这里找到:
https://github.com/dwilkie/paypal
查看 IPN 模块。代码不错:
https://github.com/dwilkie/paypal/blob/master/lib/paypal/ipn/ipn.rb
您可以在此处针对 IPN 模拟器对其进行测试:
https://developer.paypal.com/webapps/developer/applications/ipn_simulator
我使用 ngrok 在公共 URL 上公开 localhost:3000,然后将模拟器指向它。
【讨论】:
您可以这样做以获取 ipn 详细信息。结果将显示您是否已验证。您可以从 body 获取所有详细信息
post '/english/ipn' 做
url = "https://sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate&#{@query}"
body = request.body.string
result = RestClient.post 网址,正文
结束
【讨论】:
PayPal 的 Ruby Merchant SDK 提供了一个 ipn_valid? 布尔方法,让您轻松完成这项工作。
def notify
@api = PayPal::SDK::Merchant.new
if @api.ipn_valid?(request.raw_post) # return true or false
# params contains the data
end
end
https://github.com/paypal/merchant-sdk-ruby/blob/master/samples/IPN-README.md
【讨论】:
protect_from_forgery except: [:notify] 添加到您的控制器中,这样POST 不会因为无法验证CSRF 令牌的真实性而被拒绝。
查看ActiveMerchant gem,其中包括多个网关实现,其中包括Paypal's IPN。
HTH
【讨论】:
我在我的一个项目中实现了 IPN,您的代码看起来不错。那么你面临的问题是什么?
【讨论】: