โšก WebhookFix

Stripe gave you a 401.
Get the complete handler โ€” not just a hint.

Select your provider and framework. WebhookFix generates the full handler โ€” raw body method, middleware exclusion, and edge runtime variant โ€” the three places every tutorial skips.

โš  The three places webhook handlers silently fail
1 Raw body consumed before verification โ€” framework parses JSON first, bytes mutate, signature fails
2 bodyParser not disabled correctly โ€” deprecated config in App Router, different pattern per framework
3 Auth middleware blocks the route โ€” Clerk/NextAuth returns 401 before your handler runs. Silent. No log.
Provider
Framework
Auth middleware installed? (Clerk / NextAuth / Better Auth)
Adds middleware exclusion config โ€” the silent 401 source most tutorials miss
Vercel Edge Runtime / Cloudflare Workers
Replaces Buffer with TextEncoder โ€” Buffer doesn't exist on Edge
Why webhook handlers fail
The raw body problem
Stripe, GitHub, and Shopify verify signatures against the exact bytes they sent. Your framework parses the body to JSON before you touch it. The re-serialized output differs in whitespace or key ordering. Signature fails โ€” not because of a secret mismatch, but because the bytes changed.
App Router vs Pages Router
Pages Router: export config = {api: {bodyParser: false}}. App Router: that config is deprecated and silently ignored. Use request.text() โ€” but call it before any other body read, or the stream is consumed.
The silent auth 401
Clerk and NextAuth run on every route by default. Stripe is not an authenticated user. The middleware intercepts your webhook route and returns 401 before your handler executes. Stripe retries. Your logs show nothing. The fix: exclude /api/webhooks from the matcher.
Edge Runtime: no Buffer
Buffer.from() doesn't exist on Vercel Edge Runtime or Cloudflare Workers. Use TextEncoder and the Web Crypto API instead. The HMAC algorithm is identical โ€” only the API changes.
I'm using Next.js App Router โ€” why does bodyParser: false not work?
That config is for Pages Router only. App Router uses the Web Fetch API. Call await request.text() first, verify the signature against that string, then parse to JSON yourself with JSON.parse(body). Never call request.json() before signature verification.
Stripe vs CLI signing secrets โ€” which do I use?
They are different. Dashboard-created endpoints have a secret starting whsec_. The Stripe CLI generates a different secret when you run stripe listen. Using the wrong one causes every verification to fail even though your code is correct.
Does this work on Vercel Edge Runtime?
Yes โ€” enable the Edge toggle above. Buffer doesn't exist on Edge. The generated handler uses the Web Crypto API (TextEncoder + crypto.subtle) which is available everywhere. Add export const runtime = 'edge' to your route file.
GitHub webhook vs Stripe โ€” same pattern?
Same raw body requirement, different header and algorithm. GitHub uses X-Hub-Signature-256 with HMAC-SHA256. Stripe uses Stripe-Signature with a timestamp-prefixed payload. The framework-level fix (raw body, middleware exclusion) is identical.
You might also need
๐Ÿ”€ CORSFixer
Fix wildcard, preflight, and credentials misconfig
๐Ÿ”‘ OAuthFixer
Diagnose invalid_grant, redirect_uri mismatch
๐Ÿ“‹ Pre-Launch Checklist
20 HTTP checks before you ship

Done with this tool?

20 HTTP checks before you ship โ€” security, CORS, cache, redirects, staging.

Pre-Launch Checklist โ†’
๐Ÿ“– HttpFixer Blog โ€” fix guides, explainers, and references โ†’