This page covers tools and techniques for testing webhook integrations during development and debugging issues in production.

Local Development

Exposing Local Servers

Since webhooks need to reach your server from the internet, you’ll need to expose your local development server publicly.

Using Cloudflare Tunnels

Cloudflare Tunnels provide a free way to securely expose your local development server to the internet without requiring account registration or opening firewall ports:
# Download cloudflared from GitHub releases or use a package manager

# Expose your local server
cloudflared tunnel --url localhost:3000

# Example output:
# Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):
# https://abc123.trycloudflare.com
Use the provided URL in your webhook configuration:
{
  "url": "https://abc123.trycloudflare.com/webhook"
}

Debugging Common Issues

Webhooks Not Arriving

  1. Check URL accessibility – Ensure your endpoint is publicly accessible
  2. Verify HTTPS – Webhook URLs must use HTTPS
  3. Check firewall settings – Allow incoming connections to your webhook port
  4. Review event filters – Ensure you’re subscribed to the correct event types

Signature Verification Failing

  1. Check the secret key – Ensure you’re using the correct secret
  2. Verify raw body usage – Make sure you’re using the raw request body:
// ❌ Wrong - using parsed body
const signature = crypto
  .createHmac('sha256', secret)
  .update(JSON.stringify(req.body))
  .digest('hex');

// ✅ Correct - using raw body
app.use('/webhook', express.raw({ type: 'application/json' }));
app.post('/webhook', (req, res) => {
  const signature = crypto
    .createHmac('sha256', secret)
    .update(req.body) // Raw buffer
    .digest('hex');
});