#nobody_best-practices
1 messages ยท Page 1 of 1 (latest)
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.
- nobody_code, 4 hours ago, 68 messages
๐ 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/1270535398027825255
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
For example, should i re-randomize the idempotency key every time the payment element .onchange event occurs?
hello! gimme a while to take a look
Np, ty
idempotency keys aren't meant to be used client-side. They're really meant to be used server-side for example when creating a PaymentIntent. On the frontend for example, when you confirm the same PaymentIntent twice - assuming the first time was successful, confirming the same PaymentIntent doesn't result in a different status for that PaymentIntent
adding on about idempotency, Stripe can automatically generate idempotency keys and handle retries for you : https://github.com/stripe/stripe-node?tab=readme-ov-file#network-retries in our libraries
Oh seriously?
It says "a client" generates it here. Because at least for checkout, you don't want to create the charge twice if the customer presses the "pay now" button twice. And for that to work, the idempotency key has to come from the client side
I think client is just a generic term. I want to be clear that Idempotency keys are useful for preventing double charges in cases of poor network conditions only. They allow for safely retrying requests without accidentally performing the same operation twice. This is useful when an API call is disrupted in transit and you do not receive a response. For example, if a request to create and confirm a PaymentIntent does not respond due to a network connection error, the request can be retried with the same idempotency key to guarantee that no more than one PaymentIntent is created.
Idempotency keys do not prevent double charges which occur due to a button being pressed twice e.g. maybe a user clicked the button twice while a page was loading and it leads to making two API requests. You would want to use approaches like disabling the payment button to prevent such occurrences.
I mean it just seems exceedingly risky for the frontend to not have idempotency on the payment request. If the client ever somehow fired off two requests, you'd charge them twice
Maybe the idempotency key wouldn't be used in stripe's payment intent itself, but just handled by your backend..? I still don't see why not used with stripe tho
One payment intent can only make one payment regardless whether idempotency is set. Payment Intent has a state machine to keep track whether the payment has been made. Even if the client side sends two confirm requests, customer will not be charged twice
Well I'm using the "finalize payments on server" method
So the payment intent is created in my backend
This works the same for the backend
I use a confirmation token from the frontend, which a new one is generated each time "pay" is pressed
Okay but if there are multiple requests to my backend, how do they know to use the same payment intent?
isnt the confirmation token different each time
Or do you try to use the same confirmation token
If they are on the same page, then they would use the same PaymentIntent. Even if the confirmation token is different, the confirmation token is just a payment method. The PaymentIntent is what creates a payment when it is successful
Ok i see
So as long as the frontend only makes 1 payment intent, there's no way to double charge them?
Oh wait nah the frontend doesnt make the payment intent
in essence, there is no way to double charge the same PaymentIntent. i.e. if PaymentIntent A is already successful (customer is charged), and you try and confirm PaymentIntent A again, the customer will not be charged again
But think about it... your server makes a PaymentIntent when your customer presses pay. So if they press pay twice, you're making two PaymentIntents?
Yes... via idempotency keys...?
So my original question was when to refresh your idempotency key
I think you're overcomplicating your integration by trying to use idempotency keys in the manner you described. If you want to use idempotency keys in that manner, you need to figure out all the cases where you need to "refresh" your idempotency key - we can't really help with covering all the potential scenarios as to when you need to refresh your idempotency key here.
I suppose that's true, but this seems like a critical aspect of finalize payments on server which is not documented at all
that's because we don't recommend using idempotency keys in the way you want to
But if I set up payment in the way the documentation outlines, it's at extremely high risk of double charging users
there are multiple ways to prevent duplicate charges and the measures you take to prevent duplicate charges would depend on how you implement your integration. For example, you can disable the button when payment is processing to prevent the customer from accidentally clicking it twice. Redirect the customer to another page upon (successful) payment attempt so that they don't get a chance to click the button on the same page. Another example, store the PaymentIntent such that you check if there's an existing PaymentIntent for the user on that same payment page so that you don't create another one.
For example, you can disable the button when payment is processing to prevent the customer from accidentally clicking it twice
Of course I'm going to do this, but imagine the customer is on a slow machine and the javascript is lagging, so the button doesn't immediately disable. OOPS they just pressed the payment button 10 times and got spam charged.
Nor could you rely on simply looking up if a payment intent already exists, because of race conditions
Using a frontend idempotency key for these kinds of things is like, the defacto solution, as far as I'm aware.
I'm surprised this isn't covered in the documentation. It's pretty critical
I'll pass on your feedback about covering duplicate charges in our docs ๐