#simon-says0363_api
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/1288232639991382027
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Due to the missing logs I can't provide log request ids, but I am happy to provide payment intent IDs if required and doing so is secure.
Yeah please share the PaymentIntent ID
It's happened to a couple, but here is the one I am currently investigating: pi_2Q0mpPTbTiK4Bfju23gkvyrD
According to our system we tried to charge that payment intent 11 times (timestamps UTC):
2024-09-19T16:03:35.769+00002024-09-19T16:03:42.734+00002024-09-19T16:04:04.968+00002024-09-19T16:04:09.871+00002024-09-19T16:04:23.025+00002024-09-19T16:04:28.078+00002024-09-19T17:25:39.757+00002024-09-19T17:25:45.294+00002024-09-19T17:27:47.453+00002024-09-19T17:27:52.641+00002024-09-19T17:29:37.681+0000
But in the Workbench logs I only see 6 attempts.
And crucially the attempt that changed the payment method (17:29:37) is missing.
I'm seeing only 5 requests made to /v1/payment_intents/:id/confirm meaning 5 attempts were made to confirm the PaymentIntent (6 including the confirm: true attempt from payment intent creation request)
Yeah exactly. But I can see in our system logs that we made 11 requests. So something is getting lost somewhere.
Unless the Node SDK does caching?
Does your system track which endpoints these requests were made to?
Not directly, but I have enough logging that I can trace the code path it went through.
Using the npm package "stripe": "14.22.0" we made the following calls:
- The first attempt called
stripe.paymentIntents.create()(withconfirm:true) - All the rest of the attempts called (in order):
stripe.paymentIntents.retrieve()stripe.paymentIntents.update()stripe.paymentIntents.confirm()
Yeah I'm seeing update calls too. So your total number of requests isn't just confirm requests
Kinda. I'm seeing 11 total api requests in the Stripe Workbench. 1 initial creation request then 5 pairs of update and confirm. But our system reports 1 initial creation request then 10 retrieve/update/confirm triplets.
So there are 5 more update/confirm pairs missing from the Stripe workbench, and also all of the retrieve calls as well.
Is it possible that your logs duplicated these? Like I'm not aware of any issues on our end which could cause request logs disappear. We haven't heard any other reports of this too..
Anyway, taking a step back to look at the issue you've reported with payment method, what payment method object were you expecting and what are you seeing?
It's highly unlikely unless we somehow have a network cache I'm unaware of. But given the request pattern that also seems unlikely.
Here's the map of our logs to Stripe requests:
2024-09-19T16:03:35.769+0000--req_OWgcgETZNYuvF42024-09-19T16:03:42.734+0000--req_n7ZLtAmZo0WZG1+req_0HwkbKIM0hbufA2024-09-19T16:04:04.968+0000--req_rstZ0DXYMk99M5+req_pGH1hyHmnmATvY2024-09-19T16:04:09.871+0000-- missing2024-09-19T16:04:23.025+0000-- missing2024-09-19T16:04:28.078+0000--req_fdymXZ65l40H4n+req_HmzxAeB07ctaUT2024-09-19T17:25:39.757+0000-- missing2024-09-19T17:25:45.294+0000--req_6WvoVsLsbQ6AFW+req_2yF4OypQPIOA1W2024-09-19T17:27:47.453+0000-- missing2024-09-19T17:27:52.641+0000--req_1CFnbLRqaZ8M7s+req_QzawUzL7omeByp2024-09-19T17:29:37.681+0000-- missing
The final update/confirm pair says in our logs that it used pm_0PwW6kTbTiK4BfjuQOo4BpzN, but pi_2Q0mpPTbTiK4Bfju23gkvyrD lists pm_0Q0o8eTbTiK4Bfju4sRC6ip0
I'm stumped. I can't think of any reason why this would be happening. Every idea I have doesn't hold up under scrutiny.
๐ Stepping in for my teammate, give me a few minutes to catch up please
Hm, the final update/confirm pair I see for this PaymentIntent is:
https://dashboard.stripe.com/logs/req_1CFnbLRqaZ8M7s
https://dashboard.stripe.com/logs/req_QzawUzL7omeByp
The final update included PaymentMethod pm_0Q0o8eTbTiK4Bfju4sRC6ip0
Do your logs include any details about a response received from Stripe for that update request?
Yeah, it says it got back a Payment Intent with status requires_action
Oh wait I misread your question.
I don't have any response logged for the update request, just that it didn't throw.
The confirm request returned with requires_action
just that it didn't throw
What does this mean exactly?
The code in question looks like this (slightly tweaked for brevity):
// Update payment intent just in case details have changed.
await this.stripe.paymentIntents.update(
paymentIntentId,
{
amount,
currency: 'usd',
customer: stripeCustomerId,
description: label,
payment_method: cardId,
},
{ maxNetworkRetries: 2 },
);
// Initiate charge
const paymentIntent = await this.stripe.paymentIntents.confirm(
paymentIntentId,
{
capture_method: 'automatic',
off_session: !isOnSession,
payment_method_options: {
card: {
request_three_d_secure: isOnSession ? 'any' : 'automatic',
},
},
},
{ maxNetworkRetries: 2 },
);
if (paymentIntent.status === 'requires_action') {
// Handle 3D Secure
}
I can see in the logs that it is making it to the Handle 3D Secure case, which means that the call to stripe.paymentIntents.update() returned a Promise that resolved, it did not throw/reject, and stripe.paymentIntents.confirm() also resolved, this time to a PaymentIntent with status: requires_action
Hm, not exactly
Hmm?
No, nevermind.
Yeah I've had a few of those moments looking at this issue so far ๐
I think it'd be helpful to add some logging after your update
To make sure the update worked you mean?
Yeah, I'm adding a sanity check after the update call to make sure the result is what we expect.
Question about that actually. I see in the Workspace logs that you have only mostly redacted client_secret values. I'd like to replicate that in our logs so we can cross-reference. Is it safe to replace all but underscores in the middle?
Assuming that it is just failing to update though, what would that mean?
Not sure I follow this question. Can you clarify?
If there was an erorr on the Stripe side, I would expect to still see the incoming update request with a failure response. I don't see that though ๐ค
Nevermind, my idea doesn't work anyway.
Yeah exactly. The request just seems to become a ghost, but it doesn't fail.
And I have no idea what to do with that information.
As part of testing, can you retrieve the PI prior to confirming to ensure it's what you expect?
Yeah, I'm adding that in.
I just don't know what that will tell us.
If it passes, then we're back to square 1, and if it doesn't then the update call is being swallowed without a trace. But both already seem to be impossible.
We're clearly missing something.
But what??
Woah.
Ok I was just able to reproduce it in test mode.
Now I need to reduce it down to a minimal repro.
Ooh interesting
......... ๐คฆโโ๏ธ found it
Yeah the Stripe API is fine, we're just doing something dumb
Here's what we're actually doing:
let paymentIntent = await this.stripe.paymentIntents.retrieve(
paymentIntentId,
);
if (paymentIntent.status === 'requires_action') {
// Handle 3D Secure
}
// Update payment intent just in case details have changed.
await this.stripe.paymentIntents.update(
paymentIntentId,
{
amount,
currency: 'usd',
customer: stripeCustomerId,
description: label,
payment_method: cardId,
},
{ maxNetworkRetries: 2 },
);
// Initiate charge
paymentIntent = await this.stripe.paymentIntents.confirm(
paymentIntentId,
{
capture_method: 'automatic',
off_session: !isOnSession,
payment_method_options: {
card: {
request_three_d_secure: isOnSession ? 'any' : 'automatic',
},
},
},
{ maxNetworkRetries: 2 },
);
if (paymentIntent.status === 'requires_action') {
// Handle 3D Secure
}
So if we attempt to charge a second time while the payment is still in requires_action we short-circuit and never update or confirm.
Which explains all the issues I was having.
Ohh interesting
So yeah, entirely our fault. Thanks for the help being a rubber duck. ๐คฃ