#yen-webhook-node
1 messages ยท Page 1 of 1 (latest)
Hi
Hello! Can you show me screenshots of exactly what you're seeing where it says it's succeeed and where you're seeing the 400 POST error
Yeah ofcourse
Got to see this logs after doing this stripe listen --forward-to localhost:3000/api/stripe/webhook
And where are you seeing that the events succeeded?
2023-08-17 17:40:12 --> charge.succeeded [evt_3Ng8IrD7Shm9DtKO1c1vjT9m]
Doesnt that mean that the charge has succeeded?
Before i didn't get to see charge.succeeded
I only saw the 400 errors
But ive changed my code and now it shows me this
Ah no i am wrong
The charge.succeeded event works so I think that's why I am seeing that?
Let's back up for a second - the 400 errors are specifically for responding to the webhook event (as in we send the event to the endpoint you specified but we didn't get a response back). That doesn't prevent from charges from succeeding
Ah alright
In my server.js file I logged the signature const signature = req.headers['stripe-signature'];
Which logged my signature
Before signature logged undefined
But when logging this event = stripe.webhooks.constructEvent(buf, signature, webhookSecret); it returns undefined
Have you logged the webhoookSecret and buf to confirm they're what you expect?
Also just to make sure - your issue right now is that you're trying to get signature verification to work and see 200 successful responses from your webhook endpoint, right?
Yes, I think the problem might be the buf
And yes, i want to see a 200 succesfull response,
But I am not even sure what is expected from a buf
This is a piece of my webhook code:
export default async function handler(req, res) {
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const buf = await buffer(req);
const signature = req.headers['stripe-signature'];
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
let event;
try {
// if(!signature || !webhookSecret) return;
event = stripe.webhooks.constructEvent(buf, signature, webhookSecret);
res.status(200).send('OK');
} catch(error) {
console.log(event);
return res.status(400).send(`Webhook error: ${error.message}`);
}
So buf is my request, but I found out that the request body is not raw
And Stripe expects a raw request body right?
Yeah, for signature revification we definitely need the raw request body
Ah okay
Can i show the output of the bug variable?
Because webhookSecret and the signature have the correct data
I've checked it
webhook secret logs this:
we_1NdcdMD...
signature:
t=1692229813,v1=efdffe399709232d32134cc073cf4d8d4af16923df489852df1238156c5bf906fc,v0=be491312321e5c35135ae40126692726ffeed83b9630e20596f8b66c90a7059910e51a8
Yup feel free to share the buf
Also your webhook secret isn't correct
It should be seomthing like whsec_123
and you should get it from your stripe listen command
oh really.. oops my bad
Well here is my buf:
{
"id": "evt_3Ng96jD7Shm9DtKO1KkBRxwZ",
"object": "event",
"api_version": "2022-11-15",
"created": 1692289897,
"data": {
"object": {
"id": "pi_3Ng96jD7Shm9DtKO157pqBf4",
"object": "payment_intent",
"amount": 200,
"amount_capturable": 0,
"amount_details": {
"tip": {
}
},
"amount_received": 0,
"application": null,
"application_fee_amount": null,
"automatic_payment_methods": {
"allow_redirects": "always",
"enabled": true
},
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"client_secret": "pi_3Ng96jD7Shm9DtKO157pqBf4_secret_vfKDez34w113H5vzniQWqWI3C",
"confirmation_method": "automatic",
"created": 1692289897,
"currency": "eur",
"customer": null,
"description": null,
"invoice": null,
"last_payment_error": null,
"latest_charge": null,
"livemode": false,
"metadata": {
},
"next_action": null,
"on_behalf_of": null,
"payment_method": null,
"payment_method_options": {
"card": {
"installments": null,
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"processing": null,
"receipt_email": null,
"review": null,
"setup_future_usage": null,
"shipping": null,
"source": null,
"statement_descriptor": null,
"statement_descriptor_suffix": null,
"status": "requires_payment_method",
"transfer_data": null,
"transfer_group": null
}
},
"livemode": false,
"pending_webhooks": 2,
"request": {
"id": "req_kp6x7vO2PyH5up",
"idempotency_key": "7661f9a6-4636-46c8-9b8f-e6185541bf75"
},
"type": "payment_intent.created"
}
So the problem is my webhook secret?
I get my webhook secret from the .env file in my project
So i just pasted the secret in the .env and then accessed it like this ```
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
let event;
try {
// if(!signature || !webhookSecret) return;
event = stripe.webhooks.constructEvent(buf, signature, webhookSecret);
res.status(200).send('OK');
``
Could you elaborate this? and you should get it from your stripe listen command because I know this command can be used in the terminal. But I don't really understand how I could implement this in my code
While you're testing things out with the stripe CLI you typically use the stripe listen command, which works different than normal webhook endpoints and needs it's own webhook secret
Once you're ready to go to production you'd create a real webhook endpoint (through the dashboard or API) and that would give you a new webhook secret that you'd use in your code
Oooh, now I finally understand
It works locally (get a 200 response), but on production I still get a 400 error
And I have hosted my Next.js project with Vercel
It's likely that in production you're using the wrong webhook endpoint secret then
The webhook endpoint secret also starts with whsec right?
I found it under 'Signing secret'
And I have added that to Vercel's environment variables
Yup it should also start with whsec
are you still getting errors after confirming that's correct
Is it still not working?
Can you do the same logging you did locally for production and confirm you're seeing the right things?
Yes, one sec please!
I'll show you the error first:
StripeSignatureVerificationError: No stripe-signature header value was provided.
at parseEventDetails (file:///var/task/node_modules/stripe/esm/Webhooks.js:103:19)
at Object.verifyHeader (file:///var/task/node_modules/stripe/esm/Webhooks.js:65:102)
at Object.constructEvent (file:///var/task/node_modules/stripe/esm/Webhooks.js:10:32)
at handler (/var/task/.next/server/pages/api/stripe/webhook.js:53:29)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
type: 'StripeSignatureVerificationError',
raw: { message: 'No stripe-signature header value was provided.' },
rawType: undefined,
code: undefined,
doc_url: undefined,
param: undefined,
detail: undefined,
headers: undefined,
requestId: undefined,
statusCode: undefined,
charge: undefined,
decline_code: undefined,
payment_intent: undefined,
payment_method: undefined,
payment_method_type: undefined,
setup_intent: undefined,
source: undefined,
header: undefined,
payload: <Buffer 7b 22 65 76 65 6e 74 22 3a 22 63 68 61 72 67 65 2e 63 61 70 74 75 72 65 64 22 7d>
}
Interesting... so looks like there are issues with egetting the stripe-signature header on your production server
buf:
<Buffer 7b 22 65 76 65 6e 74 22 3a 22 63 68 61 72 67 65 2e 63 61 70 74 75 72 65 64 22 7d>
signature:
undefined
webhookSecret:
whsec_rC0tLaZSs4b4Z9Dsv6kTD8ePBheBF28I
The buf looks off
Helloe
HEllo! Sorry for the delay, Discord is really busy right now and I'm catching up on many other threads
I don't really understand your question overall unfortunately
I would recommend that you start fresh using https://stripe.com/docs/webhooks/quickstart for your language first which would help you get the signature from the header and the right payload
yen-webhook-node
Hmm, but I don't get why I should start over because everything works locally? The 400 error only occurs on production
And no problem
The problem is that Node.js makes this extremely hard if you don't do this right or have a different environment between dev and prod
I often recommend carefully reading through https://github.com/stripe/stripe-node/issues/356 to find the right configuration as it depends on your Node.js version, the framework you're using, third-party libraries, etc. It's really finicky sadly ๐ฆ
๐ฆ
Would it help to switch to another hosting platform?
And I am going to check your github link
I can't tell you, right now the next step is to carefully read through some of those comments and figure out what's different between your local/dev environment and your production environment
My local/dev environment is not different from my production environment tho
Only thing thats different are the data in my .env file
I mean something is different, otherwise it'd work right?
Like signature: undefined this isn't a Stripe issue, it's your code
You need to dump the raw header of the HTTP request you get to figure out what's happening
something is removing access to that header somewhere in your code/environment right?
Okay, thanks for helping me though
Im actually working for a person who doesn't have knowledge about coding, but I am building a webshop for him and I am an intern
And he keeps asking me if I can solve it faster
And if there are better and faster ways to host this
Could any of u guys write something for me so I can show some proof that it's not easy to solve? Like i have to do some research and experiment to find out whats going wrong ๐ฆ
No we can't sorry
My advice: you can skip signature verification entirely
There are other ways here to protect your code. For example add a "secret" in the URL like https://example.com/webhook?mysecret=discord123 and then have your code check that value, and if it's incorrect ignore the Event.
And then you can call the Retrieve Event API: https://stripe.com/docs/api/events/retrieve to get the data from Stripe to make sure it's a real Event.
that should mostly do it while you figure out signature verification later
I have to run, but at least that would unblock you. Signature verification is not a requirement it's just recommend for security reasons
Thats okay,