Simulated Clock

Simulated Clock

Many Synapto flows are driven by the passage of time rather than a single API call: a Direct Debit mandate is confirmed by the bank a few working days after setup, a Direct Debit collection is treated as paid once its return window closes without a bounce, and a subscription renews at each period boundary. Waiting real days to test these isn't practical.

A simulated clock lets you fast-forward time for a single test customer so these time-driven transitions happen on demand — running the same logic and firing the same webhooks they would in production.

🚧

Sandbox only

Simulated clocks exist only in the sandbox environment. Creating one is rejected in production.

How it works

  • A simulated clock is owned by one customer and created together with that customer. It has a sim_now — the customer's simulated "current time" — that starts at the customer's creation time (or a start time you choose) and only ever moves forward.
  • That customer's Direct Debit and subscription lifecycles are evaluated against its clock's sim_now instead of the wall clock.
  • Advancing the clock runs the time-driven work for that customer's objects up to the new time — Direct Debit mandate activation, the collection cycle, subscription renewals, and any other scheduled jobs due for that customer — and emits the resulting webhooks from real simulated state.
  • Everything is scoped to that one customer; other data is unaffected.

1. Create a customer with a simulated clock

Set with_simulated_clock: true on CreateCustomer. Optionally set start_time to park the clock on a specific date (useful for exercising date-sensitive behaviour like bank holidays); it defaults to the creation time and may be in the past.

curl -X POST https://api.synaptopay-sandbox.com/v1/accounts/acct_YOUR_ACCOUNT/customers \
  -H "Authorization: Api-Key $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "full_name": "Pat Customer",
      "email": "[email protected]"
    },
    "with_simulated_clock": true
  }'

The response is an ordinary customer with a simulated_clock showing the current simulated time:

{
  "name": "accounts/acct_YOUR_ACCOUNT/customers/cus_CUSTOMER_ID",
  "full_name": "Pat Customer",
  "email": "[email protected]",
  "simulated_clock": {
    "sim_now": "2026-07-13T09:00:00Z"
  },
  "create_time": "2026-07-13T09:00:00Z"
}

The clock binding is fixed at creation — a customer can't be attached to or detached from a clock afterwards.

2. Set up what you want to test

Using that customer, set up the flow you want to exercise — for example, capture a Direct Debit mandate or create a subscription. Its objects are now bound to the customer's clock and won't progress on wall-clock time; they move only when you advance the clock.

3. Advance the clock

Advance the customer's clock to a later time with advance_to, which must be at or after the current sim_now — the clock only moves forward. Advancing runs the customer's time-driven work up to that point, fires the resulting webhooks, and returns the updated customer.

curl -X POST "https://api.synaptopay-sandbox.com/v1/accounts/acct_YOUR_ACCOUNT/customers/cus_CUSTOMER_ID:advance-clock" \
  -H "Authorization: Api-Key $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "advance_to": "2026-07-20T09:00:00Z"
  }'
{
  "name": "accounts/acct_YOUR_ACCOUNT/customers/cus_CUSTOMER_ID",
  "simulated_clock": {
    "sim_now": "2026-07-20T09:00:00Z"
  }
}

You can advance repeatedly to step through a lifecycle (for example, past a mandate's activation window, then past a collection's return window). The clock never moves backward.

What advancing drives

Advancing the clock exercises the time-based transitions — and the webhooks — you'd otherwise wait days for:

FlowAdvance past…Result
Direct Debit mandatethe scheme confirmation window (a few working days)mandate → ACTIVE, dd_mandate.active / setup_intent.succeeded
Direct Debit collectionthe return window after the payment daycharge → SUCCEEDED, charge.taken then payment_intent.succeeded
Subscriptiona period boundarya renewal collection is created and billed

To test negative Direct Debit outcomes (a bounced collection, a suspended or rejected mandate), use the on-demand trigger endpoints instead of the clock — see Direct Debit → Testing in sandbox.

Rules and limits

  • Sandbox only — rejected in production.
  • One clock per customer, created with the customer; the binding is immutable.
  • Forward onlyadvance_to must be at or after the current sim_now.
  • Up to one year per request — a single advance can move the clock forward at most one year; step through longer spans with repeated calls.
  • Scoped to the customer — advancing one customer's clock never affects another customer's objects or any wall-clock data.

Did this page help you?