#coachleyton
1 messages · Page 1 of 1 (latest)
actually, the way i would go about it is slightly different
Btw, I should mention, that upcoming invoice is retrieved with these options
I'm all ears (this refund stuff has been driving me insane lol) 🙂
i think i would have just done the upgrade / downgrade, then check the customer's balance and refund from that
instead of checking the upcoming invoice balance
yeah that's an option, and my thinking was along these lines:
"What if for X reason (who knows what will occur down the line) this customer has some extra pre-existing credit on their account, and I don't want that extra credit refunded when the user downgrades. "
Also, I need a payment intent to process the refund. So what I do currently is look for either the last invoice, or the latest invoice where the amount_due is more than the amount to refund, and I use the paymentIntent associated with that invoice to process the refund. But what if the credit is too much, as to where there is no invoice with an "amount_due" larger than the amountToRefund? Stripe throws an exception when I attempt to refund more than what is on the invoice associated with the given payment intent
This may be unclear btw, please don't hesistate to ask me to re-phrase if need be
when you refund for a Subscription, you generally need to do the following :
- Look at the credit in the account balance and/or sum pending invoice items
- Use the List Invoices API and pass the subscription id in the subscription parameter to only view Invoices for that subscription. Also expand the associated charge if any. For each invoice:
Check if there’s an associated charge
If so, create a refund for up to the amount of the account balance
If the charge amount is smaller than the credit, refund fully and subtract the charge amount from the credit - Move to the next invoice in the list until the full credit has been refunded
- Update the customer’s account balance back to 0 via the API and/or delete the pending invoice items.
when you say "charge", isn't that a deprecated thing? Replaced with PaymentIntent?
a PaymentIntent still creates a Charge object when a payment is attempted
long amountToRefund = (upcomingInvoice.EndingBalance ?? 0) - upcomingInvoice.StartingBalance;
regarding your point about
The amountToRefund ends up being 0, as the upcomingInvoice.EndingBalance is -300, but so is upcomingInvoice.StartingBalance, so it refunds nothing for that billing period, and the money is left in the users invoice credit balance
so you're saying the endingBalance is -300, and the StartingBalance is +300?
Starting balance is also -300, so it's -300 - -300. Two minus make a plus, so it's -300 + 300, which results in 0
So nothing was refunded, and so the full 300 is still in the credit balance
I see. So just basically cycle through as many invoices as necessary, chipping away at the amountToRefund
yep!
Okay, and I presume that I'm only wanting to get invoices with a status of "paid" when getting the list?
yes, that's correct
Also, when looping over the invoices, to determine how much I should refund using that invoice's payment intent, should I use the amount property on the charge object? Or will amount_paid on the invoice sufficient?
i would use the amount property on the charge object
can you share the customer id so that i can take a look at it's balance?
Sure, cus_OQbD159cpsAmQV
it's not a big deal that the balance is there, just a test user after all
Also, regarding the calculating of the amountToRefund. I would prefer to avoid simply checking the user's credit balance, due to the issue of accidently refunding pre-existing credit.
I'm not sure what you mean by "sum pending invoice items"
there might be invoice items on the customer that hasn't been invoiced yet : https://stripe.com/docs/api/invoiceitems/list
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
for example, you might prorate a customer, but not invoice immediately
i guess you can potentially skip that if that's not a concern for you
My subscription's proration behaviour is always_invoice, so I don't think that is an issue?
that works then, should be fine