If you're integrating Stripe in a Node.js backend, you're likely using webhooks to handle events like checkout.session.completed. One of the common pitfalls during deployment is related to webhook signature verification failures, and recently, I ran into exactly this issue.
In this post, I’ll walk through the problem I faced, how I fixed it, and what best practices you can follow to avoid the same mistake.
app.post(
"/api/v1/webhook/stripe",
express.raw({ type: "application/json" }),
stripeWebhookHandler
);
// JSON body parser for all other routes
app.use((req, res, next) => {
if (req.originalUrl === "/api/v1/webhook/stripe") {
next(); // Skip body parsing for Stripe
} else {
express.json()(req, res, next);
}
});
This is required because Stripe needs access to the raw body to verify the signature using the stripe.webhooks.constructEvent() method.
**
❌ The Problem
**
After deploying to production, Stripe kept returning this error:
❗ "Webhook signature verification failed. No signatures found matching the expected signature for payload."
I was sure my raw body handling was correct, and the endpoint URL was accurate. Locally, everything worked using the Stripe CLI. But in production… webhook requests kept failing.
🔍 The Root Cause
Turns out the issue was very simple but easy to overlook:
👉 I was using the Test Mode webhook signing secret (whsec_...) in production, while Stripe was sending Live Mode events.
Stripe signs test and live events with different secrets, and if you mismatch them, signature verification will always fail — even if your code is perfect.
✅ The Fix: Environment-Based Configuration
To avoid this, I updated my environment variables and Stripe initialization code to handle different modes based on the environment
🧪 Bonus Tip: Use Stripe CLI for Local Testing
To test webhooks locally with the Stripe CLI:
stripe login
stripe listen --forward-to localhost:5000/api/v1/webhook/stripe
stripe trigger checkout.session.completed
Make sure your local environment uses the test mode secrets to match the CLI’s default behavior.
💡 Final Thoughts
Small mistakes like using the wrong webhook secret can cost you hours of debugging. If you're getting a "Webhook signature verification failed" error, double-check your mode (test/live) and environment configuration.
If this helped you, share it with someone struggling with Stripe setup — and happy coding! ⚡
Top comments (0)