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 onlySimulated 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_nowinstead 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:
| Flow | Advance past… | Result |
|---|---|---|
| Direct Debit mandate | the scheme confirmation window (a few working days) | mandate → ACTIVE, dd_mandate.active / setup_intent.succeeded |
| Direct Debit collection | the return window after the payment day | charge → SUCCEEDED, charge.taken then payment_intent.succeeded |
| Subscription | a period boundary | a 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 only —
advance_tomust be at or after the currentsim_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.
Updated 19 days ago