Stripe Webhook

Last updated December 27, 20253 min read
TL;DR

To integrate Stripe webhooks with Hooklistener local tunnel:

  • Start your webhook handler locally: npm start
  • Authenticate the Hooklistener CLI: hooklistener login
  • Start a local tunnel: hooklistener tunnel --port 3000
  • Register the Hooklistener URL in Stripe: Add endpoint in Developers → Webhooks
  • Verify Stripe signatures in your app using your webhook signing secret

This guide covers how to use Hooklistener’s local tunnel to receive Stripe webhooks on a service running on your machine (for example, http://localhost:3000).

Stripe requires an HTTPS, publicly reachable endpoint for webhooks. Hooklistener provides a public HTTPS URL and forwards requests to your local server through the CLI over a persistent connection.

By integrating Hooklistener local tunnel with Stripe, you can:

  • Develop and test Stripe webhooks locally without deploying your code just to receive events.
  • Inspect incoming webhook traffic quickly via the CLI’s live request log (method, path, status, duration).
  • Troubleshoot webhook delivery while keeping your local server as the source of truth for responses (status/headers/body are returned back to Stripe through the tunnel).

1. Start your app

Run a local HTTP server that can receive Stripe webhook requests.

Implement (or use) a webhook endpoint in your app (for example: POST /webhook).

Start your app on a local port (this guide uses 3000).

Example:

npm start

You can validate your app is running by visiting http://localhost:3000 (or by sending a test request to your webhook route, e.g. http://localhost:3000/webhook).

2. Login to Hooklistener CLI

Authenticate the CLI so it can create tunnels on your behalf using a device-code flow.

Run:

hooklistener login

Follow the CLI instructions:

  • Open the provided URL in your browser.
  • Enter the displayed code to authorize the CLI.

Once you’ve authorized the CLI, you’re ready to start a tunnel.

3. Start a local tunnel

Start a public HTTPS endpoint that forwards traffic to your local server.

Run a tunnel to your local port:

hooklistener tunnel --port 3000

Copy the public URL shown by the CLI (for example, https://azeq2f.hook.events).

How routing works: Hooklistener forwards the path as-is to your local server. For example, requests to https://<your-subdomain>.hook.events/webhook are delivered to http://localhost:3000/webhook.

Info:The CLI keeps a persistent outbound connection to Hooklistener (commonly over WebSockets), which helps it work even behind NAT/firewalls. If your network changes (VPN/Wi-Fi sleep/roam), you may need to restart the tunnel if you see connection reset/protocol errors.

4. Setup webhook

Register your Hooklistener public URL as a Stripe webhook endpoint.

  1. Sign in to the Stripe Dashboard.
  2. Go to Developers → Webhooks.
  3. Click Add an endpoint.
  4. In Endpoint URL, enter your Hooklistener URL plus your webhook path.

Example:

https://<your-subdomain>.hook.events/webhook
  1. Click + Select events and choose the events your local app handles.
  2. Click Add endpoint.

Run webhooks with Stripe and Hooklistener

Trigger an event and confirm it reaches your local server.

  • In Developers → Webhooks, open the endpoint you just created.
  • Use Stripe’s Send test webhook option (or trigger real activity, like creating a test object in Stripe).
  • Watch your Hooklistener CLI:
    • You should see each request appear in the live request log with status and duration.
    • Confirm your app logs/handles the event as expected.

Inspecting requests

Use the Hooklistener CLI’s tunnel UI/log to debug webhook delivery in real time.

This is useful to:

  • Confirm Stripe is reaching your public endpoint
  • See which path Stripe is calling (e.g., /webhook)
  • Check response status codes (e.g., 2xx vs 4xx/5xx) and latency

Replaying requests

Hooklistener local tunnel forwards requests; for “replays,” re-send events from Stripe.

Options:

  • From Stripe Dashboard: Developers → Webhooks → your endpoint → Send test webhook
  • If you use the Stripe CLI in your workflow: re-trigger the same event type to generate another delivery

Your local server will receive the replayed webhook through the same Hooklistener URL.

Secure webhook requests

Your Hooklistener URL is public, so your app should still verify Stripe webhook signatures using the endpoint’s signing secret.

  1. In Stripe Dashboard, go to Developers → Webhooks and select your endpoint.
  2. Under Signing secret, click Reveal and copy the secret.
  3. Verify the Stripe-Signature header in your webhook handler using Stripe’s official libraries (recommended by Stripe).

Info:Treat the Hooklistener public URL like a secret webhook endpoint (don’t post it publicly), and always validate incoming webhook signatures before processing events.