Lifecycle and States
A Firmly purchase moves through several state machines — session, cart, checkout, order — each with its own lifetime and transition rules. This page covers each lifecycle so a destination engineer knows what state exists at any moment and how long it lives.
Session lifecycle
| State | Meaning | Duration |
|---|---|---|
| Bootstrap requested | POST /browser-session made; awaiting response |
Sub-second |
| Active | Token issued, device_id assigned |
~1 hour from issue |
| Expired (renewable) | Token past exp; prior session state still retained |
Renewable while session state persists (~7 days from last activity) |
| Expired (state cleared) | Session state garbage-collected | Permanent — must bootstrap fresh |
Renewal: re-POST to /browser-session with the prior (expired) token in the body. As long as the session state is still retained, Firmly returns a new token with the same device_id. There’s no separate server-enforced renewal window — renewal works while the session state persists (~7 days from last activity), after which a fresh bootstrap is required.
Cart lifecycle
| State | Meaning | Triggers |
|---|---|---|
active |
Cart exists, items can be added/removed/modified | POST /cart/line-items (first item creates the cart implicitly) |
item_not_shippable |
One or more line items can’t ship to the chosen address | Set during POST /cart/shipping-info when an item has no valid shipping option |
checkout_blocked |
Cart has validation errors preventing checkout | Out-of-stock items, expired promotions, shipping unavailable — see Cart lifecycle |
pending |
Reserved — no current cart operation produces it | Treat as an unexpected state; don’t branch checkout logic on it |
submitted |
Order successfully placed at merchant | Merchant returned order ID |
Cart persistence: cart state is held in Firmly’s session store for ~7 days from the last activity. After 7 days idle, the cart is garbage-collected; the destination must start a fresh cart.
Order placement lifecycle
POST /payment/place-order is the moment the cart transitions to submitted. The response includes:
| Field | What it represents |
|---|---|
cart_status |
submitted on success. A payment failure returns a 422 CreditCardDeclined error rather than a status value |
cart_id |
Firmly’s stable reference for the cart |
urls.thank_you_page |
Merchant’s own confirmation URL (populated post-success) |
platform_order_number |
Merchant’s native order number — capture for reconciliation |
Post-submitted, Firmly’s scope ends. The order is the merchant’s responsibility for fulfillment, tracking, returns, and refunds.
Idempotency window
On the UCP protocol bridge, Idempotency-Key values are cached for 24 hours: the same key within the window returns the cached response, and the operation runs at most once.
The core REST endpoints accept the header but do not deduplicate on it today — a REST retry re-runs the operation. Before retrying a failed place-order over REST, re-read the cart and check cart_status: if it’s already submitted, the order went through. See Errors & Conventions → Idempotency.
State diagram — a typical purchase
What expires when
| Token / state | Expires after | Recovery |
|---|---|---|
| Session JWT | ~1 hour | Renew via re-POST to /browser-session |
| Cart state | 7 days idle | Start fresh cart |
| Idempotency key | 24 hours | Different key = new call |
| Payment public key cache | Rotated periodically; cadence not public | Re-fetch via GET /payment/key on invalid-key encryption error |
submitted order |
Permanent (no Firmly-side TTL) | n/a — merchant’s OMS owns post-order |
Destination-side state to track
A destination engineer should hold:
| State | Why |
|---|---|
Current session JWT + device_id |
For subsequent API calls and renewal |
| Current cart state (last response) | Avoids re-fetching for read-only renders |
| Idempotency key per logical operation | Stable for retries within 24h |
Order success indicators (cart_status, merchant order ID) |
For reconciliation and reporting |
| Attribution params (UTM, click-IDs) | Persisted in session for inclusion on place-order |
Related
- Security Model — session lifetime in security terms
- Data Flow — what data moves through each state
- Cart Lifecycle (API reference) — endpoint-level detail
- Errors & Conventions — error states and recovery
- Authentication — session bootstrap and renewal patterns