#coachleyton

1 messages · Page 1 of 1 (latest)

deep spruceBOT
oak void
#

actually, the way i would go about it is slightly different

final island
#

Btw, I should mention, that upcoming invoice is retrieved with these options

final island
oak void
#

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

final island
#

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

final island
oak void
#

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.
final island
#

when you say "charge", isn't that a deprecated thing? Replaced with PaymentIntent?

oak void
#

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?

final island
#

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

final island
oak void
#

yep!

final island
#

Okay, and I presume that I'm only wanting to get invoices with a status of "paid" when getting the list?

oak void
#

yes, that's correct

final island
#

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?

oak void
#

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?

final island
#

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"

oak void
#

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

final island
#

My subscription's proration behaviour is always_invoice, so I don't think that is an issue?

oak void
#

that works then, should be fine