# Subscriptions and invoices

Stripe Billing on the simulator's clock: first invoices, trials, renewals, failed-payment retries, prorations, pause and resume, cancellation and the customer balance.

Subscriptions bill as Stripe Billing does, and their trials, renewals and payment retries happen when you move the clock. Subscribe a customer with a saved card, move the clock past the first period and list the invoices:

```bash
curl -s "$RYSTIC_URL/v1/customers" -u sk_test_123: -d email=jenny@example.com -d payment_method=pm_card_visa -d 'invoice_settings[default_payment_method]=pm_card_visa' | jq -c '{id}'
# -> {"id":"cus_lllllllllllllc"}
curl -s "$RYSTIC_URL/v1/prices" -u sk_test_123: -d unit_amount=1500 -d currency=usd -d 'recurring[interval]=month' -d 'product_data[name]=Hosting' | jq -c '{id}'
# -> {"id":"price_1"}
curl -s "$RYSTIC_URL/v1/subscriptions" -u sk_test_123: -d customer=cus_lllllllllllllc -d 'items[0][price]=price_1' -d 'expand[]=latest_invoice' | jq -c '{id, status, invoice: .latest_invoice.status, amount_paid: .latest_invoice.amount_paid}'
# -> {"id":"sub_Rystic0000000001","status":"active","invoice":"paid","amount_paid":1500}
curl -s -X POST "$RYSTIC_URL/_rystic/clock" -d '{"advance_seconds": 2764800}'
curl -s "$RYSTIC_URL/v1/invoices?customer=cus_lllllllllllllc" -u sk_test_123: | jq -c '[.data[] | {billing_reason, status, amount_paid}]'
# -> [{"billing_reason":"subscription_cycle","status":"paid","amount_paid":1500},{"billing_reason":"subscription_create","status":"paid","amount_paid":1500}]
```

### The first invoice

`POST /v1/subscriptions` writes the first invoice (`billing_reason` `subscription_create`, one line per item), which `latest_invoice` names. With `charge_automatically` and a card, the subscription's `default_payment_method` or else the customer's `invoice_settings.default_payment_method`, the invoice is paid at once by a PaymentIntent and charge on that card, and the charge credits the balance. A customer with no currency takes the subscription's. The create sends `payment_intent.created`, `charge.succeeded`, `payment_intent.succeeded`, `customer.updated` (only when the customer's currency or balance moved), `invoice.finalized`, `invoice.created`, `invoice_payment.paid`, `invoice.paid`, `invoice.payment_succeeded` and `customer.subscription.created`, in that order, its `payment_intent.created` carrying the PaymentIntent as created, before the charge. The first invoice's PaymentIntent carries `setup_future_usage` `off_session`, which an invoice pay that succeeds sets to null.

With no card and no trial, a create whose `payment_behavior` is absent, `allow_incomplete` or `error_if_incomplete` answers 400 `resource_missing` and creates nothing once the account holds any PaymentMethod; in an account that holds none it reads `active` with an open first invoice. `default_incomplete` answers `incomplete`, with an open invoice and a PaymentIntent awaiting confirmation, which an invoice pay or a confirm pays as below, `attempt_count` becoming 1. A `send_invoice` subscription is `active`, and its first invoice is a draft that finalizes an hour after the create. A `billing_cycle_anchor` ahead of a create with no trial runs the first period to the anchor, billed on the first invoice as a proration of the interval that ends there, with its own invoice item.

Before it looks anything up, a create answers Stripe's 400 to these, in this order, each naming only that parameter even beside one it conflicts with: an empty `collection_method` (`parameter_invalid_empty`) or one other than `charge_automatically` or `send_invoice`; an empty `trial_end` or one that is neither `now` nor a Unix time; an empty `cancel_at` or one that is neither a Unix time nor `min_period_end`, `max_period_end` or `max_billed_until`.

### A declined first payment

A card whose charge declines, such as `pm_card_chargeCustomerFail`, leaves the create `incomplete`, `trial_end=now` or not. The first invoice stays open with one attempt and `next_payment_attempt` null, and its PaymentIntent reads `requires_payment_method`. The customer is not made `delinquent`. The create sends `payment_intent.created`, `charge.failed`, `payment_intent.payment_failed`, `customer.updated` (as above), `invoice.payment_failed`, `invoice.created`, `invoice.finalized` and `customer.subscription.created`. Under `payment_behavior=error_if_incomplete` it answers the decline's 402 instead, leaving no subscription or invoice and the PaymentIntent `canceled` (`payment_intent.canceled`).

Paying an `incomplete` subscription's open invoice, by an invoice pay or by confirming its PaymentIntent with a card that charges, makes it `active` at once, reusing the invoice's PaymentIntent and invoice payment: `attempt_count` stays 1 and `auto_advance` turns false. The payment sends `charge.succeeded`, `payment_intent.succeeded`, `invoice_payment.paid`, `invoice.updated`, `invoice.paid`, `invoice.payment_succeeded` and `customer.subscription.updated`. A confirm also sends `payment_method.attached` after the charge, as it attaches the card.

### Trials

A trial, from `trial_period_days` or a `trial_end` after the create's clock (its customer's test clock's `frozen_time` when it is on one), needs no card. Its first invoice is paid at zero with lines reading `Free trial for <quantity> × <product>`, and its items run from the create to `trial_end`. Its `billing_cycle_anchor` is `trial_end` unless the create sets one. With no card, a `charge_automatically` trial also makes a pending SetupIntent, `requires_payment_method` with `usage` `off_session`, named in `pending_setup_intent` and announced by `setup_intent.created` before the create's other events; nothing later clears it. A `send_invoice` trial keeps `pending_setup_intent` null (inferred), and the succeeded SetupIntent Stripe makes for a trial with a card is not modeled. A create answers Stripe's 400 to `trial_end` beside `trial_period_days`, and to a `trial_end` at or before its clock, with `param` `trial_end`.

A later `trial_end` on an update moves the anchor, the period end and a period-end `cancel_at` with it, and bills the added days on a paid zero invoice. One at or before the subscription's clock answers Stripe's 400 with `param` `trial_end`, and one that is neither `now` nor a Unix time answers 400 "Invalid trial_end: must be one of now", as a hash or an array does. `trial_end=now` on an update ends the trial at once and bills the new period from the card; a declining card leaves that invoice open with one attempt and the subscription `past_due`, its customer not made `delinquent`, with `invoice.payment_failed`, naming no request, after the update's own events.

Three days before `trial_end` (at once for a shorter trial, and on a test clock at its next advance) the clock sends `customer.subscription.trial_will_end`, after `invoice.upcoming` previewing the invoice the trial's end will write, when it will write one and the trial runs three days or more. At `trial_end`, a subscription with a card, a `send_invoice` one or one whose `trial_settings[end_behavior][missing_payment_method]` is `create_invoice` (the default) reads `active` and renews as at a period end; a `billing_cycle_anchor` after `trial_end` is billed first, as a proration up to it with its own invoice item. With no card, `pause` pauses the subscription instead (`status_details` names `trial_end_without_payment_method`) and `cancel` cancels it, writing no invoice.

### Renewals and failed payments

When the clock passes an `active` or `past_due` subscription's period end, a draft renewal invoice is written (`invoice.created`, `customer.subscription.updated`) and finalizes an hour later, paid from the card under `charge_automatically` (`charge.succeeded`, `payment_intent.succeeded`, `payment_intent.created`, `customer.updated` when a balance moved, `invoice.updated`, `invoice.finalized`, `invoice.paid`, `invoice.payment_succeeded` and `invoice_payment.paid`, each naming no request). Seven days before the period end, `invoice.upcoming` goes out once, naming no request and previewing the renewal's lines, amount and period. The lead is the account's "upcoming renewal events" setting, which the simulator fixes at seven days; a subscription set to cancel at its period end gets none, nor does a period shorter than seven days.

Periods are counted from `billing_cycle_anchor`, each ending on its day of the month or the month's last day, so a Jan 31 anchor renews on Feb 28, Mar 31 and Apr 30. Each item renews on its own price's interval, so a yearly item beside a monthly one is billed once a year. An item whose `current_period_end` is not a time, as a seeded record's `0`, never renews.

With no card under `charge_automatically`, or with `pm_card_chargeCustomerFail`, a renewal's or a trial end's payment fails as the invoice finalizes: the invoice stays open with one attempt and `next_payment_attempt` 42.1 hours on, the subscription reads `past_due` and the customer `delinquent`. The declining card also leaves a `failed` charge carrying the decline (`charge.failed`) and the PaymentIntent `requires_payment_method` with the decline as its `last_payment_error` (`payment_intent.payment_failed`); paying the invoice with another card clears it. The clock retries at `next_payment_attempt`: with no card, or the declining one (inferred), each attempt fails again and dates the next 42.1 hours on, until the ninth fails for the last time, leaving the invoice open with `auto_advance` false and no retry, the subscription canceled for `payment_failed` and the customer `delinquent`. With a card that charges, the retry pays the invoice, its `customer.updated` last.

Voiding, marking uncollectible or paying the invoice reads the subscription `active` in that request, and the customer not delinquent even while another of its subscriptions is still `past_due`; the paid invoice reads `auto_advance` false and no retry, its `attempt_count` unchanged.

### Items and prorations

An item added later, through `POST /v1/subscription_items` or an update's `items[]`, takes the subscription's current period: that of an item of its interval, the trial's in a trial or else its interval's period around now, bounded by `billing_cycle_anchor`. Unless `proration_behavior` is `none`, an item added to an `active` or `past_due` subscription leaves a pending proration for the rest of the period, which the next renewal bills first.

Under `always_invoice`, `POST /v1/subscription_items` bills the proration at once instead, on an invoice `latest_invoice` then names: paid from the card under `charge_automatically`, paid with no payment when there is nothing to bill and under `send_invoice` a draft that finalizes an hour later. Under `charge_automatically`, when the proration is above 0 and no stored payment method resolves (a `default_source` naming none counts as none), the add is refused with Stripe's 400 `resource_missing`, `past_due` or not, while a proration that rounds to 0 is paid at once; an update's `items[]` add waits for the renewal.

A change of an item's price or quantity prorates nothing. Deleting an item mid-period leaves a pending credit for its unused time, figured from what was last billed for it, and writes no invoice. An update or item delete that would leave a subscription with no item answers Stripe's 400, as does an update whose `items[]` names another subscription's item or an id no item has ("No subscription item with this ID (`<id>`) on the subscription."), changing neither subscription. An update whose `items[i][id]` is empty answers 400 `parameter_invalid_empty`.

`billing_cycle_anchor=now` on an update of an `active` or `past_due` subscription restarts its period at once and writes no invoice; unless `proration_behavior` is `none`, it leaves one pending proration for the days the new period adds, which the next renewal bills first. On a `paused` subscription it is refused; in any other status it moves the anchor alone. Invoice items created with `POST /v1/invoiceitems` stay pending, even with a `subscription` in the request.

### Cancellation

A create's `cancel_at` records a cancellation request, `canceled_at` the create's time. One before the first period's end ends that period there, billed on the first invoice as a proration with its own invoice item (a trial keeps its `trial_end` and anchor, its zero line running to `cancel_at`), and the clock ends the subscription at `cancel_at` with no further invoice. A `cancel_at` of `min_period_end`, `max_period_end` or `max_billed_until` sets it to the first period's end, billing that period whole. A `cancel_at` at or before the create's clock, or beside `cancel_at_period_end=true`, answers Stripe's 400.

`cancel_at_period_end=true` sets `cancel_at` to the period end; once the clock reaches `cancel_at`, the subscription reads `canceled` and `customer.subscription.deleted` goes out. A renewal or a trial end whose next period would run past `cancel_at` bills only up to it (`trial_end=now` still bills the whole period), and a renewal into a period shorter than the price's interval, after a cleared `cancel_at`, bills that period, each as a proration. A subscription the clock ends keeps the request's time in `canceled_at`, with `ended_at` the end and `cancel_at` and `cancel_at_period_end` kept; a `DELETE` while the request is pending keeps `canceled_at` too and clears both.

An update whose `cancel_at` is not after the subscription's clock (a test clock's `frozen_time` on one) answers Stripe's 400 "The `cancel_at` param can only be set to a date in the future." An update setting `cancel_at_period_end`, true or false, or `billing_cycle_anchor=now` on a `paused` subscription answers Stripe's 400 asking for a resume first, writing nothing; with both, the anchor's refusal answers. A `cancel_at_period_end` that is neither `true` nor `false` answers 400 "Invalid boolean: `<value>`" before either.

Ending a subscription, by `DELETE`, at its `cancel_at`, at its last failed retry or by its customer's delete, stops automatic collection of every open invoice of the customer and of the subscription's own renewal draft: each reads `auto_advance` false and no retry, with `invoice.updated` naming no request. The draft never finalizes, and the clock retries none of them. `cancel_at_period_end=true` stops nothing before the period ends. `DELETE` with `invoice_now=true` and `prorate=true`, in the body or the query string, credits each item's unused time on a final 0.00 invoice paid an hour later, which puts the credit on the customer's `balance` and clears `delinquent`. A `cancel_at` inside the period cuts the items' period there and leaves the same credit pending, billed on such a final invoice when the clock ends the subscription.

### Pause and resume

A resume under `billing_cycle_anchor=now` (the default) leaves the subscription `paused`, with a `pending_update` and an open `subscription_cycle` invoice for the period it starts, which nothing charges on its own; each resume writes another. Once the latest is paid or marked uncollectible, the subscription reads `active` from the resume and sends `customer.subscription.resumed`, carrying the subscription as it stood before (`trialing`, as Stripe's does), then `customer.subscription.pending_update_applied` and `customer.subscription.updated`. Once the clock passes `pending_update.expires_at`, 23 hours after the resume, an unpaid resume invoice is voided, its PaymentIntent canceled and `pending_update` cleared, and the subscription stays `paused` (`customer.subscription.pending_update_expired`); a `DELETE` before then does the same before it cancels. A resume under `billing_cycle_anchor=unchanged` reads `active` at once with no invoice, on the anchor's schedule, and unless `proration_behavior` is `none` leaves a pending proration for the rest of the period, billed with the next renewal.

### Deleting a customer

Deleting a customer cancels each of its subscriptions that is not already `canceled` or `incomplete_expired`, at the delete's time on the subscription's clock (a pending cancellation request keeps its `canceled_at`), with `cancellation_details.reason` `cancellation_requested`, so none renews. It sends `customer.deleted`, carrying the customer as it stood, before each one's `customer.subscription.deleted`. Each `draft` invoice of such a subscription reads `uncollectible` first, never finalized or charged (`invoice.updated` and `invoice.marked_uncollectible` go out before `customer.subscription.deleted`), and a void of it answers Stripe's 400; its pending invoice items stay pending.

### Connected accounts

A subscription created acting as a connected account settles as that account: the PaymentIntents and charges its renewals, trial end and later payments make are in that account's lists and balance, and every event its clock sends is the account's, listed by the account's `GET /v1/events` and sent to the platform's `connect=true` endpoints.

### The customer balance

A customer's `balance` is a credit when negative and an amount owed when positive: a customer create or update sets it, a credit note's `credit_amount` lowers it and an invoice that ends below zero leaves its credit there. A draft invoice reads `starting_balance` as the customer's balance when it is created, `ending_balance` null and `amount_due` as `total` plus `starting_balance`, never below 0: after a -500 credit, a draft with a 1200 item reads `amount_due` 700 with `total` 1200. A balance that changes while an invoice is a draft shows only when it is finalized.

Finalizing reads the balance again, so a credit another invoice spent first is not applied twice: the invoice reads `ending_balance` 0 (or the rest of a larger credit) and its PaymentIntent asks for the reduced amount. The customer's `balance` becomes the invoice's `ending_balance`, and `customer.updated` goes out before the finalize's `invoice.updated`. A credit that covers the whole invoice leaves it paid at the finalize with no PaymentIntent. A subscription's first invoice and its renewals spend the balance the same way (inferred, as are a larger credit and a positive balance). The simulator serves no `/v1/customers/{customer}/balance_transactions` and writes no `applied_to_invoice` transaction, and voiding an invoice does not give the balance back.

### Invoice payments

Each invoice payment names the PaymentIntent that pays its invoice. A `paid_out_of_band` pay adds a `paid` one of `type` `payment_record` and cancels the PaymentIntent's, and neither is then the default.

---

Source: https://www.rystic.ai/docs/simulators/stripe/features/subscriptions · Markdown: https://www.rystic.ai/docs/simulators/stripe/features/subscriptions.md
