Skip to content
Last updated

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.

ActorRole
Merchant SystemThe 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.
ShopperAnyone shopping at the merchant store.
Store ClerkMerchant employee using the Kustom POS app to collect in-person payments.
Kustom POSKustom POS app for iOS or Android running on any certified device.
Session APIKustom session API, used to create sale sessions that handle the payment collection and order creation workflow.
Merchant SystemSession APIKustom POSMerchant SystemSession APIKustom POSSession payloadcritical[Public — authenticated withx-merchant-id]critical[Kustom POS gets notifiedabout new session]alt[Payment succeeds][Payment fails — clerk retries][Clerk cancels]critical[Kustom POS payment flow]ShopperStore ClerkPOST /ipp/v1/sessions200 if session created successfullycallback: ipp.session.created (async)Push notification { sessionId }Get session detailsSelects payment method (ex: tap-to-pay)Attaches payment to sessioncallback: ipp.session.activatedPresent tap-to-pay screenPresent tap-to-payTap cardFinalize paymentcallback: ipp.session.finalizedRender receipt / QR codeTap card (declined)Finalize paymentReturn payment failed statusShow payment failedCancel sessionCancel sessioncallback: ipp.session.cancelledShopperStore Clerk

Create a session

curl -i -X POST \
  'https://api.kustom.co/ipp/v1/sessions?location_id=497f6eca-6276-4993-bfeb-53cbbbba6f08' \
  -H 'Content-Type: application/json' \
  -d '{
    "device_id": "550e8400-e29b-41d4-a716-446655440000",
    "order_amount": 240000,
    "purchase_currency": "SEK",
    "purchase_started_at": "2024-01-15T10:30:00Z",
    "order_tax_amount": 48000,
    "merchant_reference1": "ORDER-12345",
    "order_items": [
      {
        "type": "physical",
        "reference": "SKU-001",
        "name": "T-Shirt",
        "quantity": 2,
        "unit_price": 100000,
        "total_amount": 200000,
        "tax_rate": 2500,
        "total_tax_amount": 40000
      },
      {
        "type": "physical",
        "reference": "SKU-002",
        "name": "Socks",
        "quantity": 1,
        "unit_price": 40000,
        "total_amount": 40000,
        "tax_rate": 2500,
        "total_tax_amount": 8000
      }
    ]
  }'
Response
application/json
{ "session_id": "660e8400-e29b-41d4-a716-446655440001", "status": "CREATED", "device_id": "550e8400-e29b-41d4-a716-446655440000", "order_amount": 240000, "purchase_currency": "SEK", "purchase_started_at": "2024-01-15T10:30:00Z", "order_tax_amount": 48000, "merchant_reference1": "ORDER-12345", "order_items": [ {}, {} ] }

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.

If your merchant account has multiple locations, pass location_id as a query parameter: POST /ipp/v1/sessions?location_id=<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

StateDescriptionTerminal?
createdSession dispatched, push notification sent to device.No
activatedClerk selected payment method, tap-to-pay in progress.No
completedPayment collected. Order created in Kustom Order Management.✅ Yes
cancelledCancelled by the clerk or by your backend.✅ Yes
expiredSession 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

curl -i -X GET \
  'https://api.kustom.co/ipp/v1/sessions/{session_id}'
Response
application/json
{ "session_id": "660e8400-e29b-41d4-a716-446655440001", "status": "ACTIVE", "device_id": "550e8400-e29b-41d4-a716-446655440000", "order_id": "770e8400-e29b-41d4-a716-446655440002", "order_amount": 240000, "purchase_currency": "SEK", "purchase_started_at": "2024-01-15T10:30:00Z", "order_tax_amount": 48000, "merchant_reference1": "ORDER-12345", "order_items": [ {} ] }

Cancel a session

You can cancel a session from your backend as long as it has not reached a final state:

Cancel session

curl -i -X PUT \
  'https://api.kustom.co/ipp/v1/sessions/{session_id}/cancel'
Response
application/json
{ "session_id": "660e8400-e29b-41d4-a716-446655440001", "status": "CANCELLED", "device_id": "550e8400-e29b-41d4-a716-446655440000", "order_amount": 240000, "purchase_currency": "SEK", "purchase_started_at": "2024-01-15T10:30:00Z", "order_tax_amount": 48000, "merchant_reference1": "ORDER-12345", "order_items": [ {} ] }

Cancellation is final — no further payment collection is possible on a cancelled session.