Fix Stripe Webhook Signature Verification on VPS
Budget: €30 – €250 EUR
STACK
• Node.js v20.20.0
• Express backend
• Stripe Checkout + Webhooks
• PM2 process manager
• Nginx reverse proxy
• Cloudflare proxy (SSL Full Strict)
• Ubuntu 22.04 VPS (Hetzner)
Architecture:
Cloudflare
↓
Nginx (HTTPS reverse proxy)
↓
Node.js (PM2)
↓
Express webhook endpoint
Webhook endpoint:
https://api.deadanglesinstitute.org/api/webhook
Testing is performed using Stripe CLI.
PROBLEM:
Stripe webhook signature verification works locally, but fails in production.
Local testing:
stripe listen --forward-to http://localhost:3000/api/webhook
Result:
200 OK
Webhook verified successfully
Production testing:
stripe listen --forward-to https://api.deadanglesinstitute.org/api/webhook
Result:
400 Bad Request
No signatures found matching the expected signature
Debugging confirms:
req.body → Buffer = true
Meaning the Express route receives a raw body, but the payload may be altered upstream (likely by Nginx or Cloudflare) before Stripe signature verification.
WHAT I NEED:
A developer to:
• Diagnose the cause of the Stripe webhook signature failure in production
• Configure Nginx and Express correctly to preserve the raw webhook payload
• Verify middleware order (express.raw() before body parsers)
• Test using Stripe CLI
• Ensure webhook verification succeeds and returns 200 OK
Deliverables:
• Working Stripe webhook verification in production
• Any necessary code or Nginx configuration changes
• A short explanation of the fix and proof of a successful webhook event
• Node.js v20.20.0
• Express backend
• Stripe Checkout + Webhooks
• PM2 process manager
• Nginx reverse proxy
• Cloudflare proxy (SSL Full Strict)
• Ubuntu 22.04 VPS (Hetzner)
Architecture:
Cloudflare
↓
Nginx (HTTPS reverse proxy)
↓
Node.js (PM2)
↓
Express webhook endpoint
Webhook endpoint:
https://api.deadanglesinstitute.org/api/webhook
Testing is performed using Stripe CLI.
PROBLEM:
Stripe webhook signature verification works locally, but fails in production.
Local testing:
stripe listen --forward-to http://localhost:3000/api/webhook
Result:
200 OK
Webhook verified successfully
Production testing:
stripe listen --forward-to https://api.deadanglesinstitute.org/api/webhook
Result:
400 Bad Request
No signatures found matching the expected signature
Debugging confirms:
req.body → Buffer = true
Meaning the Express route receives a raw body, but the payload may be altered upstream (likely by Nginx or Cloudflare) before Stripe signature verification.
WHAT I NEED:
A developer to:
• Diagnose the cause of the Stripe webhook signature failure in production
• Configure Nginx and Express correctly to preserve the raw webhook payload
• Verify middleware order (express.raw() before body parsers)
• Test using Stripe CLI
• Ensure webhook verification succeeds and returns 200 OK
Deliverables:
• Working Stripe webhook verification in production
• Any necessary code or Nginx configuration changes
• A short explanation of the fix and proof of a successful webhook event