Blog / Webhooks

To test webhooks locally: install the Stripe CLI and run stripe listen --forward-to localhost:3000/webhook to forward real Stripe events to your local server. For Shopify, use ngrok to expose your local port, then register the ngrok URL as a temporary webhook endpoint in your Shopify store. For GitHub, use smee.io or ngrok and update the webhook URL in repository settings.

How to Test Webhooks Locally: Stripe, Shopify, and GitHub

· 8 min read · Webhook monitoring

Webhooks require a publicly reachable URL. Your local development server doesn't have one. That gap is the core difficulty — the platform needs somewhere to send events, and localhost:3000 isn't it.

The solutions differ by platform. Stripe has a purpose-built CLI. Shopify and GitHub need a tunnel. This guide covers all three.

Why Is Testing Webhooks Locally Harder Than Testing APIs?

When you call an API, you initiate the request. You control the timing, the parameters, and you can run the call as many times as you need from any environment. Webhooks invert this: the platform initiates the request when an event occurs, and it needs your server to be publicly reachable when it does.

Three specific problems make this difficult in local development:

How Do You Test Stripe Webhooks Locally?

The Stripe CLI is the best tool for this. It creates a secure connection to Stripe and forwards real webhook events to your local server — including proper signatures — without any public URL.

Step 1: Install the Stripe CLI

# macOS
brew install stripe/stripe-cli/stripe

# Windows (Scoop)
scoop bucket add stripe https://github.com/stripe/scoop-stripe-cli.git
scoop install stripe

# Authenticate
stripe login

Step 2: Start forwarding events

stripe listen --forward-to localhost:3000/webhook

This command prints a webhook signing secret that starts with whsec_. Use this secret — not your production endpoint's secret — in your local handler to verify signatures. The CLI will print every event it forwards and the response your handler returns.

Step 3: Trigger test events

In a second terminal, trigger any Stripe event type:

stripe trigger invoice.payment_failed

# Other useful triggers
stripe trigger customer.subscription.deleted
stripe trigger checkout.session.completed
stripe trigger charge.refunded

The CLI sends a real Stripe event object to your local handler. Your handler processes it exactly as it would in production. The signing secret is valid, so signature verification passes.

You can also forward only specific event types: stripe listen --events invoice.payment_failed,customer.subscription.deleted --forward-to localhost:3000/webhook

How Do You Test Shopify Webhooks Locally?

Shopify doesn't have a CLI equivalent of stripe listen. The standard approach is ngrok: expose your local port with a public HTTPS URL, then register that URL as a webhook endpoint in your Shopify store.

Step 1: Start ngrok

ngrok http 3000

ngrok prints a public URL like https://a1b2c3d4.ngrok.io. This URL is publicly reachable and forwards to your local port 3000.

Step 2: Register the webhook in Shopify

Go to your Shopify admin → Settings → Notifications → Webhooks → Create webhook. Set the event (e.g. orders/create), set the URL to https://a1b2c3d4.ngrok.io/webhook, and save.

Shopify uses the X-Shopify-Hmac-SHA256 header for signature verification. Find your webhook secret in the Shopify admin webhook settings and use it in your handler.

Step 3: Trigger a test delivery

From the webhook settings page, click "Send test notification." Shopify sends a test payload to your ngrok URL, which forwards it to your local server. Watch your terminal for the incoming request.

For real event testing, trigger the actual event in your Shopify store — create a test order, process a refund, or update a product — and watch your handler respond in real time.

Remove the temporary ngrok webhook endpoint from your Shopify store when you're done. Leaving stale endpoints causes unnecessary failed delivery attempts.

How Do You Test GitHub Webhooks Locally?

For GitHub webhooks, you have two options: ngrok (same as Shopify) or smee.io, a free webhook proxy maintained by GitHub.

Option A: smee.io

Go to smee.io and click "Start a new channel." You get a URL like https://smee.io/AbCd1234. Install the smee client and start it:

npm install --global smee-client
smee --url https://smee.io/AbCd1234 --target http://localhost:3000/webhook

Register https://smee.io/AbCd1234 as the webhook URL in your GitHub repo (Settings → Webhooks → Add webhook). smee.io acts as a relay — GitHub sends events to the smee URL, and the smee client forwards them to your local server.

Option B: ngrok

ngrok http 3000

Register the ngrok URL as your webhook URL in GitHub repo or organization settings. GitHub signs deliveries with the X-Hub-Signature-256 header using the secret you set when creating the webhook.

To trigger test events, push a commit, open a PR, or use the "Redeliver" button in GitHub's recent deliveries log to resend an existing event.

What Should You Test in Your Webhook Handler?

Local testing should cover:

What Does Local Testing Miss?

Local testing with the Stripe CLI or ngrok is valuable but it cannot cover everything:

Local testing covers handler correctness. Production monitoring covers delivery reliability.

How Do You Test Webhooks in Staging?

Staging environments have public URLs, which eliminates the tunneling requirement. The main considerations:

FAQ: Testing Webhooks Locally

How do I test webhooks locally without a public URL?
For Stripe: use the Stripe CLI — run "stripe listen --forward-to localhost:3000/webhook" to forward real events to your local server. For Shopify and GitHub: use ngrok ("ngrok http 3000") to expose your local port with a public HTTPS URL, then register that URL as a temporary webhook endpoint in the platform settings.
What is the Stripe CLI webhook command?
Two commands: "stripe listen --forward-to localhost:3000/webhook" starts forwarding and prints a local webhook signing secret. "stripe trigger invoice.payment_failed" sends a test event of any type. Run listen first, then trigger in a second terminal.
Can I test Shopify webhooks locally?
Yes. Run "ngrok http 3000" to get a public HTTPS URL, then add a webhook in Shopify admin pointing to that URL. Shopify will forward events to your local server via ngrok. Delete the temporary endpoint when you're done testing.

Local testing verifies your handler. Production monitoring catches what testing misses. Connect Webhook Guardian to get alerted within 5 minutes of any failed delivery in production — with the payload, error, and a one-click replay link. Learn how it works →

Also see: Stripe webhook monitoring · Shopify webhook monitoring · GitHub webhook monitoring · Webhook best practices · How to know when a Stripe webhook fails