# Create a Session When a customer is ready to pay in-store, your backend creates a session with the cart details and the `device_id` of the target terminal. Kustom dispatches it to the device immediately via push notification — no polling needed on your end. ## The payment session flow The diagram below shows the full lifecycle. Only the first step, creating the session, is something your backend does. Everything after the push notification happens inside the Kustom POS app; you can observe progress through the callbacks. | Actor | Role | | --- | --- | | **Merchant System** | The merchant's backend or e-commerce platform that creates payment sessions when a customer is ready to pay in-store. Webhooks to receive lifecycle events and an `orderId` to correlate the session with its own order record are configured in the Kustom Portal. | | **Shopper** | Anyone shopping at the merchant store. | | **Store Clerk** | Merchant employee using the Kustom POS app to collect in-person payments. | | **Kustom POS** | Kustom POS app for iOS or Android running on any certified device. | | **Session API** | Kustom session API, used to create sale sessions that handle the payment collection and order creation workflow. | ```mermaid sequenceDiagram actor Shopper actor Store Clerk participant Kustom POS participant Session API participant Merchant System critical Public — authenticated with x-merchant-id Merchant System->>+Session API: POST /ipp/v1/sessions Note over Merchant System,Session API: Session payload Session API->>-Merchant System: 200 if session created successfully Session API-->>Merchant System: callback: ipp.session.created (async) end critical Kustom POS gets notified about new session Session API->>Kustom POS: Push notification { sessionId } end critical Kustom POS payment flow Kustom POS->>+Session API: Get session details Store Clerk->>Kustom POS: Selects payment method (ex: tap-to-pay) Kustom POS->>+Session API: Attaches payment to session Session API-->>Merchant System: callback: ipp.session.activated Session API->>-Kustom POS: Kustom POS->>Store Clerk: Present tap-to-pay screen Store Clerk->>Shopper: Present tap-to-pay alt Payment succeeds Shopper->>Kustom POS: Tap card Kustom POS->>+Session API: Finalize payment Session API-->>Merchant System: callback: ipp.session.finalized Session API->>-Kustom POS: Kustom POS->>Store Clerk: Render receipt / QR code else Payment fails — clerk retries Shopper->>Kustom POS: Tap card (declined) Kustom POS->>+Session API: Finalize payment Session API->>-Kustom POS: Return payment failed status Kustom POS->>Store Clerk: Show payment failed else Clerk cancels Store Clerk->>Kustom POS: Cancel session Kustom POS->>+Session API: Cancel session Session API-->>Merchant System: callback: ipp.session.cancelled Session API->>-Kustom POS: end end ``` #### Create a session All amounts are in **minor units**. `19900` means `199.00` in the given currency. Lifecycle callbacks are delivered to the webhook endpoint configured in the Kustom Portal — see [Receive Callbacks](/contents/checkout/in-person-payments/callbacks). If your merchant account has multiple locations, pass `location_id` as a query parameter: `POST /ipp/v1/sessions?location_id=`. Store the `session_id`. The `ipp.session.created` callback is delivered **asynchronously** — the create response is returned first, and the callback fires shortly after. In the edge case where the callback arrives before your system has finished processing the create response, use `order_id` to correlate. ## Session lifecycle | State | Description | Terminal? | | --- | --- | --- | | `created` | Session dispatched, push notification sent to device. | No | | `activated` | Clerk selected payment method, tap-to-pay in progress. | No | | `completed` | Payment collected. Order created in Kustom Order Management. | ✅ Yes | | `cancelled` | Cancelled by the clerk or by your backend. | ✅ Yes | | `expired` | Session TTL elapsed without completion. | ✅ Yes | ## Fetch session status Poll this endpoint if you need the current state without waiting for a callback: #### Fetch session details ## Cancel a session You can cancel a session from your backend as long as it has not reached a final state: #### Cancel session Cancellation is final — no further payment collection is possible on a cancelled session.