#toni_43861

1 messages ยท Page 1 of 1 (latest)

broken ginkgoBOT
vagrant moon
#

Hi
After a charge succeeded you want have immediate available balance

#

Between why are you using charges.create ? and not PaymentIntent ?

kind fiber
#

It's legacy code that we discovered might have a race condition due to creating charges that exceed the available account balance. Thus we don't currently use PaymentIntent for it.

Let's say we have an account with a balance of 5 USD (from a gift card for example). We charge it 5 USD twice by accident or malice. We want to stop the 2nd charge (because we don't want negative balance on the gift card account), so we check the balance both before and after the charge, and if the balance is -5 after, we refund the charge.

Thus it is important that the stripe.balance.retrieve() call we do after the charge always gives the correct balance. Even if the calls go to different Stripe servers.

vagrant moon
#

But the balance you are referring to is a Stripe Account balance or a customer balance ?

kind fiber
#

Stripe Account balance. We create one for the customer when they purchase a gift card.

vagrant moon
#

The charge request you are creating will be on the Customer credit card

#

and not the Stripe Account balance

#

You are mixing concepts here

#

when you create a Charge request/paymentintent, you charge the customer credit card

#

that funds will go to your Stripe Account Balance

kind fiber
#

So let me explain. We charge the customer initally for purchasing a gift card. Transfer all the funds to a brand new Stripe account. Then later we charge that separate Stripe Account (owned by our company and not connected to any credit cards) when the customer is using the gift card.

#

We considered idempotency, but we don't have a good idempotency key, as this 'trick' can be used to purchase different items with different prices. And we don't want the key to be the customer themselves, as the customer should be able to make several purchases.

Could you please answer my initial question if possible ๐Ÿ˜… We will explore alternatives based on the response.

broken ginkgoBOT
boreal cargo
#

hi! I'm taking over this thread.

#

Am I guaranteed to get the correct balance when retrieving it immediately after charging the account (and getting OK back)? Or could one of Stripe's severs lag behind, and thus not return the right balance?
to be honest I don't know exactly how that works internally.
but why would your code make duplicate charges? that seems like a different issue that you should try to solve.

kind fiber
#

It's not necessarily a duplicate charge.

Say the user purchases two items. One costs 10 USD, the other costs 5 USD. The user has 10 USD on their gift card.

The user purchases both at the same time trying to exploit the race condition.

Unless we check the balance afterwards and cancel/refund one of them, nothing will stop them from purchasing both.

We could implement other measures, (like locking the gift card for some time) but checking the balance after is the simplest one.

In our company the database guarantees certain changes are replicated to all servers, before returning OK to the request. So I'm wondering if Stripe has guarantees regarding stripe.charges.create(), that the changes will be saved to all servers before returning OK to us. (So that a balance request to any server afterwards is correct)

For a big company like Stripe I would expect this knowledge to exist ๐Ÿค” But I understand if it is not easily available. But surely valuable for more people than just me ๐Ÿ˜…

last inlet
#

ultimately the correct way to integrate is webhooks โ€” we send you a webhook for e.g. charge.succeeded, and at that point you can do things like call the Balance retrieve API.

#

as of right now anyway when using an old API like Charges, we do attempt to guarantee that when an API request is finished, all state is saved, but in future API versions or in certain APIs we might change this, as for a lot of merchants it's more important to have low latency and immediate response and you can do processing async (e.g. https://docs.stripe.com/payments/payment-intents/asynchronous-capture-automatic-async is a mode of operation where you get a faster charge processing because we can defer doing some of the work until later and webhook you when it's done).

kind fiber
#

Thanks a lot all of you! We plan to migrate to webhooks this year. Will think some more about this and get back to you in this thread if we have more questions ๐Ÿ˜Š

#

Actually I have one already: If the behavior of the charge API were to change from the current "attempt to guarantee that when an API request is finished, all state is saved" to someting faster but less 'reliable', would this be documented in the API changes, or could it happen without us having a way to know ๐Ÿค” (other than asking I guess)

last inlet
#

it would be a version change

#

or it would be a new API or new API parameter you'd have to explicitly start using to opt-in