# One subscription in, one subscription out — no one has to do it by hand

*Design update — subscription cutover*

When a customer moves to a new NetSuite subscription, Billing used to wait for someone to notice the change, confirm the old subscription was really finished, and update two records by hand — sometimes days apart. That manual gap is gone: the moment the new subscription shows up, Billing retires the old one, turns the new one on, and carries every day of usage the old one already recorded forward — automatically, in one step.

**Upload `diagram-1-swap-flow.svg` here as an image** — it shows: a new subscription created in NetSuite tells Billing immediately; Billing then, in one step, closes the old subscription, turns on the new one, and moves the old subscription's usage history onto the new one; the result is a single active subscription with nothing missing.

> The step that used to be a person checking a report and editing two records by hand is now one automatic action, triggered the instant NetSuite creates the new subscription.

## Before / Now

**Before:** Someone had to notice the new subscription, check whether the old one had actually finished, and flip both records by hand — sometimes days or weeks after the fact.

**Now:** Billing does it the moment the new subscription appears. It doesn't matter how long the old one had been running, or how many days apart the two events happen.

## Also: a notification email

Every swap sends an email with the details — the old and new subscription, when it happened, and how many days of usage were carried over. If a swap fails partway through, the same email still goes out, marked as failed, so it's never silently missed.

## Scope

This only applies when one **Enterprise** subscription is replacing another. Upgrading a Trial account to its *first* Enterprise subscription is a separate, already-existing process — there's no prior Enterprise usage to carry over, so none is copied.

**Upload `diagram-2-usage-continuity.svg` here as an image** — it shows: although the old subscription was live for the first half of the month and the new one for the second half, all of that usage ends up recorded together on the new subscription, so its final record covers the full month with nothing missing.

> The old subscription only carried usage for the days it was actually live. At the swap, those days are added to the new subscription's own record — so however late the swap happens, nothing from before it is ever dropped.

---

## For engineers: what changes underneath

The two records referred to above are billing `Contract`s. This is the state change the automatic swap performs — no separate waiting state in between, every time it fires.

It only fires when the contract being replaced is itself a NetSuite Enterprise contract: `Status == ACTIVE_SUBSCRIPTION && Provider == SUITEBILLING`. Trial (`NETFOUNDRY_INTERNAL`) and Self-Service (`CHARGEBEE`) contracts can carry the same `ACTIVE_SUBSCRIPTION` status, so the provider check is what keeps their usage from ever being pulled into a new Enterprise contract.

A notification email fires after every swap attempt, success or failure, via the existing SES-backed mailer already used for other billing reports — not a new alerting channel. It's dispatched asynchronously so a slow or failed send can never affect the swap it's reporting on.

| Contract | Before the swap | After the swap |
|---|---|---|
| Old subscription's | `ACTIVE_SUBSCRIPTION` | `CANCELLED_FOR_UPGRADE` — resources and this period's usage moved out |
| New subscription's | didn't exist yet | `ACTIVE_SUBSCRIPTION` — resources and old usage moved in |
