#nima_webhooks
1 messages · Page 1 of 1 (latest)
👋 Welcome to your new thread!
⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1233021981008461924
📝 Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- nima_webhooks, 23 minutes ago, 22 messages
hi there!
Getting a SignatureVerificationError is quite common. It usually comes from two potential errors.
export async function onRequestPost(context) {
const { request, env } = context
// more code
let data, eventType
if (env.STRIPE_WEBHOOK_SECRET) {
let event
try {
const rawBody = await request.text()
const stripeSignature = request.headers.get('stripe-signature')
event = await stripe.webhooks.constructEventAsync(rawBody, stripeSignature, env.STRIPE_WEBHOOK_SECRET)
} catch (err) {
console.log(`⚠️ Webhook signature verification failed. Err:`, err.message)
return new Response(JSON.stringify({ error: err.message }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
})
}
// more code
}
first, can you check the value of STRIPE_WEBHOOK_SECRET? it should match the one you see in your Stripe CLI.
The secret is correct as its showing in the terminal for both server side and where I am "./stripe.exe listen --forward-to http://127.0.0.1:8787/webhook/postcheckout"
I suspect it's from rawBody or stripeSignature?
The error for this code is:
[wrangler:inf] POST /webhook/postcheckout 400 Bad Request (2ms)
⚠️ Webhook signature verification failed. Err: 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
assuming the secret is correct, then the payload you pass in the constructEvent function is probably not the raw payload. So you need to ensure that you get the raw body of the HTTP request that Stripe sent you, without any interference by your code or framework in the middle.
Ye, how do I do so?
If this "await request.text()" is not the correct way to do it, then how?
which language/frawork are you using? is this Node.js? are you using Express?
When i log it, i get:
that doesn't look like a raw body to me, but like a nicely formatted text. so that's the issue yes.
nodejs (no express)
The code you are looking at is Cloudflare Worker Functions syntax
How is a rawbody suppost to look?
when I log the raw body in Node it looks like this on my end:
<Buffer 7b 0a 20 20 22 69 64 22 3a 20 22 65 76 74 ... 2344 more bytes>
could you try using Express? that's what we use in our documentation: https://docs.stripe.com/webhooks/quickstart
I am using different routing. The Cloudflare worker is handling all routes, so the same syntax is not possible. So I need to make to a buffer somehow?
So I need to make to a buffer somehow?
no, you need to find a way to get the raw body without any modification from your code.
something like request.body or request.rawBody.
but not request.text() which is changing the rawbody
console.log("request.rawBody", request.rawBody)
console.log("request.body", request.body)
terminal:
request.rawBody undefined
request.body ReadableStream { locked: true, [state]: 'closed', [supportsBYOB]: true, [length]: 0n }
try request.body then
event = stripe.webhooks.constructEvent(rawBody, stripeSignature, env.STRIPE_WEBHOOK_SECRET)
⚠️ Webhook signature verification failed. Err: SubtleCryptoProvider cannot be used in a synchronous context.
Use `await constructEventAsync(...)` instead of `constructEvent(...)`
event = await stripe.webhooks.constructEventAsync(rawBody, stripeSignature, env.STRIPE_WEBHOOK_SECRET)
:warning: Webhook signature verification failed. Err: Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the _raw_ request body.Payload was provided as a parsed JavaScript object instead.
Signature verification is impossible without access to the original signed material.
Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing
hum... not sure. you'll need to find a way to get the raw body. you can read this, which contains some links with additional information: https://github.com/stripe/stripe-node?tab=readme-ov-file#webhook-signing
That just made me even more confused.
I'm really not familiar with "Cloudflare Worker Functions", so I don't know what the exact solution is. but you need to figure out how to get the raw body payload.
you could also try asking Stripe support, they will have more time to investigate the issue: https://support.stripe.com/contact
make sure to include all relevant information (code, error, etc.)
It is weird cuz a guy on the Cloudflare server says that it works with the "await request.text()". And the error does say that i can give a string (?). And he had a similar issue, but for him it was in production and he fixed it with:
Stripe(env.STRIPE_KEY, {
httpClient: Stripe.createFetchHttpClient(), // ensure we use a Fetch client, and not Node's `http`
});