QUANTM7 Docs
Headless APIAPI Reference

Cart & Checkout

Create carts, manage items, and process payments through the QUANTM7 API.

Cart and checkout endpoints require a secret key (q7_sk_). These operations must run on your server, never in client-side code.

Create a cart

Creates a new empty cart.

POST /v1/cart

Auth: Secret key required

Request body

FieldTypeRequiredDescription
currencystringNoThree-letter ISO 4217 currency code (default: GBP)
{
  "currency": "GBP"
}

Response

{
  "data": {
    "id": 5,
    "public_id": "cart_01J8ABC...",
    "currency": "GBP",
    "status": "active",
    "created_at": "2026-08-01T10:00:00.000Z"
  }
}

Errors

StatusCodeMessage
400bad_requestcurrency must be a 3-letter ISO code

Get a cart

Returns a cart with all its items, quantities, and totals.

GET /v1/cart/{publicId}

Auth: Secret key required

Path parameters

ParameterTypeDescription
publicIdstringCart public ID

Response

{
  "data": {
    "id": 5,
    "public_id": "cart_01J8ABC...",
    "currency": "GBP",
    "status": "active",
    "discount_code": null,
    "notes": null,
    "created_at": "2026-08-01T10:00:00.000Z",
    "updated_at": "2026-08-01T10:05:00.000Z",
    "items": [
      {
        "id": 1,
        "product_id": 42,
        "variant_id": 101,
        "quantity": 2,
        "title": "Classic Tee",
        "variant_title": "Small / Black",
        "sku": "CT-SM-BLK",
        "price": 29.99,
        "compare_at_price": 39.99,
        "image_url": "https://cdn.quantm7.com/store/products/abc123.webp",
        "requires_shipping": true,
        "weight": 0.2,
        "weight_unit": "kg"
      }
    ],
    "item_count": 2,
    "subtotal": 59.98
  }
}

Cart fields

FieldTypeDescription
idintegerInternal cart ID
public_idstringPublic cart identifier (use this in URLs)
currencystringCart currency (ISO 4217)
statusstringCart status (active, converted)
discount_codestring or nullApplied discount code
notesstring or nullOrder notes from the customer
itemsarrayCart line items
item_countintegerTotal quantity across all items
subtotalnumberSum of (price x quantity) for all items

Cart item fields

FieldTypeDescription
idintegerLine item ID
product_idintegerProduct ID
variant_idintegerVariant ID
quantityintegerQuantity
titlestringProduct title
variant_titlestringVariant title
skustring or nullSKU
pricenumberUnit price
compare_at_pricenumber or nullOriginal price (for showing savings)
image_urlstring or nullProduct image
requires_shippingboolean or nullWhether the item needs shipping
weightnumber or nullItem weight (snapshot from variant)
weight_unitstring or nullWeight unit (g, kg, lb, oz)

Errors

StatusCodeMessage
404not_foundCart not found

Add item to cart

Adds a product variant to the cart. If the variant is already in the cart, the quantity is increased.

POST /v1/cart/{publicId}/items

Auth: Secret key required

Request body

FieldTypeRequiredDescription
variant_idintegerYesThe variant to add
quantityintegerNoQuantity to add (default: 1, max: 999)
{
  "variant_id": 101,
  "quantity": 2
}

Response

Returns the full updated cart (same shape as GET /v1/cart/{publicId}).

Errors

StatusCodeMessage
400bad_requestvariant_id is required
400bad_requestquantity must be between 1 and 999
400bad_requestVariant not found
400bad_requestProduct is not available
400bad_requestInsufficient stock

Update item quantity

Changes the quantity of a cart item. Set quantity to 0 to remove the item.

PUT /v1/cart/{publicId}/items/{itemId}

Auth: Secret key required

Path parameters

ParameterTypeDescription
publicIdstringCart public ID
itemIdstringCart item ID

Request body

FieldTypeRequiredDescription
quantityintegerYesNew quantity (0 removes the item, max: 999)
{
  "quantity": 3
}

Response

Returns the full updated cart.

Errors

StatusCodeMessage
400bad_requestquantity must be between 0 and 999
400bad_requestInsufficient stock

Remove item from cart

Removes an item from the cart entirely.

DELETE /v1/cart/{publicId}/items/{itemId}

Auth: Secret key required

Path parameters

ParameterTypeDescription
publicIdstringCart public ID
itemIdstringCart item ID

Response

Returns the full updated cart.


Validate cart

Checks that all cart items are still available, in stock, and at the correct price. Call this before checkout to catch issues early.

POST /v1/cart/{publicId}/validate

Auth: Secret key required

Path parameters

ParameterTypeDescription
publicIdstringCart public ID

Response

{
  "data": {
    "valid": true,
    "issues": []
  }
}

If there are problems, valid is false and issues lists each one:

{
  "data": {
    "valid": false,
    "issues": [
      {
        "type": "insufficient_stock",
        "item_id": 1,
        "title": "Classic Tee",
        "detail": "Only 1 available"
      },
      {
        "type": "price_changed",
        "item_id": 2,
        "title": "Leather Belt",
        "detail": "Price changed from 45 to 49.99"
      }
    ]
  }
}

Issue types

TypeDescription
cart_not_foundCart does not exist or is not active
cart_emptyCart has no items
variant_removedA variant has been deleted from the store
product_unavailableA product is no longer active
insufficient_stockNot enough inventory for the requested quantity
price_changedThe variant price has changed since it was added to the cart

Create checkout

Creates a Stripe PaymentIntent for the cart. Returns a client_secret that you pass to Stripe's Payment Element on your frontend.

POST /v1/checkout

Auth: Secret key required

Request body

FieldTypeRequiredDescription
cart_idstringYesCart public ID
emailstringYesCustomer email address
shippingobjectYesShipping address

Shipping address fields

FieldTypeRequiredDescription
namestringYesRecipient name
address1stringYesStreet address line 1
address2stringNoStreet address line 2
citystringYesCity
provincestringNoState, province, or region
zipstringYesPostal or ZIP code
country_codestringYesTwo-letter country code (ISO 3166-1 alpha-2)
phonestringNoPhone number
{
  "cart_id": "cart_01J8ABC...",
  "email": "customer@example.com",
  "shipping": {
    "name": "Jane Smith",
    "address1": "123 Main Street",
    "address2": "Flat 4",
    "city": "London",
    "province": "Greater London",
    "zip": "SW1A 1AA",
    "country_code": "GB",
    "phone": "+447700900000"
  }
}

Response

{
  "data": {
    "client_secret": "pi_3ABC...secret_XYZ",
    "publishable_key": "pk_live_...",
    "connected_account_id": "acct_...",
    "subtotal": 59.98,
    "shipping": 0,
    "tax": 0,
    "total": 59.98
  }
}

Response fields

FieldTypeDescription
client_secretstringStripe PaymentIntent client secret
publishable_keystringStripe publishable key for the connected account
connected_account_idstringStripe Connect account ID
subtotalnumberSum of item prices
shippingnumberShipping cost
taxnumberTax amount
totalnumberTotal charge amount

Using the client secret

Pass the client_secret to Stripe's Payment Element on your frontend:

import { loadStripe } from '@stripe/stripe-js'

// Use the publishable_key and connected_account_id from the checkout response
const stripe = await loadStripe(data.publishable_key, {
  stripeAccount: data.connected_account_id
})

const elements = stripe.elements({
  clientSecret: data.client_secret
})

const paymentElement = elements.create('payment')
paymentElement.mount('#payment-element')

// When the customer submits the form
const { error } = await stripe.confirmPayment({
  elements,
  confirmParams: {
    return_url: 'https://mystore.com/order/confirmation'
  }
})

Errors

StatusCodeMessage
400bad_requestcart_id is required
400bad_requestemail is required
400bad_requestInvalid email format
400bad_requestshipping is required
400bad_requestname is required in shipping address
400bad_requestaddress1 is required in shipping address
400bad_requestcity is required in shipping address
400bad_requestzip is required in shipping address
400bad_requestcountry_code is required in shipping address
400bad_requestCart not found or already converted
400bad_requestCart is empty
400bad_requestStore has not enabled payments
400bad_requestStore has no connected Stripe account
400bad_requestStore payment account is not yet active
400bad_requestInsufficient stock
400bad_requestOrder total must be at least 0.50

Payment flow overview

1. Customer adds items to cart    →  POST /v1/cart/{id}/items
2. Customer enters address        →  Your frontend form
3. Your server creates checkout   →  POST /v1/checkout
4. Customer enters payment        →  Stripe Payment Element (client-side)
5. Stripe processes payment       →  Stripe handles this
6. Stripe webhook confirms order  →  QUANTM7 handles this automatically
7. Customer sees confirmation     →  Your return_url page

You do not need to handle webhooks. QUANTM7 receives the Stripe webhook, confirms the order, decrements inventory, and creates the order record.

On this page