#fxmoon_best-practices
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/1414550699269947474
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
How can I check if the subscription was renewed or went overdue?
It'd depend on the settings configured in the Dashboard I believe. Generally if a payment fails the sub transitions topast_due
Does the invoice attached to the subscription inherit its metadata?
Yes, on thesubscription_detailshash: https://docs.stripe.com/api/invoices/object#invoice_object-subscription_details
Can I fetch the invoice attached to the subscription?
Sure, multiple ways
Hey ynnoj, thanks so much for the quick reply - Does the subscription transition to past_due after the first failed payment?
(easy enough to test all this, especially with a clock: https://docs.stripe.com/billing/testing/test-clocks)
Yes
case "customer.subscription.updated": {
const subscription = await stripe.subscriptions.retrieve(
event.data.object.id,
{ expand: ["items.data.price.product"] }
);
const subscriptionId = subscription.id;
const customerId = subscription.customer as string;
const latestInvoiceId = subscription.latest_invoice as string;
const latestInvoice = await stripe.invoices.retrieve(latestInvoiceId);
if (subscription.status === "active" && latestInvoice.status === "paid") {
// renewal logic
} else if (subscription.status === "past_due") {
// suspension logic
}
}
This is what I'm trying right now - would this be effective?
Effective for what?
Not always as that .updated event may fire for other reasons beyond just a renewal. Generally we recommend invoice.paid event to track an active sub: https://docs.stripe.com/billing/subscriptions/webhooks#active-subscriptions
I was going with invoice.paid or invoice.payment_succeeded
What's the difference
.paid fires in scenarios where there may not necesarily be an actual payment but there's still an invoice (e.g. trial, 100% discount)
And how can I retrieve the subscription details using the invoice object? I'd just need the subscription ID to be honest
Generally consider .payment_succeeded to be deprecated
Does the invoice contain the subscription details?
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
No problem, glad I could help!
Oh one more thing,
customer.subscription.deleted
Let's say I cancel a subscription on Septemember 09th (tomorrow) - is this event fired as soon as it cancels?
Or when I schedule the cancellation?
This is explained here: https://docs.stripe.com/billing/subscriptions/cancel#events
Is there a invoice.unpaid event to track overdue subscriptions?
I'll use invoice.paid for renewals but what about the other scenario
invoice.payment_failed will fire if a payment fails. I'd recommend just reading this article: https://docs.stripe.com/billing/subscriptions/webhooks
Thanks, and that will just have the subscription parent as invoice.paid right?
And parent.subscription_details returns the subscription object?
Yes, it's an expandable string field so will return sub_xxx without expansion
Not all of it, just some properties: https://docs.stripe.com/api/invoices/object#invoice_object-parent-subscription_details
If you want the full object you'll need to retrieve it or expand the parent[subscription_details][subscription] property
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
True, but the type ('string') and 'Expandable' are the clue
const subscriptionDetails = invoice.parent?.subscription_details;
How am I supposed to access the ID
Haver you looked at the API reference? There's a subscription property in that hash that will be the sub_xxx ID
Thanks a lot buddy - by the way, is it safe to fetch all the subscriptions and look for the expiring ones?
Within a range of 3 days
If a sub expires on August 10th, I want to send an email on August 7th advising for expiration
What exactly does expiration mean? A trial expiring? Or the renewal?
If a subscription is scheduled to cancel
So not to renew
I think I saw this on the stripe dashboard but I want to build my own system
My recommendation would be to queue a job to send an email once the sub is set to cancel, like on receipt of the corresponding customer.subscription.updated event
There's no way to really query the API for event that cancel within a certain timeframe, so it'd be expensive to do that locally
I am storing the expirations in my database anyway but still wanted to ask
Also what do you mean by this
"once the sub is set to cancel"?
Well you said it was 'scheduled to cancel, which you'd do via an update call on the subscription yes?
No like
If a customer wants to cancel the sub at the end of the billing period
I want to send an email 3 days before the end to advise them it's expiring and set not to auto renew
I don't understand how that scenario is different to what I described, outlined here: https://docs.stripe.com/billing/subscriptions/cancel#cancel-at-the-end-of-the-current-billing-period
What you're doing is the best way. There's no easy way to 'get subscriptions that cancel on X' via the API
let me know if you have other questions
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: "2025-04-30.basil",
});
Do you recommend updating to latest version?
I am still using this one
that's up to you.
you are using 2025-04-30.basil? it's a very recent version. so unless there's something specific you want on the latest version, you don't need to update.
Yup that was my question
If there are any major changes
I started it in May and in fact this was published on May 7
Also, in my email I'd like a "Pay Invoice" button - can I retrieve the invoice link from the invoice object?
Like this one
you can view the changelog here: https://docs.stripe.com/changelog
Also, in my email I'd like a "Pay Invoice" button - can I retrieve the invoice link from the invoice object?
yes: https://docs.stripe.com/api/invoices/object?api-version=2025-07-30.preview&lang=php#invoice_object-hosted_invoice_url
By default if the payment fails it means the invoice has alread ybeen finalized right?
So there's no chance it will be null
By default if the payment fails it means the invoice has alread ybeen finalized right?
correct
