Share this post on Twitter

Photo of Ross Boucher


Ross Boucher on February 1, 2012

After I launched my first paid product, the first thing I wanted to add was a feature that would play a cash register sound on our computer every time we got a sale. I was also terrified of adding any code to our production server so I never got around to it. Of course, the way fun but unimportant features like that should be written is by keeping the code as far away from your production server as possible. And with our new webhook system, that can be as far as you want.

Cash registers are fun, but there are far more practical reasons to use webhooks. Most commonly, users of our subscription billing features use webhooks to get notified when a customer's credit card gets charged for a subscription renewal. Webhooks make it easy to send the customer an email receipt (here's a simple sinatra example that does just that). This same system also lets you watch for customers who haven't paid their bill so you can take whatever action you need to, like reaching out to the customer or canceling their service.

Events and Webhooks

The webhook system is built on top of another new feature we just released, our events API. Events are now first class API objects in Stripe, and can be retrieved like our other API resources. 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. That event contains a type property, which tells you what kind of thing happened, and a data property that contains the specifics of what happened. The events API can be useful for more than just webhooks; you can use it to build your own internal news feed of Stripe activity, or to build and monitor your own analytics.

If events are the actual things that are happening, webhooks are us telling you that something happened. When you add a new URL to your webhook settings, Stripe will start sending an HTTP POST request to that URL on every event. And we now support having as many live and test URLs as you want, which means you can mix and match multiple different services to respond to Stripe events, which is a truly enabling tool. You can see a list of events in your dashboard, and each event's detail page shows a history of the related webhooks.

Out with the old and in with the new

Our old webhook system, which we're now calling legacy webhooks, had a few significant flaws that have now been resolved. Unlike before, webhooks are now retried once an hour for up to 3 days or until a 200 status code is returned. And now you can verify the authenticity of a webhook by retrieving the associated event object securely over our API.

Another important way that we've improved webhooks is by eliminating responses. Previously, Stripe would try to take some actions based on the response to invoice_ready webhooks. Unfortunately, this meant not having an opportunity for receiving any errors Stripe may generate when validating that response. Now, rather than listening for responses, Stripe explicitly waits for one hour after you receive all your invoice.created webhooks to give you an opportunity to make any needed changes before the invoice gets paid. Since updates are done with standard API calls, errors and request logs are easy to track.

Getting started

So, now that we've built it, you should start using it! You'll find a short tutorial on webhooks in our docs, and we've also prepared an upgrade guide for users migrating off legacy webhooks. (But don't worry, the old system will keep working until you do migrate.) The documentation includes all the available API methods and a complete list of event types.

Oh, I also cooked up a quick node.js example app to get you started on building your own cash register. Have fun!