#nobody_best-practices

1 messages ยท Page 1 of 1 (latest)

reef axleBOT
wintry galleonBOT
#

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.

reef axleBOT
#

๐Ÿ‘‹ 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.

tame pendant
#

For example, should i re-randomize the idempotency key every time the payment element .onchange event occurs?

quiet sun
#

hello! gimme a while to take a look

tame pendant
#

Np, ty

quiet sun
#

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

tame pendant
#

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

quiet sun
#

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.

tame pendant
#

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

wheat kettle
#

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

tame pendant
#

Well I'm using the "finalize payments on server" method

#

So the payment intent is created in my backend

wheat kettle
#

This works the same for the backend

tame pendant
#

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

quiet sun
#

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

tame pendant
#

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

quiet sun
#

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

tame pendant
#

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?

quiet sun
#

then that's something which you need to prevent

#

it's up to you to prevent that

tame pendant
#

Yes... via idempotency keys...?

#

So my original question was when to refresh your idempotency key

quiet sun
#

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.

tame pendant
quiet sun
#

that's because we don't recommend using idempotency keys in the way you want to

tame pendant
#

But if I set up payment in the way the documentation outlines, it's at extremely high risk of double charging users

quiet sun
#

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.

tame pendant
#

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

quiet sun
#

I'll pass on your feedback about covering duplicate charges in our docs ๐Ÿ™‚

tame pendant
#

I appreciate it :)

#

Would like to see what the official solution is