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

# Shopping Cart

> Manage customer shopping carts with real-time updates

## Overview

The Shopping Cart API provides comprehensive cart management functionality for customers. Each customer can have multiple carts (one per store) with real-time synchronization across devices.

## Add to Cart

Add a product to the customer's shopping cart for a specific store.

<ParamField path="customerId" type="Id<'customers'>" required>
  Customer ID
</ParamField>

<ParamField path="storeId" type="Id<'stores'>" required>
  Store ID
</ParamField>

<ParamField path="productId" type="Id<'products'>" required>
  Product ID to add
</ParamField>

<ParamField path="quantity" type="number" required>
  Quantity to add (must be positive)
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  await convex.mutation(api.customers.cart.addToCart, {
    customerId: "c123456789",
    storeId: "j123456789",
    productId: "p123456789",
    quantity: 2
  });
  ```

  ```javascript JavaScript theme={null}
  await convex.mutation("customers.cart.addToCart", {
    customerId: "c123456789",
    storeId: "j123456789", 
    productId: "p123456789",
    quantity: 2
  });
  ```

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

  response = requests.post(
      f"{CONVEX_URL}/api/mutation",
      json={
          "path": "customers.cart.addToCart",
          "args": {
              "customerId": "c123456789",
              "storeId": "j123456789",
              "productId": "p123456789", 
              "quantity": 2
          }
      },
      headers={"Authorization": f"Bearer {token}"}
  )
  ```
</CodeGroup>

<ResponseExample>
  ```json Response theme={null}
  null
  ```
</ResponseExample>

## Update Cart Item Quantity

Update the quantity of a specific item in the cart. Set quantity to 0 to remove the item.

<ParamField path="customerId" type="Id<'customers'>" required>
  Customer ID
</ParamField>

<ParamField path="storeId" type="Id<'stores'>" required>
  Store ID
</ParamField>

<ParamField path="productId" type="Id<'products'>" required>
  Product ID to update
</ParamField>

<ParamField path="quantity" type="number" required>
  New quantity (0 to remove item)
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  await convex.mutation(api.customers.cart.updateCartItemQuantity, {
    customerId: "c123456789",
    storeId: "j123456789",
    productId: "p123456789",
    quantity: 3
  });
  ```

  ```javascript JavaScript theme={null}
  await convex.mutation("customers.cart.updateCartItemQuantity", {
    customerId: "c123456789",
    storeId: "j123456789",
    productId: "p123456789", 
    quantity: 3
  });
  ```
</CodeGroup>

## Remove from Cart

Remove a specific item from the cart completely.

<ParamField path="customerId" type="Id<'customers'>" required>
  Customer ID
</ParamField>

<ParamField path="storeId" type="Id<'stores'>" required>
  Store ID
</ParamField>

<ParamField path="productId" type="Id<'products'>" required>
  Product ID to remove
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  await convex.mutation(api.customers.cart.removeFromCart, {
    customerId: "c123456789",
    storeId: "j123456789",
    productId: "p123456789"
  });
  ```

  ```javascript JavaScript theme={null}
  await convex.mutation("customers.cart.removeFromCart", {
    customerId: "c123456789",
    storeId: "j123456789",
    productId: "p123456789"
  });
  ```
</CodeGroup>

## Clear Cart

Clear all items from the cart for a specific store.

<ParamField path="customerId" type="Id<'customers'>" required>
  Customer ID
</ParamField>

<ParamField path="storeId" type="Id<'stores'>" required>
  Store ID
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  await convex.mutation(api.customers.cart.clearCart, {
    customerId: "c123456789",
    storeId: "j123456789"
  });
  ```

  ```javascript JavaScript theme={null}
  await convex.mutation("customers.cart.clearCart", {
    customerId: "c123456789",
    storeId: "j123456789"
  });
  ```
</CodeGroup>

## Get Cart

Retrieve the cart for a specific customer and store with current product information and pricing.

<ParamField path="customerId" type="Id<'customers'>" required>
  Customer ID
</ParamField>

<ParamField path="storeId" type="Id<'stores'>" required>
  Store ID
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  const cart = await convex.query(api.customers.cart.getCart, {
    customerId: "c123456789",
    storeId: "j123456789"
  });
  ```

  ```javascript JavaScript theme={null}
  const cart = await convex.query("customers.cart.getCart", {
    customerId: "c123456789",
    storeId: "j123456789"
  });
  ```
</CodeGroup>

<ResponseExample>
  ```json Response theme={null}
  {
    "_id": "cart123456789",
    "customerId": "c123456789",
    "storeId": "j123456789",
    "items": [
      {
        "productId": "p123456789",
        "productName": "Pizza Margherita",
        "productPrice": 15.99,
        "quantity": 2,
        "subtotal": 31.98,
        "productImage": "https://storage.convex.dev/...",
        "isAvailable": true,
        "stockAvailable": 100
      },
      {
        "productId": "p987654321",
        "productName": "Garlic Bread",
        "productPrice": 6.99,
        "quantity": 1,
        "subtotal": 6.99,
        "productImage": "https://storage.convex.dev/...",
        "isAvailable": true,
        "stockAvailable": 50
      }
    ],
    "itemsCount": 3,
    "subtotal": 38.97,
    "store": {
      "id": "j123456789",
      "name": "Mario's Pizza",
      "logo": "https://storage.convex.dev/...",
      "isActive": true
    },
    "_creationTime": 1640995200000,
    "lastUpdated": 1640995800000
  }
  ```
</ResponseExample>

## Get Customer Carts

Retrieve all carts for a customer across all stores.

<ParamField path="customerId" type="Id<'customers'>" required>
  Customer ID
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  const carts = await convex.query(api.customers.cart.getCustomerCarts, {
    customerId: "c123456789"
  });
  ```

  ```javascript JavaScript theme={null}
  const carts = await convex.query("customers.cart.getCustomerCarts", {
    customerId: "c123456789"
  });
  ```
</CodeGroup>

<ResponseExample>
  ```json Response theme={null}
  [
    {
      "_id": "cart123456789",
      "storeId": "j123456789",
      "storeName": "Mario's Pizza",
      "itemsCount": 3,
      "subtotal": 38.97,
      "lastUpdated": 1640995800000
    },
    {
      "_id": "cart987654321", 
      "storeId": "j987654321",
      "storeName": "Tech Store",
      "itemsCount": 1,
      "subtotal": 299.99,
      "lastUpdated": 1640995600000
    }
  ]
  ```
</ResponseExample>

## Get Cart Summary

Get a summary of all cart activity for a customer.

<ParamField path="customerId" type="Id<'customers'>" required>
  Customer ID
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  const summary = await convex.query(api.customers.cart.getCartSummary, {
    customerId: "c123456789"
  });
  ```

  ```javascript JavaScript theme={null}
  const summary = await convex.query("customers.cart.getCartSummary", {
    customerId: "c123456789"
  });
  ```
</CodeGroup>

<ResponseExample>
  ```json Response theme={null}
  {
    "totalItems": 4,
    "totalStores": 2,
    "totalAmount": 338.96
  }
  ```
</ResponseExample>

## Get Cart for Checkout

**🆕 New Function** - Get cart with checkout calculations and validation in one call.

<ParamField path="customerId" type="Id<'customers'>" required>
  Customer ID
</ParamField>

<ParamField path="storeId" type="Id<'stores'>" required>
  Store ID
</ParamField>

<ParamField path="deliveryType" type="string" required>
  Delivery method: `delivery` or `pickup`
</ParamField>

<ParamField path="deliveryFee" type="number">
  Delivery fee (defaults to 5.99 for delivery, 0 for pickup)
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  const checkoutData = await convex.query(api.customers.cart.getCartForCheckout, {
    customerId: "c123456789",
    storeId: "j123456789",
    deliveryType: "delivery",
    deliveryFee: 5.00
  });
  ```

  ```javascript JavaScript theme={null}
  const checkoutData = await convex.query("customers.cart.getCartForCheckout", {
    customerId: "c123456789",
    storeId: "j123456789",
    deliveryType: "delivery",
    deliveryFee: 5.00
  });
  ```
</CodeGroup>

<ResponseExample>
  ```json Response theme={null}
  {
    "cart": {
      "_id": "cart123456789",
      "items": [...],
      "itemsCount": 3,
      "subtotal": 38.97
    },
    "checkoutTotals": {
      "subtotal": 38.97,
      "deliveryFee": 5.00,
      "platformCommission": 2.85,
      "totalAmount": 43.97,
      "itemsCount": 3
    },
    "isValidForCheckout": true,
    "validationIssues": []
  }
  ```
</ResponseExample>

## Real-time Updates

The cart system supports real-time updates across all devices. Use the React hooks for automatic synchronization:

<CodeGroup>
  ```typescript React Hook theme={null}
  import { useQuery, useMutation } from "convex/react";
  import { api } from "./convex/_generated/api";

  function CartComponent({ customerId, storeId }) {
    // Real-time cart data
    const cart = useQuery(api.customers.cart.getCart, {
      customerId,
      storeId
    });
    
    // Mutation for adding items
    const addToCart = useMutation(api.customers.cart.addToCart);
    
    const handleAddItem = async (productId: string, quantity: number) => {
      await addToCart({
        customerId,
        storeId,
        productId,
        quantity
      });
    };
    
    if (cart === undefined) return <div>Loading cart...</div>;
    if (cart === null) return <div>Cart is empty</div>;
    
    return (
      <div>
        <h2>Cart ({cart.itemsCount} items)</h2>
        <p>Subtotal: ${cart.subtotal}</p>
        {cart.items.map(item => (
          <div key={item.productId}>
            {item.productName} x {item.quantity} = ${item.subtotal}
          </div>
        ))}
      </div>
    );
  }
  ```

  ```typescript Vue Composition API theme={null}
  import { useConvexQuery, useConvexMutation } from "@convex-vue/core";

  export default {
    setup() {
      const cart = useConvexQuery("customers.cart.getCart", {
        customerId: "c123456789",
        storeId: "j123456789"
      });
      
      const addToCart = useConvexMutation("customers.cart.addToCart");
      
      return { cart, addToCart };
    }
  };
  ```
</CodeGroup>

## Error Handling

<AccordionGroup>
  <Accordion title="Product not available">
    **Error**: Product is inactive or out of stock

    ```json theme={null}
    {
      "error": "Product is not available for purchase",
      "code": "PRODUCT_UNAVAILABLE",
      "productId": "p123456789"
    }
    ```
  </Accordion>

  <Accordion title="Insufficient stock">
    **Error**: Not enough stock for requested quantity

    ```json theme={null}
    {
      "error": "Insufficient stock available",
      "code": "INSUFFICIENT_STOCK", 
      "available": 5,
      "requested": 10
    }
    ```
  </Accordion>

  <Accordion title="Store inactive">
    **Error**: Store is not accepting orders

    ```json theme={null}
    {
      "error": "Store is currently not accepting orders",
      "code": "STORE_INACTIVE",
      "storeId": "j123456789"
    }
    ```
  </Accordion>
</AccordionGroup>

## Best Practices

<CardGroup cols={2}>
  <Card title="Real-time Sync" icon="arrows-rotate">
    Use React hooks for automatic cart synchronization across devices and tabs.
  </Card>

  <Card title="Validation" icon="shield-check">
    Always validate cart contents before checkout to handle stock changes.
  </Card>

  <Card title="Performance" icon="gauge-high">
    Use `getCartForCheckout` for checkout flows to reduce API calls.
  </Card>

  <Card title="User Experience" icon="heart">
    Show loading states and handle errors gracefully for better UX.
  </Card>
</CardGroup>

<Note>
  Cart items are automatically validated for availability and stock levels. Unavailable items are marked but not removed automatically.
</Note>

<Tip>
  Use the `getCartForCheckout` function for checkout flows as it provides cart data, validation, and totals calculation in a single optimized call.
</Tip>
