How to Run Stripe Webhooks Locally

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.

The Problem

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.

The Solution

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.

  1. Install the Stripe CLI using brew install stripe/stripe-cli/stripe on Mac or scoop bucket add stripe https://github.com/stripe/scoop-stripe-cli.git && scoop install stripe on Windows
  2. Run stripe listen
  3. Forward stripe events to your local server with stripe listen --forward-to LOCAL_API_URL_HERE

Universal Solution

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.

  1. If you haven't already, create an Ultrahook account to receive your API key.

  2. Next, run gem install ultrahook on the command line. You may have to install ruby first by running brew install ruby on Mac, or perhaps this easy-installer for Windows.

  3. Run echo "api_key: INSERT_API_KEY_HERE" > ~/.ultrahook so you don't have to pass in your API key on every ultrahook command

  4. Run 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:

  1. Let each member create their own ultrahook account, and as part of the onboarding process, they add their listeners to Stripe.
  2. 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.