Interacting with third party APIs like Stripe often suffers from two important problems:
- Services not directly responsible for making an API request may still need to know the response
- Some events, like disputed charges and many recurring billing events, are not the result of a direct API request
Webhooks solve these problems by letting you register a URL that we will POST anytime an event happens in your account. When the event occurs, for example when a successful charge is made in your account, Stripe creates an
event object. This object contains all the relevant information, including the type of event and the data associated with that event. Stripe then sends an HTTP POST request with the event object to any URLs in your account's webhook settings. You can find a full list of all event types in the API docs.
Configuring your webhook settings
Webhooks can be configured in the webhook settings section of the Stripe dashboard. Clicking Add URL will reveal a form to add a new URL for receiving webhooks.
You can enter any URL you'd like to have receive the events. The mode determines whether test events or live events are sent to this URL — if you want to send both live and test events to the same URL you need to create two separate settings (application webhooks do not follow this rule). You may add as many URLs as you like.
Receiving a webhook
Configuring your server to receive a new webhook is no different from creating any page on your website. With PHP, you might create a new .php file on your server; with a framework like Sinatra, you would add a new route with the desired URL. Remember, with webhooks, your server is the server receiving the request.
Webhook data is sent as JSON in the request's body. The full event details are included and can be used directly. Alternatively, the event is also available in the Stripe API. If security is a concern, or if it's important to confirm that Stripe sent the webhook, you should only use the ID sent in your webhook and should request the remaining details from the Stripe API directly. We also advise you to guard against replay-attacks by recording which events you receive, and never processing events twice.
With application webhooks, it's important to note that while only test webhooks will be sent to development applications, both live and test webhooks will be sent to production applications. We recommend that you check the livemode of the webhook before processing events.
Receiving webhooks with a CSRF-protected server
If you're using Rails, Django, or another web framework, your server may automatically check that POST request bodies it receives contain a CSRF token. This is an important security feature that helps protect you and your users from cross-site request forgery. However, it may also prevent your server from receiving legitimate webhooks. You may need to exempt from CSRF protection the Rails route or Django view you use to receive webhooks.
Responding to a webhook
To acknowledge that you received the webhook without any problem, your server should return a
200 HTTP status code. Any other information you return in the request headers or request body will be ignored. Any response code outside the 200 range, including 3xx codes, will indicate to Stripe that you did not receive the webhook. When a webhook is not received for whatever reason, Stripe will continue trying to send the webhook once an hour for up to 3 days.
- Payment receipt emails: Subscribe to charge.succeeded events and send your users an email
- Metered billing: Subscribe to invoice.created events and add new invoice items to the invoice by specifying the invoice's ID in the invoiceitem creation API call.