All Posts
WebhooksTestingDeveloper Tools

How to Test Webhooks Locally and in Production — The Complete Developer Guide

Kiran MayeeMarch 28, 20269 min read

Webhooks are fire-and-forget by design. The sender makes a request, expects a fast response, and moves on. That makes debugging difficult: if your endpoint fails or your parser crashes, the payload is gone unless the provider retries. Reliable webhook testing requires capture, inspection, replay, and observability across both local development and production.

This guide gives a practical system you can use with Stripe, GitHub, and almost any webhook source.

Why Webhooks Are Hard to Debug

  • Requests come asynchronously and are not user-triggered in your UI.
  • Payload formats vary by provider and event type.
  • Signature verification fails silently when raw body handling is wrong.
  • Retries can cause duplicate processing if idempotency is missing.

Approach 1: Local Tunnel Tools (ngrok-style)

Tunnels expose localhost to the internet quickly. They are useful for first experiments, but they have tradeoffs:

  • ephemeral URLs unless you pay for static domains,
  • local machine dependency,
  • limited long-term event history for team debugging,
  • harder replay workflows across environments.

Approach 2: Webhook Receivers in moqapi.dev

Webhook receivers provide stable hosted URLs that capture every request. Instead of hoping logs include enough context, you inspect each delivery with headers, body, timestamp, status, and replay controls.

Step-by-Step Setup

  1. Create a receiver in moqapi.dev/dashboard.
  2. Copy receiver URL, for example https://hooks.moqapi.dev/r/abc123.
  3. Register this URL in provider webhook settings.
  4. Trigger test events from provider CLI or dashboard.
  5. Inspect captured payloads and headers.
  6. Replay any event to your local or staging consumer endpoint.

Stripe Example

Common events to test:

  • payment_intent.succeeded
  • invoice.payment_failed
  • customer.subscription.updated
curl -X POST "https://your-app.dev/webhooks/stripe"   -H "Stripe-Signature: test-signature"   -H "Content-Type: application/json"   -d '{"id":"evt_123","type":"payment_intent.succeeded","data":{"object":{"id":"pi_1"}}}'

In production, verify signatures using raw request body and your endpoint secret. Never parse JSON before signature verification if provider docs require raw bytes.

GitHub Example

Useful events include push, pull_request, and release. Verify X-Hub-Signature-256 with HMAC and reject mismatches.

const expected = "sha256=" + hmacSha256(rawBody, secret)
if (expected !== request.headers["x-hub-signature-256"]) {
  return new Response("Invalid signature", { status: 401 })
}

Payload Inspection Checklist

  • Event ID present and persisted for idempotency.
  • Event type mapped to correct handler.
  • Required nested fields validated before processing.
  • Response status returned quickly (usually 2xx under timeout budget).
  • Processing errors logged with correlation IDs.

Replay Is the Superpower

Replay lets you debug deterministicly. Instead of trying to re-create a complex provider event, replay the original captured payload into your latest code. This cuts mean-time-to-fix dramatically.

  1. Capture failing event in receiver history.
  2. Patch consumer code or config.
  3. Replay exact event to validate fix.
  4. Promote fix to staging and replay again.

Production Monitoring Strategy

Testing locally is not enough. In production, track delivery reliability continuously.

  • Success rate by provider and event type.
  • Median and p95 processing time.
  • Retry count and dead-letter patterns.
  • Signature failure rate (possible config or security issue).

Idempotency and Duplicate Events

Webhook providers may retry on timeouts or transient failures. Store processed event IDs and short-circuit duplicates. This prevents duplicate billing, repeated notifications, and inconsistent state transitions.

Local + Production Workflow That Works

1) Point provider to hosted receiver URL.
2) Inspect and validate payload structure.
3) Replay to local endpoint while developing.
4) Replay to staging before release.
5) Monitor production success/error metrics.
6) Keep replay history for incident analysis.

Webhook Failure-Mode Test Matrix

Reliable webhook integrations are built by testing specific failure modes, not just successful events. Add this matrix to your QA checklist:

  • Signature mismatch: endpoint must reject with 401 and log minimal sensitive data.
  • Duplicate event ID: endpoint should return 200 and skip side effects.
  • Out-of-order delivery: handler must tolerate stale state transitions.
  • Timeout to downstream DB: event should be queued or retried safely.
  • Malformed JSON body: reject early with clear error telemetry.

Incident Runbook for Production Webhooks

  1. Identify failing provider, event type, and first failure timestamp.
  2. Inspect captured payload and signature headers in receiver history.
  3. Replay event in staging with current release build.
  4. Patch handler or secret configuration.
  5. Replay original production payload before marking incident resolved.

This runbook shortens incident duration and avoids guesswork during high-pressure outages.

Security Hardening Checklist

  • Rotate webhook secrets on a schedule and after incidents.
  • Store raw payload hash for tamper diagnostics.
  • Restrict receiver access by environment and team role.
  • Alert on sudden signature failure spikes.

Security hardening turns webhook testing from ad-hoc debugging into a dependable operational system.

Also ensure your incident channel includes both backend and product owners, because webhook failures often have user-facing consequences such as delayed invoices, missing notifications, or stale account status updates.

When to Keep ngrok in the Toolbox

Tunnels still help for quick one-off local experiments. But for team workflows, repeatable debugging, and production-grade visibility, hosted receivers with replay are usually the stronger default.

Final Takeaway

Webhook reliability is not about guessing payloads in logs. It is about observable delivery pipelines: capture, inspect, replay, and monitor. Build that loop once and every future webhook integration becomes easier.

Create your first receiver URL at https://moqapi.dev/dashboard/webhooks.

Share this article:

About the Author

Kiran Mayee

Founder and sole developer of moqapi.dev. Full-stack engineer with deep experience in API platforms, serverless runtimes, and developer tooling. Built moqapi to solve the mock data and deployment friction she experienced firsthand building production APIs.

Ready to build?

Start deploying serverless functions in under a minute.

Get Started Free