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.