public
Created — forked from ryansch/hooks_controller.rb

Rails 3 Controller for Chargify Webhooks

  • Download Gist
hooks_controller.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
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

This fork fixes a few issues I experienced using rails 3.

  • Changed the required 'md5' to 'digest/md5'
  • changed the 'render :nothing' to 'render :nothing => true' throughout
  • changed the dispatch method to dispatch_handler due to naming conflict
  • updated the route to rails 3 format, also changed the action to match my above change.

To put context on how to use this. Create this controller in a "chargify" sub-folder under controllers. Add the route that is commented out at the bottom to your routes file. Then in your chargify web ui, under settings and webhooks, specify the address as http://www.yoursite.com/chargify/hooks

That is all that is required. If you want to test this in your dev machine, I recommend the https://showoff.io tool to expose your localmachine to the web, it works very well for testing these webhooks.

Also I had to change "MD5::hexdigest" to "Digest::MD5.hexdigest"

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.