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.
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 inpos_register_sessions).tender_type(enum, required) — one ofcash,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 whentender_typeisstore_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 whentender_typeiscard.tax_rate_id(integer, nullable) — optional tax rate applied to every line (must exist intax_rates).apply_customer_pricing_tier(boolean, nullable) — opt-in: re-price each line from the customer's assigned pricing tier instead of the register-submittedunit_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 singletender_type/amount_tenderedand each entry is settled independently.tenders.*.type(enum, required withtenders) —cash,card,store_credit, orsplit.tenders.*.amount(numeric, required withtenders, 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 inproducts.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
- 201
- 401
- 403
- 422
- 429
Created
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Unprocessable Entity
Response Headers
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.