Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: webhook error #314

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Fix: webhook error #314

wants to merge 1 commit into from

Conversation

joaoxmb
Copy link

@joaoxmb joaoxmb commented Mar 16, 2024

Following the current project, when I deploy to Vercel and the webhook is triggered, the following error is displayed:

❌ Error message: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? 
 If a webhook request is being forwarded by a third-party tool, ensure that the exact request body, including JSON formatting and new line style, is preserved.

Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing

Reading the documentation, I discovered that it could be related to the payload passed to the stripe.webhooks.constructEvent() function.

Currently:

...
export async function POST(req: Request) {
	const body = await req.text();
	const sig = req.headers.get('stripe-signature') as string;
	const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
	let event: Stripe.Event;
	
	try {
		if (!sig || !webhookSecret)
			return new Response('Webhook secret not found.', { status: 400 });
			
		event = stripe.webhooks.constructEvent(body, sig, webhookSecret);
		console.log(`πŸ”” Webhook received: ${event.type}`);
	} catch (err: any) {
		console.log(`❌ Error message: ${err.message}`);
		return new Response(`Webhook Error: ${err.message}`, { status: 400 });
	}
...

Solution:

...
import { NextRequest } from 'next/server';
import { headers } from 'next/headers';

export async function POST(req: NextRequest) {
	const body = await req.text();
	const sig = headers().get('stripe-signature') as string;
...

I changed the request type to NextRequest, and also used headers from Next for reading the header. With this change, I finally achieved success.

Note: When tested locally with Stripe CLI, it works perfectly; the error only occurs when deployed.

Copy link

vercel bot commented Mar 16, 2024

@joaoxmb is attempting to deploy a commit to the Vercel Solutions Team on Vercel.

A member of the Team first needs to authorize it.

@e-roy
Copy link

e-roy commented Mar 20, 2024

I tried this and it didn't seem to work for me. I did look at the same stripe documentation suggested above and changed my api/webhooks route to:

export async function POST(req: NextRequest) {
  const body = await req.text();
  // const sig = req.headers.get('stripe-signature') as string;
  const sig = headers().get('stripe-signature') as string;
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET as string;
  let event: Stripe.Event;
  console.log('πŸ””  Webhook received body:', body);
  console.log('πŸ””  Webhook received sig:', sig);
  console.log('πŸ””  Webhook received secret:', webhookSecret);

  const header = stripe.webhooks.generateTestHeaderString({
    payload: body,
    secret: webhookSecret
  });

  try {
    if (!sig || !webhookSecret)
      return new Response('Webhook secret not found.', { status: 400 });
    // event = stripe.webhooks.constructEvent(body, sig, webhookSecret);
    event = stripe.webhooks.constructEvent(body, header, webhookSecret);
    console.log(`πŸ””  Webhook received: ${event.type}`);
  } catch (err: any) {
    console.log(`❌ Error message: ${err.message}`);
    return new Response(`Webhook Error: ${err.message}`, { status: 400 });
  }

and it worked bypassing sig... which is NOT a good solution.

Doesn't this error suggest the problem is in the request body?

@ovy9086
Copy link

ovy9086 commented May 24, 2024

weird things is that running this locally does not produce an error. I forwarded my Stripe webhooks to my local machine and then I don't this error πŸ˜‘

maybe some Vercel middleware intercepts the Stripe Payload and then forwards it to our webhook... and that's causing a signature miss-match ? 🀷

help ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants