# Cart Actions API

Cart actions allow you to programmatically control the shopping cart.

## actions.cart.openCart()

Open the cart drawer.

### Signature

```typescript
openCart(): void
```

### Example

```javascript
window.LiquidCommerce.elements.actions.cart.openCart();
```

---

## actions.cart.closeCart()

Close the cart drawer.

### Signature

```typescript
closeCart(): void
```

### Example

```javascript
window.LiquidCommerce.elements.actions.cart.closeCart();
```

---

## actions.cart.toggleCart()

Toggle the cart drawer open/closed.

### Signature

```typescript
toggleCart(): void
```

### Example

```javascript
// Add to your cart button
document.getElementById('cart-btn').addEventListener('click', () => {
  window.LiquidCommerce.elements.actions.cart.toggleCart();
});
```

---

## actions.cart.addProduct()

Add products to the cart programmatically.

### Signature

```typescript
addProduct(params: IAddProductParams[], openCart?: boolean): Promise<void>
```

### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `params` | IAddProductParams[] | Yes | Array of products to add |
| `openCart` | boolean | No | Open cart after adding (default: false) |

```typescript
interface IAddProductParams {
  identifier: string;      // Product UPC, SKU, or ID
  fulfillmentType: FulfillmentType;  // 'shipping' or 'onDemand'
  quantity: number;        // Number of items
  engravingLines?: string[]; // Optional engraving (see below)
}
```

#### `engravingLines` (optional)

Pre-fills an engraving for the added item. The SDK enforces the product's engraving rules and degrades silently rather than failing the call:

- Non-string-array input is ignored (warning logged).
- Blank/whitespace-only entries are stripped; an empty result is treated as no engraving.
- If the product/size doesn't support engraving, lines are dropped.
- Lines beyond `maxLines` are sliced off; any line longer than `maxCharsPerLine` is truncated.
- If no engravable variant is available for the chosen fulfillment, lines are dropped and the item is still added.

### Example

```javascript
// Add single product
await window.LiquidCommerce.elements.actions.cart.addProduct([
  {
    identifier: '00619947000020',
    fulfillmentType: 'shipping',
    quantity: 1
  }
], true);  // Open cart after adding

// Add multiple products
await window.LiquidCommerce.elements.actions.cart.addProduct([
  {
    identifier: '00619947000020',
    fulfillmentType: 'shipping',
    quantity: 2
  },
  {
    identifier: '08504405135',
    fulfillmentType: 'onDemand',
    quantity: 1
  }
]);

// Add a product with engraving
await window.LiquidCommerce.elements.actions.cart.addProduct([
  {
    identifier: '00619947000020',
    fulfillmentType: 'shipping',
    quantity: 1,
    engravingLines: ['Happy Birthday', 'Love, Sam']
  }
], true);
```

### Address Requirement

If no address is set, the SDK automatically:
1. Opens address input drawer
2. Waits for user to set address
3. Retries add-to-cart operation

### Errors

**Throws `SDKError` if:**
- Identifier is invalid
- Fulfillment type is not `'shipping'` or `'onDemand'`
- Quantity is less than 1
- Product is not available
- Product is a presale item

---

## actions.cart.applyPromoCode()

Apply a promo code to the cart.

### Signature

```typescript
applyPromoCode(promoCode: string): Promise<void>
```

### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `promoCode` | string | Yes | Promo code to apply |

### Example

```javascript
try {
  await window.LiquidCommerce.elements.actions.cart.applyPromoCode('SUMMER20');
  console.log('Promo code applied successfully');
} catch (error) {
  console.error('Invalid promo code:', error);
}
```

### Notes

- Code is automatically normalized (trimmed, uppercased)
- Promo codes must be enabled in configuration
- Only one promo code can be active at a time
- Applying a new code replaces the existing one

---

## actions.cart.removePromoCode()

Remove the active promo code.

### Signature

```typescript
removePromoCode(): Promise<void>
```

### Example

```javascript
await window.LiquidCommerce.elements.actions.cart.removePromoCode();
```

---

## actions.cart.resetCart()

Clear all items from the cart.

### Signature

```typescript
resetCart(): Promise<void>
```

### Example

```javascript
await window.LiquidCommerce.elements.actions.cart.resetCart();
console.log('Cart cleared');
```

### Warning

This permanently removes all cart items. There is no undo.

---

## actions.cart.getDetails()

Retrieve current cart information.

### Signature

```typescript
getDetails(): IBaseCartEventData
```

### Returns

```typescript
interface IBaseCartEventData {
  cartId: string;
  items: ICartItem[];
  subtotal: number;  // in cents
  total: number;     // in cents
  itemsCount: number;
  itemsQuantity: number;
  promoCode?: {
    code: string;
    discount: number;  // in cents
  };
  retailers: IRetailer[];
  // ... additional fields
}
```

### Example

```javascript
const cart = window.LiquidCommerce.elements.actions.cart.getDetails();

console.log(`Cart ID: ${cart.cartId}`);
console.log(`Items: ${cart.itemsCount}`);
console.log(`Subtotal: $${cart.subtotal / 100}`);
console.log(`Total: $${cart.total / 100}`);

if (cart.promoCode) {
  console.log(`Discount: $${cart.promoCode.discount / 100}`);
}
```

### Use Cases

#### Display Cart Summary

```javascript
function updateCartSummary() {
  const cart = window.LiquidCommerce.elements.actions.cart.getDetails();
  
  document.getElementById('cart-count').textContent = cart.itemsCount;
  document.getElementById('cart-total').textContent = `$${cart.total / 100}`;
}

// Update on cart changes
window.addEventListener('lce:actions.cart_updated', updateCartSummary);
```

#### Check Cart Before Checkout

```javascript
document.getElementById('checkout-btn').addEventListener('click', () => {
  const cart = window.LiquidCommerce.elements.actions.cart.getDetails();
  
  if (cart.itemsCount === 0) {
    alert('Your cart is empty');
    return;
  }
  
  window.LiquidCommerce.elements.actions.checkout.openCheckout();
});
```

#### Track Cart Value

```javascript
const cart = window.LiquidCommerce.elements.actions.cart.getDetails();

gtag('event', 'view_cart', {
  value: cart.total / 100,
  currency: 'USD',
  items: cart.items.map(item => ({
    item_id: item.identifier,
    quantity: item.quantity
  }))
});
```

## Events

Cart actions trigger events that you can listen for:

```javascript
// Item added
window.addEventListener('lce:actions.cart_item_added', (event) => {
  console.log('Item added:', event.detail.data);
});

// Cart updated
window.addEventListener('lce:actions.cart_updated', (event) => {
  console.log('Cart updated:', event.detail.data);
});

// Promo code applied
window.addEventListener('lce:actions.cart_promo_code_applied', (event) => {
  console.log('Promo applied:', event.detail.data);
});

// Product add success
window.addEventListener('lce:actions.cart_product_add_success', (event) => {
  console.log('Products added:', event.detail.data);
});

// Product add failed
window.addEventListener('lce:actions.cart_product_add_failed', (event) => {
  console.error('Failed to add:', event.detail.data);
});
```

See [Events Guide](../../guides/events.md) for all cart events.

## See Also

- [Cart Component Guide](../../guides/cart-component.md)
- [Cart Events](../../guides/events.md#cart-events)
- [Product Actions](./product-actions.md)
- [Checkout Actions](./checkout-actions.md)
