Search code examples
ruby-on-railsrecurring-billingnet-http

Requesting data from an API using Net::HTTP before a user logs in?


I'm trying to integrate my Ruby on Rails application with CheddarGetter using their hosted payment pages (http://support.cheddargetter.com/kb/hosted-payment-pages/hosted-payment-pages-setup-guide).

I pretty much have everything figured out except for the last part -- checking customer data against their API to make sure that the customer is still active before letting him log-in your system.

Apparently it involves some sort of HTTP request, which to be honest I am not at all familiar with, sorry. Here's the code:

uri = URI.parse("https://yoursite.chargevault.com/status?key=a1b2c3d4e6&code=yourcustomercode")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
status = http.request(request).body

I'm wondering where exactly do I put this code?

I'm thinking put the following in my user_session.rb model:

class UserSession < Authlogic::Session::Base
  before_create :check_status

  private
  def check status
      # insert above code here
  end
end

But I'm not too sure..? I suspect there also has to be some if active? elsif cancelled? && pending? code in there, referring to the response that the CheddarGetter API will give you..

Would appreciate some direction, thanks..


Solution

  • I would recommend putting that in it's own module in the /lib directory and also wrapping the call in a Timeout in case the website you are trying to access is unavailable. I just made a generic example below, so you can tweak the time as needed.

    Inside /lib/customer_status.rb

    require 'timeout'
    module CustomerStatus
      class << self
        def get_status
          begin
            Timeout::timeout(30) {
              uri = URI.parse("https://yoursite.chargevault.com/status?key=a1b2c3d4e6&code=yourcustomercode")
              http = Net::HTTP.new(uri.host, uri.port)
              http.use_ssl = true
              http.verify_mode = OpenSSL::SSL::VERIFY_NONE
              request = Net::HTTP::Get.new(uri.request_uri)
              status = http.request(request).body
            } # end timeout
    
            return status
    
          rescue Exception => e
            # This will catch a timeout error or any other network connectivity error
            Rails.logger.error "We had an error getting the customer's status: #{e}"
          end
        end
      end
    end
    

    Then you can just call it like this:

    class UserSession < Authlogic::Session::Base
      # include the new module we added
      include CustomerStatus
    
      before_create :check_status
    
      private
      def check status
        raise someError unless (CustomerStatus.get_status.include?("active"))
      end
    end
    

    I'll let you add in the other logic for cancelled, pending etc states as well as passing in the customer info to the new module method. You may just want to use a switch statement for handling different states.


    Update

    Also, if you don't already have this in your config/application.rb file, make sure you include it so it adds the lib folder to the autoload path:

    module YourAppNameGoesHere
      class Application < Rails::Application
    
        # Custom directories with classes and modules you want to be autoloadable.
        config.autoload_paths += %W(#{config.root}/lib)
    
      end
    end