#jefskoa_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/1434886472376254515
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Resending in the Dev dashboard for a payout.paid. Original event id: evt_1SK7ChIvHz5DOm3orxsRuwNN. In the StripeCLI after login, it has confirmed log in with the platform account: "Done! The Stripe CLI is configured for KOA Development Sandbox with account id acct_1QptxoI1VSC7qNYw"
What looks odd is in the StripeCLI when I issue the stripe Listen, it returned the webhook signing secret which is NOT the signing secret for the connected account web hook listener I established in the dev toolbox.
resending the event from the dashboard doesn't resend it to the CLI
this is normal
the Stripe CLI is a separate webhook endpoint that has its own secret
Oh, phew, good to know ... so that likely isn't the issue?
yes
while stripe listen is running, open a new terminal and use the CLI to resend the event https://docs.stripe.com/cli/events/resend
in the new command, do I need to login in again before issuing the resend? I'm getting a resource_missing code with: stripe events resend evt_1SK7ChIvHz5DOm3orxsRuwNN
๐ Hey, taking over here, just taking a look
You'll likely need to pass a value in the --account flag with the connected account ID: https://docs.stripe.com/cli/events/resend#events_resend-account
I think I got it. The event came from a connected account so I need to pass it in the CLI.
Exactly, yes
Thx for the quick responses Stripe dev support team! 5 stars!
I don't know if this is your area or not -- I am getting the webhook response now back to my c# app via the listen. However, the Stripe supplied method to validte the signature is failing as the webhook content doesn't contain a v1 signature, it is a v0 signature. Does that have anything to do with the resend or sandbox environment settings?
Are you verifying the signature manually?
No sig verification is my c# code calling a Stripe supplied method. I can see in that method, it fails if there is NOT a signature tagged "v1". What I'm seeing being sent only contains a v0 signature.
Do you have an example of the signature header where the v1 signature is missing?
Give me a second, yes. Thanks so much for the help.
PS: I can see the web secret we are using for the signature compare and it is the web secret from the portal platform. Could the issue be it is expecting the web hook secret the StripeCLI is using, which I understand now is differnent?
Here's a screen shot of Stripe's c# ValidateSignature method with a break point hit. It shows the signature collections and the debug showing the key "v0". There isn't a "v1" is the collection being sent so the method fails.
What does the ParseStripeSignature method do here?
Splits the SignatureHeader into key/value pairs.
So I suspect the signaturheader only has a v0 entry, not a v1. Not sure if that is expected with this sandbox environment.
I've not seen a case where only v0 sig would be present. You generally shouldn't need to do any parsing of the signature at all. An example endpoint that shows how it's generally used: https://docs.stripe.com/webhooks?lang=dotnet&snapshot-or-thin=snapshot#example-endpoint
I am calling the ConstructEvent as your sample shows. In that method, ValidateSignature is being called which in turn is calling IsSignaturePresent method where it is looking for that v1 entry in the SignatureHeader.
Just worries me to throw this code/app forward when I'm not sure why that this code fails:
if (!IsSignaturePresent(signature, signatureItems["v1"]))
{
throw new StripeException(
"The expected signature was not found in the Stripe-Signature header. " +
"Make sure you're using the correct webhook secret (whsec_) and confirm the incoming request came from Stripe.");
}
I can mock the needed value and see if the rest of it passes.
Are you able to see the raw value of the Stripe-Signature field where it appears to be missing the v1 sig?
Not in that method. The string is unobservable in debug. Let me back up in the breakpoints and see if it is available. Might take a second.
Interesting!!! Yes, I can see the stripe header:
t=1762178336,v1=ce480dfdbe963478ffe2ea7f28e7be39d67ae33b3943e2bd5e7c294dda1014c4,v0=189a64122fd7be8db2fd44505ae00290e24db32f09cfb9903ccc89462fc07717
There is a v1
Ah, yes, so it must be getting parsed out somehow in the integration
As a next step, you'd need to ensure that you're passing the raw value
OK, starting to understand more how the verification is working. Ultimately, the value of t1 is matched up against the signature present method:
if (!IsSignaturePresent(signature, signatureItems["v1"]))
where the signature string value is computed with:
signature = ComputeSignature(secret, signatureItems["t"].FirstOrDefault(), json);
Could it be that I'm retrieving the web secret from the platform, but the stripeCLI is being started up with a different web hook secret as Tarzan explained to me above?
That's it!!! We store the web secret shown in the Dev portal and use it for the verification. When I use the StripeCLI though to "listen" it starts up with a different web hook secret:
C:\Users\jsutherl\source\StripeCLI>stripe listen --forward-to localhost:64492/v1/webhooks/receive/stripe
A newer version of the Stripe CLI is available, please update to: v1.32.0
Ready! You are using Stripe API Version [2025-03-31.basil]. Your webhook signing secret is whsec_8cba6c44a09e3ff176c31303053cdaff45b45b0b400fb13c997ec6e330d5a3c4 (^C to quit)
when I change the value of the web hook secret to the what the CLI supplies, it verifies.
Anything is possible. You can rule all of these out by manually pasting the webhook secret in your code.