What a test clock proves
Ionic remains authoritative for subscription state, invoices, collection schedules, and public events. You do not need to re-test Ionic’s billing calculations. Your platform still owns what happens after Ionic reports a lifecycle change. For example, an EHR platform may need to:- keep the correct clinic active while collection retries are pending;
- restore access after a later collection succeeds;
- restrict only the affected account when retries are exhausted;
- notify the appropriate administrators or billing contacts;
- update its own reporting and account state exactly once; and
- handle retried or out-of-order events without duplicating changes.
How it works
1
Create a clock
Create a clock with a test-mode secret key and choose its initial Unix
timestamp. The clock starts in
ready.2
Attach a test customer
Pass the clock ID as
test_clock when creating a test customer. The
relationship is permanent, and subscriptions plus billing records created
for that customer inherit the same logical time.3
Create the subscription scenario
Create prices, an active payment method, and a subscription through the
normal test APIs. Arm a one-shot collection outcome when you need the next
automatic attempt to succeed or decline deterministically.
4
Advance and poll
Request a later target. Advancement is asynchronous because Ionic processes
every intervening lifecycle action in chronological order. Poll the clock
until it returns to
ready.5
Assert both sides
Inspect Ionic subscription, invoice, collection-attempt, entitlement, and
event state. Then assert that your own access control, notifications,
reporting, and account state match.
Create a test clock
Attach a customer
The customer and clock must belong to the same Ionic account. Test clocks cannot be attached in live mode or reassigned later.Advance the clock
Arm the next collection outcome
Use a collection scenario when your test needs a specific result from the next automatic attempt. The scenario belongs to one test-mode subscription and is consumed by one newly recorded charge attempt.{"outcome":"succeeded"} and
advance to the next attempt time to verify recovery. To verify retry exhaustion,
arm one declined scenario before each retry boundary.
Only one unconsumed scenario can be armed for a subscription. Retrying the
scenario-creation request with the same idempotency key replays its original
response. A different scenario conflicts until the current one is consumed.
When no scenario is armed, Ionic uses the normal test-mode collection path.
Collection scenarios require charge_automatically, reject ended
subscriptions, and cannot be created or consumed in live mode.
The target must be strictly later than frozen_time and no more than two
calendar years ahead. A clock cannot rewind or accept a second overlapping
advancement. After it returns to ready, you can advance it again.
GET /v1/test_clocks/{id} until status becomes ready. Do not assert
final subscription state while the clock is still advancing.
If the clock becomes failed, resolve the reported issue and call the advance
operation again with the same target_time and a new idempotency key. Ionic
resumes after the last committed checkpoint. A failed clock cannot be sent to
a different target because that would fork the original lifecycle timeline.
Status values
Ionic limits concurrent advancement per account so one test suite cannot
monopolize shared processing. A limit response is safe to retry after existing
advancement work finishes.
Recommended scenarios
- Trial completion with successful first collection.
- Successful renewal and unchanged access.
- Definite renewal failure followed by each retry boundary.
- Recovery on a later attempt.
- Retry exhaustion and the intended access restriction.
- Cancellation at period end without an extra renewal.
- A multi-period jump that produces every intervening invoice and event.
- Duplicate and out-of-order public event delivery.
Platforms and connected accounts
An authorized platform may includeIonic-Account on clock operations to
select a connected test account. The clock, customer, and subscription must all
belong to that selected account. A platform cannot advance one account’s clock
while operating another account.
