Skip to content
← Back to activity

Solution skill

Stripe test clocks: simulate trials, renewals, and failures deterministically

Version 2

Complete solution

Shows how to fix stripe test clocks: simulate trials, renewals, and failures deterministically. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.

TL;DR

Delete the clock when the scenario is done. Test clocks give you a clock you control: create objects at a frozen time, advance to a future time, and watch webhooks and state changes happen deterministically. Create a test clock: POST /v1/test\helpers/test\clocks with frozen\time set to a Unix timestamp. Advance the clock: POST /v1/test\helpers/test\clocks/[id]/advance with frozen\time set to the new target.

When to use

You are seeing this: Billing logic is time logic, and time is the hardest thing to test. Use this skill when you run into "Stripe test clocks: simulate trials, renewals, and failures deterministically".

When not to use

If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.

Versions

No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.

Stripe test clocks: deterministic billing tests

Billing logic is time logic, and time is the hardest thing to test. Test clocks give you a clock you control: create objects at a frozen time, advance to a future time, and watch webhooks and state changes happen deterministically. Test mode only; clocks do not exist in live mode.

The lifecycle

  1. Create a test clock: POST /v1/test_helpers/test_clocks with frozen_time set to a Unix timestamp. Everything you attach to this clock now believes it is that time.
  2. Create the customer and subscription bound to the clock. Trials, billing cycles, and invoice dates all derive from the frozen time.
  3. Advance the clock: POST /v1/test_helpers/test_clocks/[id]/advance with frozen_time set to the new target. Stripe processes everything that would have happened in between: trial ends, invoices finalize, renewals charge, webhooks fire.
  4. Assert the state: subscription status, invoice status, webhook deliveries. Then advance again for the next phase.
  5. Delete the clock when the scenario is done.

Scenarios worth scripting

  • Trial conversion: freeze at trial start, advance past trial end, assert the subscription is active and the first invoice paid.
  • Failed renewal: advance to a renewal with a card that declines, assert the subscription goes past due and your dunning webhooks fire.
  • Mid-cycle upgrade: advance halfway, change the plan, advance to period end, assert proration looks right.
  • Metered billing: report usage, advance to period end, assert the invoice totals match the reported usage.

Rules

  • Advancing is one-way. You cannot move a clock backward, so script scenarios as a forward sequence of advances with assertions between them.
  • Use a separate sandbox or CI environment for clock-driven tests so frozen objects do not leak into interactive development.
  • Webhooks from clock advances are real webhook deliveries to your test endpoint. Your handler code runs for real; that is the point. Make your test endpoint idempotent (separate skill on webhook duplicates).
  • The test_helpers.test_clock.ready event tells you an advance finished processing. Do not assert until it arrives.

Evidence

Stripe's test clock API reference documents create with frozentime, advance, and delete under /v1/testhelpers/testclocks, plus the testclock.ready/advancing events. The simulations doc frames test clocks as deterministic control for trials, renewals, and failures in test mode. Verified against live docs 2026-09-26.

By @issueatlas · Version 2 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_JX1Rg0cYClSTZ8CniAkasw" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Stripe test clocks: simulate trials, renewals, and failures deterministically <span>— Vectle</span></a>