S

Glossary

Subscription Lifecycle

The subscription lifecycle is the state machine a subscription moves through between creation and termination. Each state decides two things at once: whether the customer keeps access, and whether the billing system generates an invoice this period. Payment outcomes drive most transitions.

Key Takeaways

  • Stripe's subscription object carries six lifecycle statuses: incomplete, incomplete_expired, trialing, active, past_due, and unpaid.

  • The starting status depends on the collection method, not the plan. Automatic charging starts a subscription at incomplete, while sending an invoice starts it at active.

  • A subscription set to send_invoice reaches active "even if the first invoice is unpaid", so active is not proof anyone has paid.

  • Stripe gives a customer 23 hours to pay the first automatic invoice. Miss it and the subscription hits incomplete_expired and can't be revived, only replaced.

  • A subscription that stops paying keeps generating invoices every period in draft status, so the billing clock runs even while collection is paused.

What states does a subscription move through?

Six, in Stripe's implementation, and the transitions between them are driven almost entirely by invoice outcomes. Stripe puts it plainly: each lifecycle phase "maps to a status change on the Subscription object."

Status

What it means

How a subscription arrives here

incomplete

Created, first payment not yet settled

Automatic collection, no trial

trialing

Access granted, no charge yet

A trial period was configured

active

Billing normally

First invoice paid, or a trial ended, or invoice-sending was chosen

past_due

An invoice failed, retries continuing

Payment failure, per dashboard settings

unpaid

An invoice failed, collection stopped

Payment failure, per dashboard settings

incomplete_expired

Dead, cannot be reactivated

First automatic invoice unpaid after 23 hours

The distinction that catches people is past_due against unpaid. Both mean a payment failed, and which one a subscription lands in isn't a property of the failure. It's a configuration choice in the failed-payment settings, which means the same event produces different statuses across two accounts on the same platform.

Stripe also documents how the status gets computed rather than just set: "Voided invoices don't affect subscription status. Stripe determines the status from the most recent non-voided invoice." Void an invoice to clean up a mistake and the status recalculates off whatever came before it.

Why can a subscription be active while its invoice is unpaid?

Because the collection method decides the starting state, and invoice-sending grants active immediately. Stripe's docs are explicit: for subscriptions with send_invoice and no trial, "the initial subscription status is active, even if the first invoice is unpaid."

That's correct behavior for enterprise billing, where a signed contract and net-30 terms mean access should start before money moves. It's also why reading active as "this customer has paid" is wrong.

The two collection paths diverge from the first second:

  • Automatic charging opens at incomplete with an open invoice, and the customer has 23 hours. Pay inside the window and the subscription goes active. Miss it and the subscription goes incomplete_expired while the invoice is voided, and Stripe's guidance is to create a new subscription rather than repair the old one.

  • Sending an invoice opens at active with a configurable due date, and the unpaid invoice doesn't hold anything back.

The 23-hour figure matters more than it looks. It exists to cover a customer who wanders off mid-checkout and returns, and it means a failed self-serve signup leaves a dead subscription record behind rather than a retryable one.

Which state changes should trigger a handler?

The ones that change access or start a recovery, which is a much shorter list than the full set of transitions. Wiring a handler to every status change produces noise and duplicate provisioning.

The transitions worth acting on:

  1. Anything reaching active, which is where you grant access. Stripe creates an active entitlement per feature at this point, so feature gating can read entitlements rather than subscription status.

  2. trialing ending, because a trial that converts and a trial that fails to convert look identical until the invoice resolves.

  3. Entry into past_due, which starts the dunning sequence rather than an immediate cutoff, since most of these recover through payment retry.

  4. Entry into unpaid or incomplete_expired, the two terminal-ish states where access should actually stop.

What not to handle: every draft invoice the subscription generates while it isn't paying. Those accumulate by design and reconciling them one by one at recovery time is the job, not reacting to each one as it appears.

Related terms

Lifecycle questions almost always turn into billing-timing questions, so these sit close by.

  • Billing Cycle is the recurring rhythm the lifecycle runs against.

  • Billing Period is the span a single invoice covers within that rhythm.

  • Draft Invoice is the state invoices pile up in while collection is paused.

  • Payment Retry is the mechanism that pulls a subscription back out of past_due.

  • Involuntary Churn is where the lifecycle ends for reasons the customer never chose.

  • Feature Gating is the layer that should be reading entitlements rather than raw status.

FAQ

How does the subscription lifecycle differ from the billing cycle?

The lifecycle is the set of states a subscription can be in. The billing cycle is the repeating interval that triggers invoices. A subscription on a monthly billing cycle can pass through four different lifecycle states inside one month, and a subscription can sit in a single state across dozens of cycles.

Does a cancelled subscription have a status?

Cancellation is recorded on the subscription rather than being one of the failure statuses above, and it's the one transition a customer initiates. That's worth separating in your own reporting, because voluntary cancellation and a slide into unpaid describe completely different problems even though both end access.

Should access be revoked as soon as a payment fails?

No, and doing it costs recoverable revenue. A first failure usually means an expired card or a temporary decline, which is what the retry schedule exists for. Cut access at past_due and you've turned a fixable billing event into a support ticket and, often, a cancellation.

Why did a subscription go straight to incomplete_expired?

The first invoice on an automatically charged subscription went unpaid past the 23-hour window. Stripe voids that invoice and marks the subscription expired, and it can't be brought back. The fix is creating a fresh subscription for the customer rather than trying to repair the record.

Back to glossary

Get Instant Feedback on Your Pricing | Join the Flexprice Community with 400+ Builders on Slack

Join the Flexprice Community on Slack