StoreKitdocs
Concepts

Carts & checkout

Guest carts, customer carts, the merge between them, and turning a cart into an order.

Cart lines and items

A cart is a list of lines. Each line targets a product variant and a quantity, plus optional modifiers (e.g. size, add-ons for restaurants):

{ variantId: "var_123", quantity: 2, modifiers: { "grp_size": ["mod_large"] } }

Once a line exists, you address it by its line id (cart.items[].id) — not the variant id — to change quantity or remove it. Adding the same variant + modifier set again merges into the existing line.

Guest carts vs. customer carts

  • A guest cart has no customerId. Anyone holding its id can read it.
  • A customer cart belongs to a logged-in shopper. Only that customer can read it; cart.me() returns it without needing the id.

When a guest logs in, their guest cart is claimed (merged) into their customer cart — automatically during auth.verifyOtp if a guest cart id is known. You can also merge explicitly with cart.claim(cartId).

The SDK manages cart ids for you (Next.js)

With the Next.js adapter, the cart id lives in an httpOnly cookie. You call storekit.cart.add(item) / setQuantity / remove with no cart id — the adapter tracks it. The framework-agnostic core client is explicit about cart ids instead. See SDK — Next.js.

Cart totals

A cart response includes computed money fields as strings (to avoid float rounding):

{
  subtotal: "1200.00",
  total: "1320.00",
  charges: { taxAmount: "120.00", taxInclusive: false, packagingCharge: "0.00",
             deliveryCharge: "0.00", deliveryMessage: null, total: "1320.00" },
  currency: "INR",
  items: [ /* lines */ ],
}

Format them for display with formatMoney().

Checkout

Checkout turns the customer's cart into an order and a payment intent. It requires a logged-in customer.

const { data, error } = await storekit.checkout.create({
  orderType: "delivery", // or "pickup" | "dine_in"
  shipping: { firstName, address, city, state, zipCode, country },
  couponCode: "WELCOME10", // optional
  notes: "Leave at the door", // optional
});
// data.redirectUrl → hand off to the payment provider

Behind the scenes the API:

  • Re-checks stock for every line (fails with INSUFFICIENT_STOCK if something sold out).
  • Validates the coupon, minimum order value, and delivery serviceability.
  • Creates the order in pending status and a payment intent.
  • Returns a redirectUrl to the payment provider.

Idempotency

checkout.create() is idempotent. The SDK generates an idempotency key for you (or pass your own). Retrying with the same key returns the same pending order instead of creating duplicates. A key bound to an already-progressed order fails with STALE_CHECKOUT (410) — start a fresh checkout.

Common checkout errors

CodeMeaning
INSUFFICIENT_STOCKA line went out of stock between cart and checkout.
MINIMUM_ORDER_NOT_METCart total is below the store's minimum.
COUPON_EXPIRED / COUPON_INVALIDThe coupon can't be applied.
STALE_CHECKOUTThe idempotency key belongs to a non-pending order.
PAYMENT_NOT_CONFIGUREDThe store hasn't set up payments.

After the customer pays and returns, you confirm the order — see Payments.

On this page