How Rubycoders uses Stripe webhooks
Cristiano - 2017-05-03
Rubycoders uses Stripe system in order to receive payments via credit card.
Stripe is a US technology company, operating in over 25 countries, that allows both private individuals and businesses to accept payments over the Internet. Stripe focuses on providing the technical, fraud prevention, and banking infrastructure required to operate on-line payment systems.
Rubycoders never keeps the credit card information in its local database. Therefore, it increases its security.
Stripe has a very powerful event system:
Whenever something interesting happens (like a new charge succeeding or failing, a customer changing their subscription, or an invoice being created), Stripe creates an event.
As soon as Stripe creates an event, it sends an HTTP POST request to a specific configured url which has been set consequently.
Once Rubycoders receives the request from Stripe, it analyzes it and then it launches the correct routine in order to manage the event.
For example, if the event is a
customer_subscription.created, Rubycoders sends an email to the customer making him aware of the successful subscription creation.
Stripe includes several types of events but Rubycoders is interested only in a couple of them. Indeed, we want to instantiate the correct routine for each event we would like to manage.
First of all, you have to set up the router in order to receive the http post request
#config/routes.rb resources :hooks, only: :create
then, set up the
create action in
#app/controllers/hooks_controller.rb class HooksController < ApplicationController def create event_manager = EventManager.new Event.retrieve(params[:id]) event_manager.manage render nothing: true, status: 201 rescue StripeError render nothing: true, status: 400 end end
The http post request contains the
id of the event. For that reason, we can recover the event through the
retrive method, offered by the
Event class which is here mentioned stripe-ruby gem
EventManager class is the core system. It is a simple Ruby PORO class which analyzes the incoming event and instantiates the correct corrisponding class.
Finally, in case everything was successfully done, the controller will answer with a
201 http code. Otherwise, the controller will answer with
This is the
#lib/event_manager.rb class EventManager attr_reader :event, :method, :clazz def initialize event @event = event @method = event.type.split(".").last.to_sym @clazz = event.type.split(".").tap(&:pop).map(&:capitalize).join end def manage clazz_istance.new(event).send method end private def clazz_istance clazz.constantize end end
If the event type is:
Then, we will have a class named
customer_subscription.rb which will contain the method
EventManager class instantiates dynamically the correct class analyzing the event type.
For example, the
customer_subscription.created event has the corresponding class and method
#lib/customer_subscription.rb class CustomerSubscription attr_reader :event def initialize event @event = event end def created #your logic here #for example you can send an email to customer end end
In this post only the basic system has been explained in order to make it as clear as possible. For that reason, the management of the exceptions was ignored. However, if there is an incoming event with any Ruby PORO class, the system will offer an exception to be managed.
It should be important to put PORO classes inside a namespace, like
StripeEventManager or similar ones.
To improve the security, it is better to accept the http requests only coming from Stripe web hooks domain.