---
title: Cart, Checkout & Orders
description: Manage carts, line items, coupons, checkout flow, and completed orders with the Spree SDK
---

The Store API is split into two resource groups:

- **Carts** — managing shopping carts, items, coupon codes, checkout flow (addresses, delivery, payments, completion)
- **Orders** — retrieving completed orders

All cart and checkout endpoints require a `cartId` as the first argument.

## Carts

### Create & Retrieve

```typescript
// Create a new cart
const cart = await client.carts.create();

// Get a specific cart
const cart = await client.carts.get(cartId, { spreeToken: 'xxx' });

// List carts
const carts = await client.carts.list();

// Delete a cart
await client.carts.delete(cartId, { spreeToken: cart.token });

// Associate guest cart with authenticated user
// (after user logs in, merge their guest cart with their account)
await client.carts.associate(cartId, {
  token: jwtToken,         // User's JWT token
  spreeToken: cart.token,  // Guest cart token
});
```

### Items

```typescript
const options = { spreeToken: cart.token };

// Add item
await client.carts.items.create(cartId, {
  variant_id: 'var_123',
  quantity: 2,
}, options);

// Update item quantity
await client.carts.items.update(cartId, lineItemId, {
  quantity: 3,
}, options);

// Remove item
await client.carts.items.delete(cartId, lineItemId, options);
```

### Discount Codes

```typescript
const options = { spreeToken: cart.token };

// Apply a discount code
await client.carts.discountCodes.apply(cartId, 'SAVE20', options);

// Remove a discount code
await client.carts.discountCodes.remove(cartId, 'SAVE20', options);
```

### Gift Cards

```typescript
// Apply a gift card (reduces amount_due, not total)
const cart = await client.carts.giftCards.apply(cartId, 'GC-ABCD-1234', options);

// Remove a gift card (ID from cart.gift_card.id)
await client.carts.giftCards.remove(cartId, 'gc_abc123', options);
```

### Fees and Duties

A cart may carry charges that are neither a product price nor tax: gift wrapping, a handling charge, a cash-on-delivery surcharge, or an import duty on a cross-border order. Each is a [fee](../../core-concepts/fees.md) on the cart, and the storefront should show every one of them before the customer pays.

```typescript
const cart = await client.carts.get(cartId, options);

cart.fees.forEach((fee) => {
  fee.label;          // "Import duty"
  fee.kind;           // "duty"
  fee.display_amount; // "$12.00"
  fee.line_item_id;   // set when the fee is for one item, otherwise null
});

cart.display_fee_total; // "$17.00"
```

`kind` is one of `surcharge`, `handling`, `gift_wrap`, `cod`, `payment` or `duty`. Fees are already part of `total`, so list them as their own lines between the subtotal and the total; never add them on top. A `duty` fee is a customs charge and is not taxed, which is why it is worth showing under its own label rather than folding it into a generic "fees" line.

Fees are written by the merchant or by an integration, never by the customer; there is no Store API endpoint to create one.

## Checkout

### Update Cart

```typescript
await client.carts.update(cartId, {
  email: 'customer@example.com',
  shipping_address: {
    first_name: 'John',
    last_name: 'Doe',
    address1: '123 Main St',
    city: 'New York',
    postal_code: '10001',
    phone: '+1 555 123 4567',
    country_iso: 'US',
    state_abbr: 'NY',
  },
  billing_address_id: 'addr_xxx', // Or use existing address by ID
}, { spreeToken: cart.token });
```

### Complete Checkout

```typescript
await client.carts.complete(cartId, { spreeToken: cart.token });
```

### Fulfillments

Fulfillments are included in the cart response — there is no separate list endpoint.

```typescript
const options = { spreeToken: cart.token };

// Access fulfillments from the cart response
const cart = await client.carts.get(cartId, options);
const fulfillments = cart.fulfillments;

// Select a delivery rate
await client.carts.fulfillments.update(cartId, fulfillmentId, {
  selected_delivery_rate_id: 'rate_xxx',
}, options);
```

### Store Credits

```typescript
const options = { spreeToken: cart.token };

// Apply store credit (applies maximum available by default)
await client.carts.storeCredits.apply(cartId, undefined, options);

// Apply specific amount of store credit
await client.carts.storeCredits.apply(cartId, 25.00, options);

// Remove store credit from order
await client.carts.storeCredits.remove(cartId, options);
```

### Totals

The cart and order responses break the amount the customer pays into these totals. Each has a raw string value and a `display_` twin formatted in the cart's currency.

- `item_total` — the products, before anything else
- `delivery_total` — the selected delivery rates
- `discount_total` — promotions and discount codes, as a negative amount
- `fee_total` — every [fee](#fees-and-duties) on the cart, duties included
- `tax_total` — tax on items, delivery and taxable fees
- `total` — what the order costs: items, delivery, fees and tax, less discounts
- `store_credit_total` / `gift_card_total` — store credit or gift card value applied against the total
- `amount_due` — what is left to pay after store credit and gift cards
- `covered_by_store_credit` — boolean, whether the order is fully covered by store credit
- `gift_card` — associated gift card (if applicable)

## Orders

### Get a Completed Order

```typescript
const order = await client.orders.get('R123456789', {
  expand: ['items', 'fulfillments'],
}, { spreeToken: cart.token });
```

### List Orders (Authenticated Customer)

```typescript
const orders = await client.customer.orders.list({}, { token });
```
