FleetbaseFleetbase

Checkout

Checkout endpoints turn a cart into a payable order flow. Use them to initialize gateway-specific payment data, check checkout status, capture payment callbacks, and create orders from completed checkouts.

The Checkout object

A checkout represents a prepared storefront checkout session for a cart, customer, gateway, and delivery or pickup option. The fields returned depend on the gateway. Realtime updates are published on the channel `checkout.{checkout}` as `{ checkout, status, order, payment, error }`, where `status` is `pending`, `paid`, `completed` or `failed`. With socket authentication enabled, subscribe using `socket_token` (guests) or a customer socket token from `POST customers/socket-token`.
Attributes
checkoutstringoptional

Public checkout ID (chkt_…). Use it with checkouts/status and the realtime channel checkout.\{checkout\}.

tokenstringoptional

Checkout token used to capture the order and check its status.

paymentIntentstringoptional

Stripe PaymentIntent ID when using Stripe checkout.

clientSecretstringoptional

Stripe client secret when using Stripe checkout.

ephemeralKeystringoptional

Stripe ephemeral key when returned for mobile checkout.

customerIdstringoptional

Gateway customer ID.

invoiceobjectoptional

QPay invoice payload (bank app links, QR) when using QPay checkout.

socket_tokenobjectoptional

Present when realtime socket authentication is enabled: \{ token, expires_in, expires_at \}, a short-lived token allowed to subscribe to checkout.\{checkout\}. Logged-in customers can use their own socket token instead.

The Checkout object
{
  "checkout": "chkt_8Ty2nQ4",
  "token": "checkout-token",
  "paymentIntent": "pi_123",
  "clientSecret": "pi_123_secret_456",
  "ephemeralKey": "ek_test_123",
  "customerId": "cus_123",
  "socket_token": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expires_in": 900,
    "expires_at": "2026-10-12T10:15:00+00:00"
  }
}
GET/v1/checkouts/before

Before ❗

Initializes a checkout preview for a cart, customer, gateway, and delivery or pickup option. The response prepares gateway-specific client data or a checkout token before the order is captured.

Stock and booked slots are checked when the checkout is created (cash, Stripe and QPay alike, and again when Update Stripe Payment Intent creates or re-prices a checkout). For products that track inventory, each line's quantity is held at the line's store location or food truck for 15 minutes and taken when the order is captured; an abandoned checkout gives it back. A refusal deletes the checkout:

  • 422 { "errors": ["Some items in your cart are no longer available."], "code": "cart_items_unavailable", "items": [{ "id", "product_id", "name", "available" }] } when a tracked product doesn't have enough stock at the line's location. id is the cart line and available is what is left to sell there.
  • 422 { "errors": ["The time you picked for <service> was just booked. Please pick another time."], "code": "booking_slot_unavailable" } when a booked service's slot (see List Product Booking Slots) has no places left.

Promotions are priced when the checkout is created: automatic promotions and any promo codes (from promo_codes or applied to the cart) are subtracted from the amount charged, and each use is reserved for the checkout. A code that cannot be applied refuses the checkout with 400.

The response depends on the gateway: cash returns { checkout, token }, Stripe returns { paymentIntent, clientSecret, ephemeralKey, customerId, checkout, token }, and QPay returns { invoice, checkout, token }. When realtime socket authentication is enabled, every response also carries socket_token: a token scoped to the realtime channel checkout.{checkout}, which a guest uses to receive payment and order updates (see the Checkout object).

Errors: 403 when customer does not match the authenticated customer; 400 when no gateway is configured or a promo code cannot be applied; for Network carts, 422/403 when the cart is empty, has a store outside the network or offline, mixes stores without multi-store carts, has an unavailable product or location, or mixes currencies.

Query parameters
gatewaystringrequired

Code of a payment gateway configured for the store or network (for example stripe or qpay), or cash for cash on delivery. Gateway IDs are not accepted.

customerstringrequired

Customer public ID. When Customer-Token is sent, it must identify the authenticated customer, otherwise the checkout is refused with 403.

cartstringrequired

Cart public ID (cart_…). Only open carts are used: an ID of a cart that was already checked out or cleared resolves to the device's open cart. Network checkout validates member stores, online state, products, locations, currency consistency and the network multi-cart policy before payment initialization.

service_quotestringoptional

Delivery service quote public ID. Required unless pickup is true. serviceQuote is an accepted alias.

pickupbooleanoptionalDefault: false

Set to true for a pickup order. A pickup checkout needs no service quote and ignores delivery_tip.

cashbooleanoptionalDefault: false

Set to true to pay cash on delivery. Same as gateway=cash.

tipstringoptional

Store tip, as an amount in the currency's smallest unit or a percentage string such as 10%.

delivery_tipstringoptional

Driver tip, as an amount or a percentage string such as 10%. Ignored for pickup. deliveryTip is an accepted alias.

promo_codesarray of stringsoptional

Promo codes to apply, as an array or a comma separated string. promo_code, promoCode and discount_code are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with 400 and promotions.rejected[] (\{ code, reason \}) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code.

ebarimt_registration_nostringoptional

QPay only. Company registration number for the e-barimt receipt. It is saved on the customer and sent as the receipt's receiver.

GET/v1/checkouts/before
curl https://api.fleetbase.io/v1/checkouts/before?gateway=stripe&customer={{customer_id}}&cart={{cart_id}}&service_quote={{service_quote_id}}&pickup=false \
  -H "Authorization: Bearer flb_live_…"
GET/v1/checkouts/before

Before Cash Pickup Checkout

Initializes a cash (cash-on-delivery) pickup checkout. A pickup checkout with the cash gateway needs no delivery service quote, so the service_quote parameter is omitted. The response returns the checkout id and token; no gateway client data is prepared for cash.

Like every checkout, it holds stock for products that track inventory and can be refused with 422 cart_items_unavailable or booking_slot_unavailable (see Before).

Query parameters
gatewaystringrequired

Payment gateway code: cash for a cash-on-delivery checkout.

customerstringrequired

Customer public ID. Must match the authenticated customer when Customer-Token is sent.

cartstringrequired

Cart public ID (cart_…).

pickupbooleanoptional

Set true for a pickup order; a cash pickup checkout needs no service quote.

promo_codesarray of stringsoptional

Promo codes to apply, as an array or a comma separated string. promo_code, promoCode and discount_code are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with 400 and promotions.rejected[] (\{ code, reason \}) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code.

GET/v1/checkouts/before
curl https://api.fleetbase.io/v1/checkouts/before?gateway=cash&customer={{customer_id}}&cart={{cart_id}}&pickup=true \
  -H "Authorization: Bearer flb_live_…"
POST/v1/checkouts/capture

Capture checkout as order

Captures a checkout token and creates the corresponding order. Capture is idempotent: an already completed checkout returns its existing order, while a concurrent capture still in progress returns 409 so the client can retry safely.

Stripe checkouts are captured only after Fleetbase retrieves the server-linked PaymentIntent and verifies that it succeeded and matches the checkout amount, currency, customer, and live/test mode. An incomplete payment returns 402, a missing or mismatched PaymentIntent returns 422, and a temporary Stripe verification failure returns 502. Clients must confirm the PaymentIntent before calling this endpoint and must not send or trust a client-selected PaymentIntent ID during capture.

The order is built from the cart as it was when the checkout was created, so changing or clearing the cart afterwards doesn't change the order, and the cart is marked checked out. A cart with a bookable product or a scheduled line becomes a booking order (meta.is_booking, meta.booking_at). A Network checkout across several stores creates one order per store under a master order (meta.is_master_order, meta.related_orders); see GET orders/{id}/stores. The response is the order; its meta includes discount, promotions, payment_status and the booking fields.

Because a contract run cannot complete a card payment, this example captures the cash pickup checkout created by Before Cash Pickup Checkout, which needs no provider payment; the unpaid Stripe checkout's 402 refusal is asserted by Capture Stripe checkout without payment.

Body parameters
tokenstringrequired

Checkout token returned by checkout initialization.

transactionDetailsobjectoptional

Optional gateway transaction details to store with the resulting transaction and order metadata.

notesstringoptional

Optional notes stored on the created order.

POST/v1/checkouts/capture
curl -X POST https://api.fleetbase.io/v1/checkouts/capture \
  -H "Authorization: Bearer flb_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "token": "{{cash_checkout_token}}"
}'
POST/v1/checkouts/capture

Capture Stripe checkout without payment

Documents the refusal contract for capturing a Stripe checkout whose PaymentIntent has not succeeded: the API answers 402 with "Stripe payment has not been completed." and creates no order. Client-supplied transaction details can never substitute for the provider's verified payment state.

Body parameters
tokenstringrequired

Checkout token of a Stripe checkout whose PaymentIntent has not succeeded.

POST/v1/checkouts/capture
curl -X POST https://api.fleetbase.io/v1/checkouts/capture \
  -H "Authorization: Bearer flb_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "token": "{{checkout_token}}"
}'
POST/v1/checkouts/capture-qpay

Capture QPay Callback

The callback QPay calls when an invoice is paid; it is public and needs no storefront key. Fleetbase looks up the checkout, asks QPay for the invoice's payments, and creates the order only when a payment is PAID for at least the invoiced amount (NEW, FAILED, PARTIAL and REFUNDED create nothing). The payment is recorded on the checkout and published to the realtime channel checkout.{checkout}, first as paid, then as completed with the order.

Response: without respond, always HTTP 200 with the plain-text body SUCCESS, as QPay requires, even when something failed. With respond=1: JSON { checkout, payment, error }, where error is CHECKOUT_ID_MISSING, CHECKOUT_SESSION_NOT_FOUND, GATEWAY_NOT_CONFIGURED, MISSING_INVOICE_ID or PAYMENT_NOT_PAID.

In sandbox, test=success only publishes test data (no payment is recorded and no order is created) and test=error returns PAYMENT_NOT_PAID.

Body parameters
checkoutstringrequired

Public checkout ID being confirmed by QPay.

respondbooleanoptional

Return \{ checkout, payment, error \} as JSON instead of QPay's plain-text SUCCESS.

testenumoptional

Sandbox-only test scenario to simulate. One of success, error.

POST/v1/checkouts/capture-qpay
curl -X POST https://api.fleetbase.io/v1/checkouts/capture-qpay \
  -H "Authorization: Bearer flb_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "checkout": "{{checkout_id}}",
  "respond": true,
  "test": "success"
}'
GET/v1/checkouts/capture-qpay

Capture QPay Callback via GET

The same callback with its parameters in the query string, which is how QPay calls it; it is public and needs no storefront key. Fleetbase looks up the checkout, asks QPay for the invoice's payments, and creates the order only when a payment is PAID for at least the invoiced amount (NEW, FAILED, PARTIAL and REFUNDED create nothing). The payment is recorded on the checkout and published to the realtime channel checkout.{checkout}, first as paid, then as completed with the order.

Response: without respond, always HTTP 200 with the plain-text body SUCCESS, as QPay requires, even when something failed. With respond=1: JSON { checkout, payment, error }, where error is CHECKOUT_ID_MISSING, CHECKOUT_SESSION_NOT_FOUND, GATEWAY_NOT_CONFIGURED, MISSING_INVOICE_ID or PAYMENT_NOT_PAID.

In sandbox, test=success only publishes test data (no payment is recorded and no order is created) and test=error returns PAYMENT_NOT_PAID.

Query parameters
checkoutstringrequired

Public checkout ID (chkt_…) the invoice was created for.

respondbooleanoptional

Return \{ checkout, payment, error \} as JSON instead of QPay's plain-text SUCCESS.

testenumoptional

Sandbox only. Simulate a paid (success) or unpaid (error) callback. One of success, error.

GET/v1/checkouts/capture-qpay
curl https://api.fleetbase.io/v1/checkouts/capture-qpay?checkout={{checkout_id}}&respond=true&test=success \
  -H "Authorization: Bearer flb_live_…"
GET/v1/checkouts/status

Get Checkout Status

Returns the status of a checkout. The answer comes from the database: the payment is recorded the moment QPay's callback (or a verify check) confirms it.

Response: { status, checkout, payment, order }. status is completed once an order exists, paid for a QPay payment that is recorded but has no order yet, and pending otherwise. order is the order, or null. payment is null, or for QPay the recorded payment { payment_id, payment_status, payment_amount, payment_currency, payment_date, payment_wallet, recorded_at }. A payment counts only when QPay reports it PAID for at least the invoiced amount. If a recorded payment still has no order after 15 seconds, this call creates the order.

Errors: 400 without checkout and token, 404 when they don't match a checkout.

Query parameters
checkoutstringrequired

Public checkout ID (chkt_…).

tokenstringrequired

The checkout's token. Both values must belong to the same checkout.

verifybooleanoptionalDefault: false

QPay only. Ask QPay for the payment state when no payment is recorded yet. Limited to once every 5 seconds per checkout; calls within that window answer from the database.

GET/v1/checkouts/status
curl https://api.fleetbase.io/v1/checkouts/status?checkout={{checkout_id}}&token={{checkout_token}}&verify=false \
  -H "Authorization: Bearer flb_live_…"
POST/v1/checkouts/stripe-setup-intent

Create Stripe Setup Intent

Creates a Stripe SetupIntent for a storefront customer, for saving a payment method.

Response: { setupIntent, clientSecret, defaultPaymentMethod, customerId }. defaultPaymentMethod is null or { paymentMethodId, id, brand, last4, label, exp_month, exp_year, country, funding }. Errors: 400 when Stripe is not set up or not configured correctly.

Body parameters
customerstringrequired

Customer public ID. Must match the authenticated customer when Customer-Token is sent, otherwise 403.

POST/v1/checkouts/stripe-setup-intent
curl -X POST https://api.fleetbase.io/v1/checkouts/stripe-setup-intent \
  -H "Authorization: Bearer flb_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "customer": "{{customer_id}}"
}'
PUT/v1/checkouts/stripe-update-payment-intent

Update Stripe Payment Intent

Recalculates and updates an existing Stripe PaymentIntent for the current cart and checkout options, and returns refreshed Stripe client data (plus socket_token when socket authentication is enabled).

If a checkout is already linked to the PaymentIntent, it is updated in place: the response keeps the same checkout and token, and its promotion reservations are released and reserved again. A new checkout is created only when none is linked. Cash on delivery is not supported here.

Errors: 422 when the PaymentIntent belongs to another customer's checkout, 400 when the PaymentIntent can no longer be updated (its status is not requires_payment_method, requires_confirmation, requires_action or processing) or a promo code cannot be applied.

Body parameters
customerstringrequired

Customer public ID. When Customer-Token is present it must identify the authenticated customer.

cartstringrequired

Cart public ID or unique identifier. Only open carts are used.

payment_intent_idstringrequired

Stripe PaymentIntent to update. paymentIntent and paymentIntentId are accepted aliases.

service_quotestringoptional

Delivery service quote public ID. Required unless pickup is true. serviceQuote is an accepted alias.

pickupbooleanoptional

Whether the order is a pickup order.

tipstringoptional

Tip, as an amount or a percentage string such as 10%.

delivery_tipstringoptional

Delivery tip, as an amount or a percentage string. deliveryTip is an accepted alias.

promo_codesarray of stringsoptional

Promo codes to apply, as an array or a comma separated string. promo_code, promoCode and discount_code are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with 400 and promotions.rejected[] (\{ code, reason \}) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code.

PUT/v1/checkouts/stripe-update-payment-intent
curl -X PUT https://api.fleetbase.io/v1/checkouts/stripe-update-payment-intent \
  -H "Authorization: Bearer flb_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "customer": "{{customer_id}}",
  "cart": "{{cart_id}}",
  "service_quote": "{{service_quote_id}}",
  "payment_intent_id": "{{payment_intent_id}}",
  "pickup": false,
  "tip": 0,
  "delivery_tip": 0
}'
Checkout | Fleetbase