#heisend3rp-refund

1 messages · Page 1 of 1 (latest)

gloomy sierra
hasty sleet
#
{
  "id": "pyr_1KlqVCFQFr5kixFfmMabyTKA",
  "object": "refund",
  "payment_intent": "pi_3Kj4EIFQFr5kixFf0IrBtUzX",
  "status": "failed",
  "amount": 2300,
  "balance_transaction": "txn_1KlqVDFQFr5kixFfpJCdYp9X",
  "charge": "py_3Kj4EIFQFr5kixFf03rPd6AW",
  "created": 1649319338,
  "currency": "eur",
  "metadata": {
    "orderId": "szQd8bBMA2RqJWApvxI6"
  },
  "reason": null,
  "receipt_number": null,
  "source_transfer_reversal": null,
  "transfer_reversal": null
}
#

That looks like failed to me 😅

gloomy sierra
#

Oh you are right, it first had a pending status, and now it's failed. Give me a few minutes to look into this.

last canyon
#

Hey, taking over from @gloomy sierra - checking on this

hasty sleet
#

any updates? @last canyon

last canyon
#

But this was done before this refund was created

#

Have to retried to refund? It'll be safe to just re-attempt

hasty sleet
#

ok, we will reatempt

#

retried refund did not update yet after 10 minutes...

#

@last canyon can you check again?

last canyon
#

Can you share the Refund ID pyr_xxx?

#

It'll be a new object

hasty sleet
#

pyr_1KlqVCFQFr5kixFfmMabyTKA

#

but it seems to be the same refund object as the last one

#

you can see the new refund attempt in the activity of the payment intent

last canyon
#

Hmm, weird. I didn't expect that

hasty sleet
#

we are setting a idempotency key in the refund request. might this be the reason it is the same refund object?

last canyon
#

Ah, yep

#

Those should be unique per request. Otherwise you're just re-attempting the previous request

hasty sleet
#

we are using it since we are using cloud functions with at least once policy

last canyon
#

But you received a 200 response

hasty sleet
#

this will be tricky to do with our current implementation

last canyon
#

You should never re-use the same idempotency key within a 24 hour window

hasty sleet
#

why

#

?

#

Clients can safely retry requests that include an idempotency key as long as the second request occurs within 24 hours from when you first receive the key (keys expire out of the system after 24 hours). For example, if a request to create a charge doesn’t respond because of a network connection error, a client can retry the request with the same idempotency key to guarantee that no more than one charge is created.

#

just saw that the payment was disputed or at least it showed up just now

#

might this be the reason it failed in the first place?

last canyon
#

Exactly. You received a 200 (sucessful) response the first time, by making the same API call with the same idempotency key you're just going to get back the exact same successful 200 response. We won't actually retry the refund (hence why the same pyr_xxx ID was returned)

last canyon
hasty sleet
#

Ok, so at least we understand now why the refund failed.

#

coming back to the idempotency keys:
Let me explain again. We are using an asynchronous system with cloud functions for handling the payments. The cloud functions have an at least once policy, meaning that each function trigger gets executed at least once. Meaning it is possible that a certain function runs two times for one request. This is unlikely but possible.

To not charge customers twice for the same request we are using the idempotency key, generated by data in our database to ensure we use the same request.

As far as I understood til now, this is the way to go. The points you were mentioning above, made me unsure about our current implementation. This is why I want to dig deeper here a little bit.

#

Furthermore, we have another question. Is it possible to set a minimum amount that should stay available on the connected accounts? So when a refund is initiated we can guarantee, that the account has sufficient funds.

I know we could switch to manual payouts, but that would make reporting impossible for us, since the docs say we cannot see the pi that build up the payout for manual payouts.

last canyon
#

To not charge customers twice for the same request we are using the idempotency key, generated by data in our database to ensure we use the same request.
Yep, that's an approriate use case for the idempotency key. In reality you should just accept the 200 response and prevent that function/API call from being re-attempted

#

Because in instances like this, where you actually need to retry a API call (i.e. the refund re-attempt), you want a unique key

hasty sleet
last canyon
#

Furthermore, we have another question. Is it possible to set a minimum amount that should stay available on the connected accounts? So when a refund is initiated we can guarantee, that the account has sufficient funds.
There's no way to do that without manually managing the balance and payouts, no

#

since the docs say we cannot see the pi that build up the payout for manual payouts
Where does it state this?

hasty sleet
#

Maybe there is a kind of hacky way for us where we are using transaction based databse writes that ensures the stripe api is only called once

last canyon
#

Yep, as I said that's fine. But in the particular case of this refund it tripped you up. So you just need to be wary of that

hasty sleet
#

But I guess I need to dig deeper into our codebase for this 😅

hasty sleet
#

Thanks a lot for your help, Stripe support is amazing 🥰

last canyon
#

Np!