How to Test Webhooks Locally: Complete 2026 Guide

Published: (February 26, 2026 at 01:07 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Introduction

Testing webhooks during local development can be tricky because your localhost isn’t reachable from the internet. Services like Stripe, GitHub, or Shopify need a public URL to deliver HTTP POST requests to your webhook endpoint.

Tunneling Tools

ngrok

ngrok http 3000
  • Creates a public URL (e.g., https://abc123.ngrok.io) that forwards to localhost:3000.
  • Free tier URLs change on each restart; paid plans ($8‑25/month) provide stable URLs.

Cloudflare Tunnel (formerly Argo Tunnel)

cloudflared tunnel --url http://localhost:3000
  • Free and integrates with existing Cloudflare configuration.

localtunnel

npx localtunnel --port 3000
  • Open‑source alternative; reliability may vary.

Capture Services

Capture services act as an inbox for incoming webhooks, allowing you to inspect, store, and replay them later.

  • Permanent URL – e.g., https://thunderhooks.com/h/my-project.

Workflow

  1. Configure the provider (Stripe, GitHub, etc.) to send webhooks to the permanent URL.
  2. Webhooks are stored (typically 7‑30 days) and can be inspected via a dashboard.
  3. When ready, replay the captured webhook to your local tunnel URL.

Advantages over direct tunneling

  • No need to keep a tunnel alive 24/7; missed deliveries are queued.
  • Easy to replay the same payload multiple times for debugging.
  • Eliminates constant URL updates in provider configurations.

Trade‑off

  • Two‑step process (capture → replay) instead of direct forwarding, but often worth the flexibility.

Provider‑Specific Testing Tools

Stripe CLI

stripe listen --forward-to localhost:3000/webhooks/stripe
stripe trigger payment_intent.succeeded
  • Forwards live Stripe events to your local server.
  • Allows you to trigger test events on demand.
  • Works only with Stripe.

GitHub

  • No built‑in forwarding, but you can use the GitHub API to redeliver webhooks from the settings page.
ScenarioRecommended Tool
Quick debugging & inspectionCapture service
Integration testing (specific events)Provider CLI (e.g., Stripe CLI)
End‑to‑end testing with real eventsStable tunnel (ngrok paid tier, Cloudflare Tunnel)

Development Best Practices

  • Signature verification – Never skip it in development; enable it before production. See Stripe’s signature verification docs.
  • Environment variables – Store webhook URLs per environment (local, staging, production).
  • Idempotency – Webhooks may be delivered multiple times; ensure your handler can process duplicates gracefully. Test by replaying the same webhook.
  • Timeout handling – Respond with a 2xx status quickly (under 30 seconds). Offload heavy processing to background jobs.

Pre‑deployment Checklist

  • Handler returns 2xx status promptly
  • Signature verification is enabled
  • Duplicate deliveries are handled (idempotency)
  • Failures are logged with sufficient context
  • Retry logic for temporary failures is in place
  • Timeout handling works correctly

Resources

0 views
Back to Blog

Related posts

Read more »