【问题标题】:Is there a PayPal IPN code sample for Ruby on Rails?是否有 Ruby on Rails 的 PayPal IPN 代码示例?
【发布时间】:2012-12-28 07:03:00
【问题描述】:

有几种语言的官方代码示例,但找不到适用于 Rails 的代码示例。

【问题讨论】:

    标签: ruby-on-rails paypal-ipn


    【解决方案1】:

    有一些 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
    

    【讨论】:

      【解决方案2】:

      我在这里发布了一个 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

      【讨论】:

      • 真的很有帮助,谢谢!尽管就像一个注释一样,如果他们真的希望它是安全的,就必须使用 OpenSSL::SSL::VERIFY_PEER
      • 这为我节省了大量的下午时间。我现在可以早点回家了。非常感谢!
      • 这为我节省了很多时间,谢谢!另外,请记住在不处于生产模式时使用 SANDBOX paypal URL 进行验证! (sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate)
      • 哦,关于“检查 txnId 是否以前没有被处理过”,这里有一个重要的问题。如果在“已完成”付款状态之前收到“待处理”付款状态,则它们都将具有相同的交易 ID。换句话说,为了澄清,您必须验证仅收到一个带有该 txn_id 的“已完成”通知。
      • url现在改了,搞了半天才发现问题。以下是新网址:live = 'https://ipnpb.paypal.com/cgi-bin' sandbox = 'https://ipnpb.sandbox.paypal.com/cgi-bin' uri = URI.parse(sandbox + '/webscr?cmd=_notify-validate')
      【解决方案3】:

      IPN 宝石

      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,然后将模拟器指向它。

      【讨论】:

        【解决方案4】:

        您可以这样做以获取 ipn 详细信息。结果将显示您是否已验证。您可以从 body 获取所有详细信息

        post '/english/ipn' 做

        url = "https://sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate&#{@query}"

        body = request.body.string

        result = RestClient.post 网址,正文

        结束

        【讨论】:

          【解决方案5】:

          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 令牌的真实性而被拒绝。
          【解决方案6】:

          查看ActiveMerchant gem,其中包括多个网关实现,其中包括Paypal's IPN

          HTH

          【讨论】:

          • 您知道是否所有国家/地区都支持 PayPal 付款标准?根据 Active Merchant 的文档,这些是受支持的 PayPal 网关: PayPal Express Checkout - US, CA, SG, AU PayPal Payflow Pro - US, CA, SG, AU PayPal Website Payments Pro (UK) - UK PayPal Website Payments Pro ( CA) - CA PayPal Express Checkout - 美国 PayPal 网站付款专业版(美国)- 美国
          • @joscas,对不起。我在英国和美国都使用过 AM 的 PayPal IPN,没有问题。抱歉,我无法提供进一步的帮助。
          【解决方案7】:

          我在我的一个项目中实现了 IPN,您的代码看起来不错。那么你面临的问题是什么?

          【讨论】:

          • 嗨罗文。是的,我的代码工作正常,感谢您的确认。我把它贴在这里是因为我花了一些时间才想出可行的解决方案,而且由于没有官方示例,我认为其他人可以从中受益。
          猜你喜欢
          • 2012-12-10
          • 2017-03-19
          • 2016-09-27
          • 2021-12-20
          • 1970-01-01
          • 2013-01-07
          • 1970-01-01
          • 2014-12-25
          • 2015-12-04
          相关资源
          最近更新 更多