Concepts
Session lifecycle
Handle session statuses, phases, and checkout method locking.
A payment session moves through lifecycle statuses and UI phases until it reaches a terminal outcome. Understanding both layers helps you build reliable checkout UX and webhook handlers.
Session statuses
Session opened
Payer attached
Payment succeeded
Idle or pay window elapsed
Payment cancelled
Payment failed
Status definitions
| Name | Type | Description |
|---|---|---|
CREATED | active | Session opened. Checkout is available; payer not yet attached. |
AWAITING_PAYMENT | active | Payer attached and payment in progress in the Zippy mobile app. |
COMPLETED | terminal | Payment succeeded. Emits payment_session.completed. |
EXPIRED | terminal | Idle or pay window elapsed without completion. Emits payment_session.expired. |
CANCELLED | terminal | Customer cancelled checkout before completion. |
FAILED | terminal | Payment attempt failed. Customer may retry with a new session. |
Phases and timers
Checkout UI also tracks a phase separate from lifecycle status:
- Idle — customer is choosing how to pay (QR, manual Zippy ID, or Pay with Zippy on phone). Session status is typically Created.
- Paying — customer confirmed in the Zippy mobile app. Session status moves to Awaiting Payment and a pay window timer starts.
Three time boundaries
Timer fields on the session
| Name | Type | Description |
|---|---|---|
createdAt | ISO-8601 | When the session was opened. |
expiresAt | ISO-8601 | Idle expiry while phase is IDLE. Customer must start payment before this instant. |
payExpiresAt | ISO-8601 | Pay window expiry while phase is PAYING. Set when the customer starts payment in the app. |
absoluteExpiresAt | ISO-8601 | Hard cap on total session lifetime regardless of phase. |
Checkout methods
Customers can pay via QR code scan, manual Zippy ID entry, or — on phone with SDK 1.1.x+ — Pay with Zippy to open the Zippy Pay app. The chosen method is locked when the customer commits to that path.
Checkout method locking
| Name | Type | Description |
|---|---|---|
QR | method | Customer scans the payment QR in the Zippy mobile app. Locked when QR flow starts. |
Manual | method | Customer enters a Zippy ID in checkout. Locked when payment starts. |
Pay with Zippy | phone only | Customer opens the Zippy Pay app from checkout. Default on phone in SDK 1.2.0+. |
Transitions
Known transitions
| Name | Type | Description |
|---|---|---|
Create | → CREATED | POST /api/v1/payment-sessions returns CREATED + clientToken. |
Start payment | CREATED → AWAITING_PAYMENT | Customer confirms in mobile app. Emits payment_session.payment_started. |
Success | → COMPLETED | Payment completed. Emits payment_session.completed and transaction events. |
Idle timeout | → EXPIRED | expiresAt reached while still IDLE. |
Pay timeout | → EXPIRED | payExpiresAt reached while PAYING. |
Absolute cap | → EXPIRED | absoluteExpiresAt reached regardless of phase. |
Cancel / fail | → CANCELLED | FAILED | Customer aborts or payment attempt fails. |
Terminal states
Once a session is Completed, Expired, Cancelled, or Failed, it cannot return to an active checkout state. Create a new session (with a fresh Idempotency-Key) for another payment attempt.
Webhook event catalog and payload fields are documented under Webhook events. Checkout SDK polling behavior is covered in Checkout flow and screens.