Efficent webhook handling with Ruby on Rails

When implementing a payment system as Paypal or Stripe, the more tedious part is implementing webhooks. In this post I wil explain you a how you can optimize the webhook and get a clean and light implementation.

What are the Webhooks for?

Webhooks are endpoints in your application where a service like Paypal or Stripe will inform you about the events happening in them. Paypal and Stripe use them to notify whether a charge was successful or not, for example. This mechanism is necesary given the charges proccess are asyncronous. Ergo, in the moment we create a charge using thier API we won't know until in the future if the charge was successful or not.

Standard way

The webhook is just an endpoint (route or path) which receives information through POST method. In Rails a barebone implementation of Stripe webhook could be:

This webhook method uses a switch-case in order to determinate, with the event type that was received, which code block execute. Now imagine implement more events, this method will smell and get hard to maintain.

Sure we can write more methods to put the logic of each event and call them into the switch-case, however we can still improve this webhook method.

Cleaner way

The cleanest webhook implementation I've seen is in Laravel Cashier. Cashier's Webhook Controller allows you to handle automaticaly by mapping each event to a method. The controller convention says that if you want to handle the event invoice.payment_succeeded create a method in the controller whose name start with handle and the camelCase form of the event type: handleInvoicePaymentSucceeded.

Next level is to queue up jobs to process each webhook. You could exhaust the http connection pool if you get hammered with webhooks. Also, Stripe webhooks timeout (and retry!) if it takes a couple of seconds to process them.

I tend to persist the webhook payload in the DB and process it async. It makes debugging and replaying way easier.

Good stuff, but there are definitely lots of challenges with webhooks like what Philippe points out, signature verification, and more. They are always easy to get started with, but plenty of work lay ahead.