Rails 3 - Chargify webhooks and how to test in development

This is a quick post on how to integrate chargify (subscription billing) webhooks into your Rails 3 app.

Create a sub-folder in your controllers folder called chargify

Create a new controller within this folder named "hooks_controller.rb". This files contents will be:

require 'digest/md5'
 
class Chargify::HooksController < ApplicationController
  protect_from_forgery :except => :dispatch_handler
  before_filter :verify, :only => :dispatch_handler
 
  EVENTS = %w[ test signup_success signup_failure renewal_success renewal_failure payment_success payment_failure billing_date_change subscription_state_change subscription_product_change ].freeze
 
  def dispatch_handler
    event = params[:event]
 
    unless EVENTS.include? event
      render :nothing => true, :status => 404 and return
    end
 
    begin
      convert_payload
      self.send event
    rescue Exception => e
      notify_hoptoad(e) #If you use hoptoad...
      render :nothing => true, :status => 422 and return
    end
  end
 
  def test
    Rails.logger.debug "Chargify Webhook test!"
      render :nothing => true, :status => 200
  end
 
  def signup_success
      render :nothing => true, :status => 200
  end
 
  def signup_failure
      render :nothing => true, :status => 200
  end
 
  def renewal_success
      render :nothing => true, :status => 200
  end
 
  def renewal_failure
      render :nothing => true, :status => 200
  end
 
  def payment_success
      render :nothing => true, :status => 200
  end
 
  def payment_failure
      render :nothing => true, :status => 200
  end
 
  def billing_date_change
      render :nothing => true, :status => 200
  end
 
  def subscription_state_change
      render :nothing => true, :status => 200
  end
 
  def subscription_product_change
      render :nothing => true, :status => 200
  end
 
  protected
  def verify
    if params[:signature].nil?
      params[:signature] = request.headers["HTTP_X_CHARGIFY_WEBHOOK_SIGNATURE"]
    end
 
 
    unless Digest::MD5::hexdigest(ENV['CHARGIFY_SUBDOMAIN_SHARED_KEY'] + request.raw_post) == params[:signature]
      render :nothing => true, :status => :forbidden
    end
  end
 
  def convert_payload
    if params[:payload].has_key? :transaction
      @transaction = Chargify::Transaction.new params[:payload][:transaction]
    end
 
    if params[:payload].has_key? :subscription
      @subscription = Chargify::Subscription.new params[:payload][:subscription]
    end
  end
end
 
# to put in the routes.rb file...
#  namespace 'chargify' do
#    match '/hooks' => "hooks#dispatch_handler", :via => "post"
#  end

In the above code, there was a commented section at the bottom advising to add the route into your routes.rb, do that!

Within the chargify web ui, go to the settings page for your site, and go to the webhooks preferences. Set the webhook URL to http://www.yoursite.com/chargify/hooks

Click send a test webhook from the chargify web ui, and you should see it be successful.

Note: to test in your dev environment, I recommend https://showoff.io, it works great for testing webhooks.

Go back to the controller, and put your application specific code that needs to be executed under the appropriate method (ie. under def subscription_state_change)

Note: The gist above is not my handy work, it was someone elses that I updated to be compatible with Rails 3, I take no credit for it.

By Joel Friedlaender