Skip to main content

Ring Up Sale (Checkout)

POST 

/api/pos/checkout

Ring up a sale: cart lines + tender(s) become a paid, fully-fulfilled sales order plus a POS transaction.

Not yet available to API tokens

This endpoint currently requires session authentication; Personal Access Token scope support is in progress.

Authentication: Requires Bearer token. Permission: pos.operate.

Request body fields:

  • pos_register_session_id (integer, required) — the open session to ring against (must exist in pos_register_sessions).
  • tender_type (enum, required) — one of cash, card, store_credit, split.
  • amount_tendered (numeric, required, min 0) — amount the customer handed over (for a single tender; may exceed the total for cash, yielding change).
  • customer_id (integer, nullable) — attached customer; REQUIRED when tender_type is store_credit (store credit debits the customer's wallet).
  • payment_source_id (string, nullable, max 255) — tokenized card source (Web Payments SDK nonce / Terminal ref); REQUIRED when tender_type is card.
  • tax_rate_id (integer, nullable) — optional tax rate applied to every line (must exist in tax_rates).
  • apply_customer_pricing_tier (boolean, nullable) — opt-in: re-price each line from the customer's assigned pricing tier instead of the register-submitted unit_price. Defaults to false.
  • idempotency_key (string, nullable, max 255) — client-supplied stable token; a retried checkout re-uses the same processor idempotency key so a timed-out sale never double-charges.
  • tenders (array, nullable) — optional split tender; when present, overrides the single tender_type/amount_tendered and each entry is settled independently.
    • tenders.*.type (enum, required with tenders) — cash, card, store_credit, or split.
    • tenders.*.amount (numeric, required with tenders, min 0) — amount for this tender.
    • tenders.*.payment_source_id (string, nullable, max 255) — tokenized card source for a card tender.
  • lines (array, required, min 1) — the cart.
    • lines.*.product_id (integer, required) — must exist in products.
    • lines.*.quantity (numeric, required, > 0).
    • lines.*.unit_price (numeric, required, min 0).

For a simple single-tender sale, omit tenders, set tender_type to cash/card/store_credit, and set amount_tendered.

Returns 201 with the created POS transaction.

Gift card tender: set tender_type to gift_card with a top-level gift_card_code, or include a split tender {"type":"gift_card","amount":..,"gift_card_code":".."}. One gift card per sale; the card is validated and debited atomically inside the sale (rolls back on a concurrent drain). Store-credit and gift-card tenders settle exactly (no change).

On-account tender: set tender_type to on_account (or add a split tender {"type":"on_account","amount":..}) to charge the sale to the attached customer's house account. Requires a customer with a house account enabled and enough credit-limit headroom; the sale is recorded as PAID (settled on account) and the customer's house-account balance increases.

Selling gift cards (gift_cards_to_sell): Each entry SELLS a new gift card to the customer. It is added to the order as a non-product line posted to the Gift Card Liability nominal (Dr Cash / Cr Liability — never revenue, never taxed) and the card is activated for the paid amount on checkout. amount is required; code auto-generates when omitted. Requires the Gift Card Liability nominal to be configured (422 otherwise). lines is OPTIONAL when the sale is purely gift-card sales.

Request

Responses

Created

Response Headers
    Content-Type