#mangle-subscription-refund
1 messages · Page 1 of 1 (latest)
Hello! We'll be with you shortly. 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.
- mangle8582, 19 hours ago, 77 messages
- mangle8582, 3 days ago, 36 messages
mangle-subscription-refund
@ionic ore you should pass prorate: true on cancellation. That way we will calculate the proration automatically for you and the "balance" will be added to their credit balance (more details here: https://stripe.com/docs/billing/customer/balance)
We don't refund automatically though and so that part you do it to do yourself. Usually what you do is your find their previous payment and its PAymentIntentId and then you refund for the prorated amount (what is in their credit balance)
And then you clear the balance
{
invoice_now: true,
prorate: true
}
like this right?
yes
prorated amount can i get it from the latest_invoice on response from subscription.cancel?
yes
The thing is i tried adding back the credit balance, and it never worked. I had 5.99$ and i added credit balance back and it remained the same, and then i have issues with paying because clientSecret doens't come anymore
sure that's what I explained
- Cancel the Subscription
- Refund the Charge
- Clear the credit balance back to 0
const customerBalanceTransaction = await stripe.customers.createBalanceTransaction(
customerId
{
amount: -599,
currency: 'usd',
}
);
This doens't work, if i cancel subscription and i have 599 in credit balance and i do this, it will be still 599 there in customer credit balance
ending_balance on invoice is null
i have only
subtotal: -386,
subtotal_excluding_tax: -386,
tax: null,
test_clock: 'clock_1O8O0gDmVlmqORBIqGRBn0KM',
total: -386,
total_discount_amounts: [],
total_excluding_tax: -386,
fairly sure that's not the case, look at https://dashboard.stripe.com/test/events/evt_1OCQoADmVlmqORBIiGJS5ACK which has a clear ending_balance right there
const deletedSubscriptionFromStripe = await stripe.subscriptions.cancel(
subscriptionId,{
invoice_now: true,
prorate: true
});
I'm talking about coming here the latest_invoice: id
Then await stripe.invoices.retrieve(that id);
And the ending_balance is null
Sorry that's a picture. You're going really fast and jumping steps for me to follow you as I don't sit next to you right now pairing with you.
Please provide detailed information about the exact ids of all the objects you are looking at because I don't really get the problem yet
Sure
-
SubscriptionId: sub_1OCR66DmVlmqORBILQ2jCzZo
-
const deletedSubscriptionFromStripe = await stripe.subscriptions.cancel(
'sub_1OCR66DmVlmqORBILQ2jCzZo',{
invoice_now: true,
prorate: true
}); -
Get the latest_invoice from deletedSubscriptionFromStripe and make a call for the invoice with
await stripe.invoices.retrieve('in_1OCR86DmVlmqORBI01bKC2So'); -
Get the response from the invoice, and the ending balance is null.
The total and subtotal seems good though
what's the status on the Invoice when you retrieve it?
status: 'draft'
okay so that's the problem, the Invoice isn't immediately finalized. So you have to call the Finalize Invoice API https://stripe.com/docs/api/invoices/finalize first or wait for it to be finalized automatically first
Isn't there a way for Stripe to refund imediately with proration without doing all of this? A prorated refund is a general thing
unfortunately no we don't support this (I also wish we did)
So i can call finalize invoice imediately after cancel right?
Now i receive the ending balance nice
There is one more thing:
const refund = await stripe.refunds.create({
payment_intent: subscriptionToDeleteAndRefund?.payment_intent,
amount: nextInvoice.total,
customer: subscriptionToDeleteAndRefund.dataValues?.customer_id
});
I receive customer error here
sub_1OCRIzDmVlmqORBIkG7djmWC with message Received unknown parameter: customer
why are you passing customer?
payment_intent is enough?
yes, https://stripe.com/docs/api/refunds/create doesn't have customer as a parameter
Why is invoice.paid webhook being triggered?
You cannot preview the upcoming invoice for a canceled subscription.
The Invoice is paid so it's triggered that's normal
sorry you're firing questions really fast but a lot of this is in our docs
I use invoice.paid for when a customer pays the invoice when he buys subscription for monthly or yearly and i add the subscription in the database
So it's okay to trigger an error on invoice.paid right? Because it's a refund paid with that invoice, and we don't need to add to database
stripe.invoices.retrieveUpcoming
I belive the error on invoice.paid comes from this
I'm sorry but I don't really follow your train of thoughts. Also have to leavefor now but @austere plaza can help you further if you have a clear and specific question for them
Sorry about that, thank you
Hi there 👋 taking over, as my colleague needs to step away
@ionic ore can you summarize your question succinctly?
Sure
- I want to refund partially to user, depends on how much he used the subscription.
- I use the following methods:
const deletedSubscriptionFromStripe = await stripe.subscriptions.cancel(
subscriptionId,
{
invoice_now: true,
prorate: true
}
);
Getting the latest_invoice id from the canceled subscription and finalize it
const nextInvoice = await stripe.invoices.finalizeInvoice(
deletedSubscriptionFromStripe?.latest_invoice
);
Creating a refund with payment intent and amount, transforming amount from negative to positive so i can refund money to the customer.
const refund = await stripe.refunds.create({
payment_intent: subscriptionToDeleteAndRefund?.payment_intent,
amount: Math.abs(nextInvoice.ending_balance),
});
Reseting Balance of Customer
const customerBalanceTransaction = await stripe.customers.createBalanceTransaction(
subscriptionToDeleteAndRefund?.dataValues.customer_id,
{
amount: -nextInvoice.ending_balance,
currency: 'usd',
}
);
Until now i see it works fine with help from koopajah.
My only concern is that i get a invoid.paid webhook trigger, that webhook i use to add subscription into the database when invoice is paid.
I believe the invoice for refund is paid now and that's why it's triggering invoice.paid method, i just need to not do anything on that particular webhook right? Even if i receive error
okay I'm back as Discord is getting really busy so I'll keep this thread
My only concern is that i get a invoid.paid webhook trigger, that webhook i use to add subscription into the database when invoice is paid.
That is expected. The Invoice is considered paid even if they didn't really pay money. So you have to handle this logic yourself. I can't really say what you need to do since you didn't explain in details what's confusing or blocking you there and it really depends what your code does overall with that Event.
You also didn't seem to end the sentence, it ends with
Even if i receive error
I receive error from
const invoice = await stripe.invoices.retrieveUpcoming({
subscription: dataObject?.subscription,
});
That i use on invoice.paid
invoice.paid webhook is just for adding subscription into database after user pays, that's it
I need to check the result that i receive on webhook and don't do anything if it's a refund or something
Right?
I'm sorry I'm always struggling to follow you and it's a lot of short sentences without a clear summary
Why are you using the Upcoming Invoice in this case since the Subscription is being canceled?
upcoming invoice is used on invoice.paid webhook so i can add data about the latest_invoice in my database
Subscription is getting canceled, by creating a refund the invoice.paid webhook is getting triggered
i have logic adding into database on invoice.paid, and i use invoices.retrieveUpcoming, which throws error because the subscription is canceled
Now i believe i have to add logic to not do anything on that webhook if the invoice is for a refund
To avoid adding things in my database on refunds
upcoming invoice is used on invoice.paid webhook so i can add data about the latest_invoice in my database
I'm really sorry but this is really vague and doesn't make sense to me. Thelatest_invoiceis the previous Invoice that was issued. When you getinvoice.paidit's like that Invoice that is the latest.
Calling the Upcoming Invoice API is previewing a future Invoice that hasn't been issued yet (so it wouldn't be the latest).
Hmm, you're right, i'm calling that invoice upcoming only for next_amount_due: invoice?.amount_due,
Which i set in my database to show the price of the subscription
I don't wanna make invoice calls to stripe to check for the next price of the invoice
gotcha so yes in that case you have to special-case the situation where the Subscription has been canceled. It can always happen in production even without this so you need to be resilient to that
this invoice.retrieveUpcoming is saving me by triggering the catch error and not adding in database, but i was looking on the webhook response in invoice.paid so i can do and if and return
yeah use try/catch, catch the error and if it's about the Subscription being canceled, ignore it
or retrieve the Subscription first
Yea, maybe if i have the subscriptionId, i can retrieve subscription from Stripe and check there if it's canceled?
Everything works good
One more thing
I need to show the user, how much money he will get refund before he initiates the refund button
I can call await stripe.invoices.retrieveUpcoming right?
with some params
subscription_cancel_now right?
yes that's what the link points you to, but you also need the prorate one.
What do you mean by prorate one
Sorry I'm trying to push you to read the docs and figure it out.
There are tons of parameters, please carefully read the docs at https://stripe.com/docs/api/invoices/upcoming, please go over them and find the right fit for you