Subscribing to a namespace of event types

StripeEvent.subscribe 'customer.card.'do |event|
# Will be triggered for any customer.card.* eventsend

Securing your webhook endpoint

StripeEvent automatically fetches events from Stripe to ensure they haven't been forged. However, that doesn't prevent an attacker who knows your endpoint name and an event's ID from forcing your server to process a legitimate event twice. If that event triggers some useful action, like generating a license key or enabling a delinquent account, you could end up giving something the attacker is supposed to pay for away for free.

To prevent this, StripeEvent supports using HTTP Basic authentication on your webhook endpoint. If only Stripe knows the basic authentication password, this ensures that the request really comes from Stripe. Here's what you do:

Arrange for a secret key to be available in your application's environment variables or secrets.yml file. You can generate a suitable secret with the rake secret command. (Remember, the secrets.yml file shouldn't contain production secrets directly; it should use ERB to include them.)

Configure StripeEvent to require that secret be used as a basic authentication password, using code along the lines of these examples:

When you specify your webhook's URL in Stripe's settings, include the secret as a password in the URL, along with any username:

https://stripe:my-secret-key@myapplication.com/my-webhook-path

This is only truly secure if your webhook endpoint is accessed over SSL, which Stripe strongly recommends anyway.

Configuration

If you have built an application that has multiple Stripe accounts--say, each of your customers has their own--you may want to define your own way of retrieving events from Stripe (e.g. perhaps you want to use the user_id parameter from the top level to detect the customer for the event, then grab their specific API key). You can do this:

If you'd like to ignore particular webhook events (perhaps to ignore test webhooks in production, or to ignore webhooks for a non-paying customer), you can do so by returning nil in you custom event_retriever. For example:

Testing

Handling webhooks is a critical piece of modern billing systems. Verifying the behavior of StripeEvent subscribers can be done fairly easily by stubbing out the HTTP request used to authenticate the webhook request. Tools like Webmock and VCR work well. RequestBin is great for collecting the payloads. For exploratory phases of development, UltraHook and other tools can forward webhook requests directly to localhost. You can check out test-hooks, an example Rails application to see how to test StripeEvent subscribers with RSpec request specs and Webmock. A quick look:

Note: 'Test Webhooks' Button on Stripe Dashboard

This button sends an example event to your webhook urls, including an id of evt_00000000000000. To confirm that Stripe sent the webhook, StripeEvent attempts to retrieve the event details from Stripe using the given id. In this case the event does not exist and StripeEvent responds with 401 Unauthorized. Instead of using the 'Test Webhooks' button, trigger webhooks by using the Stripe API or Dashboard to create test payments, customers, etc.