Skip to main content
A test clock advances logical time for a test customer and its billing objects. It lets you exercise months of subscription behavior in minutes without changing production time or waiting for a real billing date.

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.
A renewal can be completely correct in Ionic while the end-user experience is incorrect because an integration changed the wrong account or reacted to the wrong event. Test clocks let you verify that integration behavior through the same Ionic objects and events used in production.

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.
Finish each customer and subscription creation request before advancing its clock. Ionic serializes those writes with advancement, but waiting for each response gives your test a clear creation-before-advancement order.

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.
Arm the scenario before advancing the clock to the renewal or retry boundary. After a failed attempt schedules a retry, arm {"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.
Poll 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.
  • 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.
Test clocks work only in test mode. They never affect live customers, subscriptions, invoices, collection attempts, events, or money movement.

Platforms and connected accounts

An authorized platform may include Ionic-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.