> ## Documentation Index
> Fetch the complete documentation index at: https://developers.firmly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Full Cart API Implementation

> The complete checkout flow for complex fulfillment scenarios.

## Full Cart API Guide

Build a complete checkout flow with Firmly's Full Cart API. This guide walks through adding items, setting shipping, and completing payment.

### When to Use Full Cart API

The Full Cart API supports complex fulfillment scenarios like split shipments and scheduled delivery. Use it when you need:

* Mix of standard shipping and scheduled delivery
* Items requiring different fulfillment types
* Addon services (warranties, protection plans)
* In-store pickup options
* Complex shipping scenarios

### Prerequisites

Before starting, ensure you have:

<CardGroup cols={3}>
  <Card title="Firmly Application ID" icon="key">
    Your Application ID from Firmly (contact support if you don't have one)
  </Card>

  <Card title="Test Merchant Domain" icon="globe">
    Work with Firmly to enable your app ID for a specific test store
  </Card>

  <Card title="API Client" icon="terminal">
    cURL, Postman, or your preferred HTTP client
  </Card>
</CardGroup>

<Note>
  **Important:** Before you can access a merchant's store, Firmly must configure your app ID to work with that specific domain. Contact our team to set up access to your test merchant.
</Note>

### Step 1: Authenticate

Get an access token for your session:

```bash theme={null}
curl -X POST https://api.firmly.work/api/v1/browser-session \
  -H "x-firmly-app-id: YOUR_APP_ID"
```

Use the `access_token` from the response as `x-firmly-authorization` in all API calls.

### Step 2: Browse Products

Discover available products from the merchant:

```bash theme={null}
# List products
curl -X GET "https://api.firmly.work/api/v1/domains-products/staging.luma.gift?size=100" \
  -H "x-firmly-authorization: YOUR_TOKEN"

# Get product details
curl -X GET "https://api.firmly.work/api/v1/domains-products/staging.luma.gift/radiant-tee" \
  -H "x-firmly-authorization: YOUR_TOKEN"
```

### Step 3: Add to Cart

Add a product variant to the cart:

```bash theme={null}
curl -X POST https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/line-items \
  -H "x-firmly-authorization: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "add_to_cart_ref": {
      "variant_id": "WS12-XS-Orange"
    },
    "quantity": 1
  }'
```

### Step 4: Set Shipping Address

Add shipping information and get available shipping methods:

```bash theme={null}
curl -X POST https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/shipping-info \
  -H "x-firmly-authorization: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@staging.luma.gift",
    "phone": "555-123-4567",
    "address1": "123 Main St",
    "city": "New York",
    "state_or_province": "NY",
    "postal_code": "10001",
    "country": "US"
  }'
```

### Step 5: Select Shipping Method

Choose a shipping method for each shipment:

```bash theme={null}
curl -X POST https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/shipment/methods \
  -H "x-firmly-authorization: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "shipment_id": "SHIPMENT-ID-FROM-CART",
    "shipping_method_id": "standard"
  }'
```

### Step 6: Complete the Order

Get the public key and complete the order with encrypted payment:

```bash theme={null}
# Get public key for encryption
curl -X GET https://cc.firmly.work/api/v1/payment/key \
  -H "x-firmly-authorization: YOUR_TOKEN"

# Complete order with encrypted card data
curl -X POST https://cc.firmly.work/api/v2/payment/domains/staging.luma.gift/complete-order \
  -H "x-firmly-authorization: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "encrypted_card": "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoidjEifQ...",
    "billing_info": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john.doe@staging.luma.gift",
      "address1": "123 Main St",
      "city": "New York",
      "state_or_province": "NY",
      "postal_code": "10001",
      "country": "US"
    }
  }'
```

### Complete Example

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Full checkout flow
  async function checkout(domain, productVariantId) {
    // 1. Authenticate
    const authResponse = await fetch('https://api.firmly.work/api/v1/browser-session', {
      method: 'POST',
      headers: { 'x-firmly-app-id': 'YOUR_APP_ID' }
    });
    const { access_token } = await authResponse.json();

    const headers = {
      'x-firmly-authorization': access_token,
      'Content-Type': 'application/json'
    };

    // 2. Add to cart
    const cartResponse = await fetch(
      `https://api.firmly.work/api/v2/domains/${domain}/cart/line-items`,
      {
        method: 'POST',
        headers,
        body: JSON.stringify({
          add_to_cart_ref: { variant_id: productVariantId },
          quantity: 1
        })
      }
    );
    const cart = await cartResponse.json();

    // 3. Set shipping
    const shippingResponse = await fetch(
      `https://api.firmly.work/api/v2/domains/${domain}/cart/shipping-info`,
      {
        method: 'POST',
        headers,
        body: JSON.stringify({
          first_name: 'John',
          last_name: 'Doe',
          email: 'john.doe@staging.luma.gift',
          phone: '555-123-4567',
          address1: '123 Main St',
          city: 'New York',
          state_or_province: 'NY',
          postal_code: '10001',
          country: 'US'
        })
      }
    );
    const cartWithShipping = await shippingResponse.json();

    // 4. Select shipping method
    const shipment = cartWithShipping.shipments[0];
    const shippingMethod = shipment.shipping_method_options[0];
    
    await fetch(
      `https://api.firmly.work/api/v2/domains/${domain}/cart/shipment/methods`,
      {
        method: 'POST',
        headers,
        body: JSON.stringify({
          shipment_id: shipment.shipment_id,
          shipping_method_id: shippingMethod.id
        })
      }
    );

    // 5. Get public key and encrypt card
    const keyResponse = await fetch(
      'https://cc.firmly.work/api/v1/payment/key',
      { headers }
    );
    const { key, kid } = await keyResponse.json();
    
    // Encrypt card data (see Complete Order API docs for encryption details)
    const encryptedCard = await encryptCardData(
      { number: '4242424242424242', cvv: '123', exp_month: '12', exp_year: '2025' },
      key,
      kid
    );

    // 6. Complete order
    const orderResponse = await fetch(
      `https://cc.firmly.work/api/v2/payment/domains/${domain}/complete-order`,
      {
        method: 'POST',
        headers,
        body: JSON.stringify({
          encrypted_card: encryptedCard,
          billing_info: {
            first_name: 'John',
            last_name: 'Doe',
            email: 'john.doe@staging.luma.gift',
            address1: '123 Main St',
            city: 'New York',
            state_or_province: 'NY',
            postal_code: '10001',
            country: 'US'
          }
        })
      }
    );

    const order = await orderResponse.json();
    return order;
  }
  ```

  ```python Python theme={null}
  import requests
  import json

  def checkout(domain, product_variant_id):
      # 1. Authenticate
      auth_response = requests.post(
          'https://api.firmly.work/api/v1/browser-session',
          headers={'x-firmly-app-id': 'YOUR_APP_ID'}
      )
      access_token = auth_response.json()['access_token']
      
      headers = {
          'x-firmly-authorization': access_token,
          'Content-Type': 'application/json'
      }
      
      # 2. Add to cart
      cart_response = requests.post(
          f'https://api.firmly.work/api/v2/domains/{domain}/cart/line-items',
          headers=headers,
          json={
              'add_to_cart_ref': {'variant_id': product_variant_id},
              'quantity': 1
          }
      )
      cart = cart_response.json()
      
      # 3. Set shipping
      shipping_response = requests.post(
          f'https://api.firmly.work/api/v2/domains/{domain}/cart/shipping-info',
          headers=headers,
          json={
              'first_name': 'John',
              'last_name': 'Doe',
              'email': 'john.doe@staging.luma.gift',
              'phone': '555-123-4567',
              'address1': '123 Main St',
              'city': 'New York',
              'state_or_province': 'NY',
              'postal_code': '10001',
              'country': 'US'
          }
      )
      cart_with_shipping = shipping_response.json()
      
      # 4. Select shipping method
      shipment = cart_with_shipping['shipments'][0]
      shipping_method = shipment['shipping_method_options'][0]
      
      requests.post(
          f'https://api.firmly.work/api/v2/domains/{domain}/cart/shipment/methods',
          headers=headers,
          json={
              'shipment_id': shipment['shipment_id'],
              'shipping_method_id': shipping_method['id']
          }
      )
      
      # 5. Get public key
      key_response = requests.get(
          'https://api.firmly.work/api/v1/payment/key',
          headers=headers
      )
      public_key = key_response.json()
      
      # 6. Encrypt card and complete order
      # Note: Card encryption implementation depends on your crypto library
      encrypted_card = encrypt_card_data(
          {'number': '4242424242424242', 'cvv': '123', 'exp_month': '12', 'exp_year': '2025'},
          public_key['key'],
          public_key['kid']
      )
      
      order_response = requests.post(
          f'https://api.firmly.work/api/v2/payment/domains/{domain}/complete-order',
          headers=headers,
          json={
              'encrypted_card': encrypted_card,
              'billing_info': {
                  'first_name': 'John',
                  'last_name': 'Doe',
                  'email': 'john.doe@staging.luma.gift',
                  'address1': '123 Main St',
                  'city': 'New York',
                  'state_or_province': 'NY',
                  'postal_code': '10001',
                  'country': 'US'
              }
          }
      )
      
      return order_response.json()
  ```
</CodeGroup>

### Key Differences from Simple Cart API

| Feature        | Simple Cart API    | Full Cart API          |
| -------------- | ------------------ | ---------------------- |
| Cart Structure | Flat               | Shipment-based         |
| Shipping       | One method for all | Per-shipment selection |
| Fulfillment    | Standard only      | Multiple types         |
| Addons         | Not supported      | Full support           |

### Error Handling

Common errors and their meanings:

* `ErrorCartNotFound` - Cart session expired
* `ErrorProductNotFound` - Invalid variant ID
* `ErrorNotEnoughStock` - Item out of stock
* `ErrorCountryNotSupported` - Shipping country not available
* `CreditCardDeclined` - Payment failed

### Next Steps

* Review [Error Codes](/resources/error-codes) for comprehensive error handling
* Explore [Addon Management](/api-reference/addon-management/overview) for warranties and services
* Check [Session Management](/api-reference/session/overview) for managing multiple carts
