How to Run Stripe Webhooks Locally
Today's article is going to be a bit niche, but nevertheless it's an issue I have run into on multiple projects and have finally reached a solid solution.
Stripe (and other payment solutions like PayPal) allows your application to listen to webhooks for all kinds of payment events (subscription updated, invoice creation, etc).
When trying to test payment events locally, we often resort to using our "live" test endpoints.
This is a huge pain when debugging payments, since you have to deploy your test environment for every single change.
Also, Stripe only gives you two environments: test mode, and live mode. This ends up being pretty limiting for the common "local, dev, qa, prod" environment setup.
We need a way to funnel webhook events to our locally running API. There are two options, one being a Stripe only solution, the other being applicable for any API using webhooks.
Stripe Only Solution
This one is a quicky.
- Install the Stripe CLI using
brew install stripe/stripe-cli/stripeon Mac or
scoop bucket add stripe https://github.com/stripe/scoop-stripe-cli.git && scoop install stripeon Windows
- Forward stripe events to your local server with
stripe listen --forward-to LOCAL_API_URL_HERE
Ultrahook is going to be our one-size-fits-all solution. What is ultrahook? It's an awesome, free tool that allows you to receive webhook events on localhost by funneling requests from the Ultrahook cloud (via your unique url), to your private endpoint (ex. localhost:8080). Once you try it, you won't ever go back.
If you haven't already, create an Ultrahook account to receive your API key.
gem install ultrahookon the command line. You may have to install
rubyfirst by running
brew install rubyon Mac, or perhaps this easy-installer for Windows.
echo "api_key: INSERT_API_KEY_HERE" > ~/.ultrahookso you don't have to pass in your API key on every ultrahook command
ultrahook stripe INSERT_DESTINATION_HERE, where the destination is your local endpoint (ex. localhost:8080/webhooks/stripe)
And that's it! Thank you Vinay Sahni for creating this!
Note for Teams
There are two approaches (that I've thought at least) you can take to get this setup for a team:
- Let each member create their own ultrahook account, and as part of the onboarding process, they add their listeners to Stripe.
- Use a master ultrahook account and share it with your team.
I think option 1 is the safer choice, although more tedious.
Create a New Stripe Account
This might seem a bit annoying, but it really makes your dev life easier.
I usually organize it as follows:
- Main Stripe Account -> live -> production
- Main Stripe Account -> test mode -> QA
- Test Stripe Account -> test mode -> local
Enjoy the fruits of your labor
It takes a hot minute to set this up, but once you do, you will be so happy you did. At least I was.
If anyone goes with this setup, I'd love to hear about your experience! Any ideas for improvements? Let me know.