#yurt_subscription-invoice
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1430292669166518416
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
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.
- yurtdweller_api, 18 hours ago, 86 messages
- yurtdweller_api, 1 day ago, 31 messages
๐
Hello! ๐
This is the code I have writen in checkout.session.completed : - what seems to happen is that the payment method gets attached properly and set as default properly, but resuming the trial does not result in a proper charge happening
// Get the newly set payment method from the SetupIntent.
const setupIntent = await stripe.setupIntents.retrieve(
session.setup_intent.toString()
);
const paymentMethodId = setupIntent.payment_method?.toString();
if (paymentMethodId && session.customer) {
// Set as the payment method as default on the customer.
const response = await stripe.customers.update(
session.customer!.toString(),
{
invoice_settings: {
default_payment_method: paymentMethodId,
},
}
);
console.log(
'Updated default payment method:',
response.invoice_settings.default_payment_method
);
// If this subscription is paused, resume it now.
const subscriptionId = session.metadata?.subscription_id;
if (subscriptionId) {
const subscription =
await stripe.subscriptions.retrieve(subscriptionId);
console.log(`Using found subscription.... ${subscription.id}`);
if (subscription.status === 'paused') {
const result = await stripe.subscriptions.resume(subscriptionId);
console.log(
`Resuming subscription.... Resulting status is... ${result.status}`
);
}
} else {
console.log(
`Could not find subscription ID when resuming subscription for ${session.customer_details!.email}`
);
}
} else {
console.log(
`Could not update customer default payment method for customer: ${session.customer_details!.email}`
);
}
digging into this looking ove rthe examples you provided
I wonder if it's because the resulting invoice isn't set to auto_advance
testing
Hi there,
taking over for my colleague who had to step away. Let me quickly catch up...
thanks
I haven't tested this yet, but from my understanding how resuming a subscription works is, that the invoices are not automatically paid after resuming. Meaning, when a subscription pauses, you attach a payment method to customer as the default PM for invoices, you would need to pay outstanding invvoices berfore resuming the subscription. Otherwise you run in the same issue again you had initially, subscription would get paused again because of unpaid invoice. Does that make sense?
We also call this out in our API reference, that if a resumption invoice is generated, it must be paid or marked uncollectible before the subscription will be unpaused.https://docs.stripe.com/api/subscriptions/resume Pointing out that this is something that has do be done manually and does not happen automatically through resuming the subscription.
Paying, then resuming. I would call the List all Invoices API to get all Invoices with the status: 'open' and the subscription: subscriptionID and pay them with the new Payment Method. After that, resume the subscription.
OK, interesting, there are no invoices once it goes to paused. So it seems like I need to create an invoice first?
We currently use the Pricing Table and the Customer Portal to achieve this, but we're moving away from that to have more control in app with Stripe Elements.
A user with a paused subscription can go to the Stripe Customer Portal with a paused subscription and add a payment method.
I created a test user in this workflow and it seems like Stripe creates a draft invoice -
The subscription pauses because of an ending trial and a missing payment method? Just assuming here because of the code snippet you shared.
Correct, yes.
And the workflow I am adding it creating a screen where someone can add their payment method
If they are adding the payment method while on trial, it will be used when the trial is over. But if they are adding the payment method after they are paused, I want to resume the subscription
Yes that makes sense. Nortmally when a subscription pauses after trial because of a missing payment method, Stripe does not create an invoice. Because of the setting, the subscription would simply transition into the paused state
So when the payment method gets added to the customers invoice_settings.default_payment_method and the subscriptions collection_method is set to charge_automatically (which it seems like it is), the newly created invoices (Invoices created after resuming the subscription) would get automatically paid with the customers default payment method.
newly invoices directly created after resuming subscription will initially remain in draft until finalized and paid.
OK, so then there might be something wrong with how I am resuming then?
I advance the clock to pause the subscription: evt_1SKm32EXjRBPmDmBvUSa0XYk
The card method was added via the Stripe Element:
evt_1SKm4CEXjRBPmDmBU04D4KL5
The new payment pi was created: evt_3SKm4FEXjRBPmDmB1sHBrLHL
A SetupIntent was canceled?
evt_1SKm4GEXjRBPmDmBsVHMcG0U
Draft invoice was created:
evt_1SKm4HEXjRBPmDmBsmMGViaU
Draft invoice was finalized:
evt_1SKm4HEXjRBPmDmBJOz27P0S
But the invoice remained open - so the charge_automatically didn't seem to work
Ok, let me check
ok so it seemed like I needed to search for the open invoice and then pay it
if (subscription.status === 'paused') {
// Resume the subscription to generate the invoice
const result = await stripe.subscriptions.resume(subscriptionId, {
proration_behavior: 'none',
});
// Find the open invoice
const invoices = await stripe.invoices.list({
subscription: subscriptionId,
status: 'open',
limit: 1,
});
if (invoices.data.length > 0) {
// Pay the most recent invoice
const result = await stripe.invoices.pay(invoices.data[0].id, {
payment_method: paymentMethodId,
});
console.log('Paying the outstanding invoice...', result.status);
}
console.log(
`Resuming subscription.... Resulting status is... ${result.status}`
);
}
Yes, because in this case the Invoice's auto_advance is set to false, which mean Stripe does not automatically try to pay the invoice.
That invoice is generated automatically on resuming, is there any control over the auto_advance setting before that in that case?
No, the auto_advance: false is the default behavior https://docs.stripe.com/billing/invoices/subscription#new-subscription-invoices
Auto_advance stays false until payment succeeds.
yurt_subscription-invoice