Using Laravel Cashier to handle Stripe webhooks
This blog post was originally published a little while ago. Please consider that it may no longer be relevant or even accurate.
Stripe webhooks can be a little bit annoying to verify. In Laravel I've generally done it using the authorize
method of a FormRequest.
The implementation is simple enough: use Stripe to construct a Webhook event from the request and if an Exception
is thrown you know it's invalid. You need to provide the webhook secret in order to build this event.
However, I've found that it's super easy to use Laravel Cashier to do most of the legwork for you here, and you get a beautiful syntax for handing those webhooks too.
Install Cashier
Run composer require laravel/cashier
to install the package.
Ignore Cashier's migrations
Call ignoreMigrations
in a service provider to prevent the framework from automatically running Cashier's migrations next time you migrate.
Add the API route
Register the route in routes/api.php
- not your regular web routes file.
Create the Webhook controller
Finally create a webhooks controller that extends Cashier's controller. You can then create methods that camelCase Stripe events and handle them - for example checkout.session.completed
is mapped to handleCheckoutSessionCompleted
and the payload is passed in as an argument.
Obviously there's a bit more code involved here than just using the custom authorize
in a form request. However I like the simplification of being able to offload that (and the tests involved) to a well maintained first-party package, and get a fluent interface to handle events.