#Ema.webhook-environments
1 messages ยท Page 1 of 1 (latest)
Hey! By 2 webhooks do you mean 2 separate handlers (code) or 2 different webhooks configured with Stripe?
Oh hi ynnoj! Talking to you has become a daily thing ๐
The latter!
router.route("/webhook").post( async (req, res) => {
const sig = req.headers['stripe-signature']
let event;
let user;
try {
event = stripe.webhooks.constructEvent(req.rawBody, sig, keys.STRIPE_WH_SECRET)
} catch(e) {
console.log("Webhook error: " + e)
res.status(400).json(e)
}
switch(event.type){
//events
}
res.sendStatus(200);
}
this is what my code looks like right now
So both webhooks are pointing to the same endpoint?
no
one is pointing to my prod server, one is pointing to staging
and they, of course, have two separate secrets
Hmm, I'm struggling to understand what the issue is. Can you re-clarify? (sorry probably me pre-coffee)
The webhooks are both firing when I checkout in a server, intended behavior would be only the right one gets executed
let's say I have server-prod.com and server-staging.com, which have separate webhooks.
I want the webhook for server-prod.com to work when I'm coming from server-prod.com, and not the staging one, and vice-versa
Right now, both webhooks get executed regardless of the server I'm running this on
Hmm, the webhook should only fire for events pertinent to the environment it's created in. For example, if you have a payment_intent.succeeded event in live then only your live webhook should receive those events
Can you share your account ID? (acct_xxx)
Perfect thanks! I can't see any live environment webhooks configured for the account
I'm still in a testing phase, so there's no live environment webhook!
They're both testing webhooks because we aren't ready to go live yet
but they're based on different servers right now
try {
event = stripe.webhooks.constructEvent(req.rawBody, sig, keys.STRIPE_WH_SECRET)
} catch(e) {
console.log("Webhook error: " + e)
res.status(400).json(e)
}
Ah, now I see! Like I said, pre-coffee ๐
shouldn't this code snippet kill the webhook if the stripe_wh_secret isn't what the webhook expects?
Seems so yeah. It should return a 400 HTTP response plus the error
I'll have a look at your events, one second
I am rebuilding my prod server just in case I had some old code leftover XD
Is there a particular event you're testing? Just so I can filter them
these events are the ones the webhook tests
first one is prod server, last one is staging. I was testing staging and it still executed the prod webhook
Okay so looking specifically at this event from this morning: https://dashboard.stripe.com/test/events/evt_1JwlZYK4b2fM2OBho2S6IMsz
Your 'production' endpoint returned a 400 error (seemingly the try/catch around the event construct)
I was looking at the ones that happened right after that one, that one didn't have the prod change I just pushed yet
so the ones ~11 mins afte rthe one you linked
Ok so delivery to your staging webhook timed out and production succeeded
that's also super weird because it should have been the opposite LOL
By the way you can see this on that page you just linked (not sure if you knew that)
Not sure why it's timing out? Is it deployed?
I see the clock and checkmark but no info about what they returned
But if you were expecting it the other way round then I guess you have you webhook signing secrets mixed up
Click the little caret
I am going to try once more and see what happens because maybe the builds weren't deployed yet and that's the reason for timeout
sorry bout the hassle :(
Np!
Okay, 12:06 PM, tried again after deployment, now staging webhook gives 4 green checks while I am still experiencing the same situation on prod webhook
Staging (to be expected)
Prod (should not fire at all)
Why should it not fire?
Because I am currently working on the staging server, so the request should only go to the staging webhook
that is what I am trying to achieve
sorry if it wasn't clear earlier :p
Then just disable the webhook in your Dashboard. This is working as intended as you have configured 2 webhooks to listen for the same events in your Stripe test environment
Oh so there is no way in code to make it so that only the webhook with the corresponding secret goes through?
Once we'll actually ship and move to a live environment this issue will, clearly, not exist anymore but I was wondering if there was a temporary "patch" for that
Well yeah, that's what you have. But right now your production webhook is timing out
So it's not even getting to that point in the code
Yeah unresponsive for some reason. Generally we timeout within ~20 seconds (we recommend returning a 2xx response immediately)
I will try executing the prod webhook and see what happens
I think I know what causes the timeout
but that means it's getting past the check of webhook secret for some reason
while what I'd want is getting a 400 back because I am trying to "access" the wrong webhook
That's the purpose of the signing secret โ so that unsigned/incorrectly signed payloads aren't handled
Why is it timing out?
It is timing out because in the part where I handle the customer.subscription.* events I am awaiting an User.findOne() from my DB that doesn't work because it cannot find the user
but that is after the code snippet I sent you, so logically the event creation with the WH secret should fail and it should never reach that code and return 400
I don't know if I'm getting this wrong.
I think the issue here is that the value of your keys.STRIPE_WH_SECRET variable in each environment is correct. You have 2 unique webhooks, 2 unique secrets and 2 environments. In order for it to behave how you need it to, you'd have to use the incorrect secret
Shouldn't the secret be compared to the signature or am I missing something?
Also, your webhook should return a 2xx response prior to any custom logic. If it continues to time out or return 4xx errors repeatedly then it'll eventually be disabled: https://stripe.com/docs/webhooks/best-practices#events-and-retries
Well, yes for it to be successful. But you want it to intentionally fail, right?
If I send an event from the prod server shouldn't the signature contain the prod server Secret, so when it gets checked against the keys.STRIPE_WH_SECRET in the dev environment it fails?
Okay so the way I intended this is:
User checks out from prod -> event is sent using prod secret -> the staging webhook fails and the one whose secret matches the sent signature works
I assume I got any of this wrong
Yes, exactly. But right now we can't confirm the issue because your one of the webhooks is timing out so you should address that (as stated above) then we can confirm the behaviour
I assume a solution to the issue I'm experiencing and to stop from getting timed out/400 because I can't find the user would be having a test stripe account for developers and a prod company stripe account with separate webhooks and dashboards
but I assume that is against your EULA :p
We're expecting a 4xx response with a Webhook error message
No, a lot of merchants have separate accounts for testing
But as I said, you should be responding with a 2xx immediately regardless of the custom logic - Stripe doesn't care about that
We just need to know that the event was received, signed correctly and is being handled
so do res.sendStatus(200) before the event handling logic
Okay! I surrounded the custom logic with try-catches so that it should always reach the 200 status.
It is currently deploying so I'll keep you posted c: Thank you very much for your patience these past few convos!
Yes, but after you've verified the signature with your signing secret
Once we fix the timeout issue we should be able to figure out the problem!
Okay, the timeout issue is fixed in staging. So if I send a webhook request to prod, I should get a 400 with a Webhook error, right
It returned 200 OK on the staging webhook instead of giving me the signature error
The best way to handle this would be just having two separate accounts with one webhook each, right?
Can you share that event ID please
Ok, so that 1 event is sent once to 2 separate webhook endpoints with 2 unique signatures
Now assuming you have the correct signing secrets configured in each deployment (yes?) then it is expected that both deliver successfully as we've seen there
Oh, I see. I thought the event would be sent twice with the same secret (the prod. one), so the other one would fail.
Right now, then, I guess, the solution to my issue would be two separate account with testing webhooks until we go to prod
No, secrets are unique per webhook. So for each webhook you have configured there will be a unique signature for each event
It doesn't matter which URL the event happened on, as it happened with your test Stripe keys in this case and you have 2 webhooks in your test environment
Does that make sense?
It does!
So, the solution is deleting the prod webhook from the account and creating it in another account, and use that account and webhook secret in the prod environment and the current account and webhook for staging and development.
I guess if you need to test in separate environments without yet going 'live' then yes
Would a live webhook allow for test payments and test mode?
No
then two accounts it is hehe
thank you very much again for your help
this dev community is amazing, I'm very thankful to Stripe for setting up such a nice way to get help
is there anywhere I can email to tell people how great of a job you're doing?
I'll relay your kind words ๐
Thank you very much c: