vercel / nextjs-subscription-payments

Clone, deploy, and fully customize a SaaS subscription application with Next.js.
https://subscription-payments.vercel.app/
MIT License
6.4k stars 1.3k forks source link

Stripe webhook failing with Vercel Supabase extention #240

Closed ripuser closed 1 year ago

ripuser commented 1 year ago

Hi, I have the Supabase extension running and my app working locally and on Vecel. I also have Supabase set up to work locally and with the Vercel cloud env config.

When I run the preview webhook on my local and update the products (with the env vars config for the cloud DB) and the locally generated secret, it works, the products are updated on my Supabase cloud DB.

However, the Stripe Server Webhook just keeps throwing an error. I've set STRIPE_WEBHOOK_SECRET in my Vercel env vars and have repeatedly deleted, updated, and renewed the secret on the webhook and in Vercel, but I keep getting the same error.

Webhook Error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing

The thing is, this was working, but then I moved to a copy of the DB in another Supabase account, everything else works fine, it's just this webhook. I also re-ran the extension as part of this migration. I don't think this has anything to do with it.

Any ideas, please?

thorwebdev commented 1 year ago

When you update the env var, do you redeploy your project? In Vercel, env vars aren't automatically updated in the deployment, you need to redeploy in order for env var changes to be applied.

ripuser commented 1 year ago

Hi, yes I did indeed, Ive run through the process a number of times.

Set the updated secret (revealed, not ID) Redeploy with no build cache Update the product to trigger the webhook on Strip Dashboard

I get the same error :/

gooodsoil commented 1 year ago

You have to make sure that you using your localhost route, I had the same issue. When you run the webhooks command in stripe make sure it matches your endpoint as such: localhost:3000/api/webhooks

Second I would try printing out your env var to see what is actually being passed through. I noticed I added a comment after my key and that messed it up because env vars capture comments after them.

ripuser commented 1 year ago

thanks, @gooodsoil, the localhost webhook is working using: stripe listen --forward-to=localhost:3000/api/webhooks

Its the vercel webhook that isn't working, even though I have the STRIPE_WEBHOOK_SECRET set as an env var in Vercel and it 100% matches whats in Stripe under the Reveal Secret.

The vercel serverless function is definitely being hit, I have recreated the webhook as well and updated the secret again. This is the log error Im getting in Vercel. I also updated the API version in the webhook settings to the latest

❌ Error message: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?

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

micheltucker commented 1 year ago

I had the same issue and it was a space in the env variables on vercel. Carefully paste it into vercel and make sure there are no spaces!

ripuser commented 1 year ago

thanks @micheltucker , just checked and I have no spaces, honestly Im at my wits end :) Ive left no stone unturned.

micheltucker commented 1 year ago

thanks @micheltucker , just checked and I have no spaces, honestly Im at my wits end :) Ive left no stone unturned.

And the last thing, which I am sure you checked. If you are still using the /pages folder you need to make sure bodyParser is set to false

// Stripe requires the raw body to construct the event.
export const config = {
  api: {
    bodyParser: false
  }
};
gooodsoil commented 1 year ago

@ripuser did you find a solution?

ripuser commented 1 year ago

thanks, @micheltucker , Im using App Router, and I don't have any reference to bodyParser in the code.

@gooodsoil Unfortunately not, however, I've just spotted all the logic in the repo under helpers that running the updates:

https://github.com/vercel/nextjs-subscription-payments/tree/main/utils

I'm going to dive into this and debug this to see what I can find.

thanks!

mattmuller commented 1 year ago

I managed to resolve my issue.

What would be useful in the readme is a bit of a description on how things work in the code base. Its not clear what the role of the Supabase extension is or that the actual update logic is present in the code along with the webhook handler. Once I found this I could start to debug.

The second part is I had 2 issues, one was the webhook wasn't listening to the correct branch handler, so when I was deploying, the env vars were not updating on the same branch as the webhook was firing to (400 error), and the second was I had some auth set on the preview env in Vercel so I was getting a 401 after solving my first issue.

I figured out the branch issue pretty quickly when I was adding logging and it wasn't appearing in the Vercel logs.

Thanks all for the help,

Matt

kobekapoor commented 1 year ago

Hey @mattmuller , can you share specifically what you did to fix the error? I have the same problem!

abeisleem commented 1 year ago

I spent a shameful amount of time dealing with this and just resolved it.

It seems there are 2 webhook secrets:

1) the one provided in the sample code when setting up the new endpoint image 2) the other after the endpoint is created: image

They are different. (1) works in local development and (2) works when deployed to Vercel. IT EVEN SAYS IT IN THE COMMENT ABOVE (1).

I'm not sure what this is about and I tested several times to ensure I'm not hallucinating and can confirm, that's how it is.

Cheers, Abe

mattmuller commented 1 year ago

Oh yes, that old chestnut 😅

On Sat, 9 Sep 2023 at 16:30, Abe Isleem @.***> wrote:

I spent a shameful amount of time dealing with this and just resolved it.

It seems there are 2 webhook secrets:

  1. the one provided in the sample code when setting up the new endpoint [image: image] https://user-images.githubusercontent.com/29489334/266788818-8a722dc7-b1bb-47a8-ad1b-8f7a0887fe1c.png
  2. the other after the endpoint is created: [image: image] https://user-images.githubusercontent.com/29489334/266789046-dbfa9e58-21bb-47ea-a91d-d03d18af3474.png

They are different. (1) works in local development and (2) works when deployed to Vercel. IT EVEN SAYS IT IN THE COMMENT ABOVE (1).

I'm not sure what this is about and I tested several times to ensure I'm not hallucinating and can confirm, that's how it is.

Cheers, Abe

— Reply to this email directly, view it on GitHub https://github.com/vercel/nextjs-subscription-payments/issues/240#issuecomment-1712537687, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABB3DVHJNJAF2IGCMYPAOLXZSDRHANCNFSM6AAAAAA3X5CSRA . You are receiving this because you were mentioned.Message ID: @.***>

haramishra commented 1 year ago

For me, when I pasted the key, it added a new line, which caused the error. I removed the new line, and the error was fixed.

shsunmoonlee commented 1 year ago

This worked for me . change headers().get'Stripe-Signature') line to

const sig = req.headers.get('stripe-signature') as string;

I've opened a PR for it. Please approve @thorwebdev https://github.com/vercel/nextjs-subscription-payments/pull/242