Skip to main content

Subscription Lifecycle

States

draft → confirmed → trialing → active ↔ past_due → canceled

paused
StateDescription
draftDraft. Can be freely edited before confirmation
confirmedConfirmed, awaiting activation
trialingIn a free trial period
activeActive, generating recurring charges
past_dueHas overdue payments
pausedTemporarily paused (no charges)
canceledCanceled (terminal state)

Creating a Subscription

To create a subscription, provide:

FieldRequiredDescription
Billing accountYesThe customer account to be charged
PlanNoPre-configured plan (or individual items)
Billing cycleYesmonthly, quarterly, semiannual, or annual
Collection methodYescharge_automatically, manual_charge, or manual_invoice
Trial periodNo0 to 90 days of free trial
Discount codeNoDiscount to be applied
ItemsNoProducts, prices, and quantities (if not using a plan)
CompanyNoIssuing company (for multi-company setups)

Creation Flow

  1. The subscription is created with draft status
  2. Items are created from the provided items or from the plan items
  3. The discount code usage is incremented (if provided)
  4. A subscription.db.created event is emitted

Confirmation and Activation

Confirm (draftconfirmed)

Confirms the subscription, optionally creating the first invoice.

Activate (draft/confirmedtrialing/active)

  • If it has a trial period: status changes to trialing, with trialStart and trialEnd set
  • If there is no trial: status changes directly to active
  • Sets the billing period dates (currentPeriodStart, currentPeriodEnd)

Activation Preview

Before activating, you can preview:

  • Start date, whether there will be a trial, trial duration
  • Billing period dates
  • First invoice date
  • Setup and recurring totals

Renewal

Renewal is automatic via a daily worker (00:00 UTC):

  1. Finds active subscriptions with currentPeriodEnd ≤ now
  2. If cancelAtPeriodEnd = true: cancels the subscription
  3. Otherwise: advances to the next billing period
  4. Uses optimistic locking to prevent duplicate renewals

Period Calculation

CycleDuration
monthly+1 month
quarterly+3 months
semiannual+6 months
annual+1 year

Cancellation

Cancel at End of Period (cancelAtPeriodEnd: true)

  • Sets the cancelAtPeriodEnd flag
  • The subscription remains active until the end of the current period
  • On renewal, the status changes to canceled
  • Can be reversed before the cancellation date

Cancel Immediately (cancelAtPeriodEnd: false)

  • Status changes to canceled immediately
  • The cancellation date is recorded
  • The cancellation reason is stored

Revert to Confirmed

Active subscriptions can be reverted to confirmed to allow editing before reactivating. Useful for correcting errors before the next renewal.

Deletion

Only subscriptions in draft, confirmed, or canceled status can be deleted, and only if there are no invoices with payments.

MRR Calculation

MRR (Monthly Recurring Revenue) is calculated by normalizing the total value to a monthly basis:

CycleFormula
monthlyTotal of items
quarterlyTotal / 3
semiannualTotal / 6
annualTotal / 12

Emitted Events

EventWhen
subscription.db.createdSubscription created
subscription.confirmedConfirmed
subscription.activatedActivated
subscription.renewedRenewed
subscription.pausedPaused
subscription.resumedResumed
subscription.canceledCanceled
subscription.pending_cancellationMarked for cancellation at end of period
subscription.plan_changedPlan changed
subscription_status_changedAny status change