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

# Cart (actions)

> Carrinho da vitrine com useCorvexCart e storefront.cart.

# Cart actions

No tema, use **`useCorvexCart()`** ou `storefront.cart.*`. Não monte fetch manual.

`cartId` coincide com o checkout da sessão — `checkoutUrl` vem pronto após o primeiro `ensure` / `addItem`.

***

## Hook recomendado

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { useCorvexCart } from '@corvex/theme-sdk';

function AddToCartButton({ product, variant }) {
  const { addItem, itemCount, mutating } = useCorvexCart();

  return (
    <button
      type="button"
      disabled={mutating}
      onClick={() => addItem(product, 1, variant)}
    >
      Adicionar ({itemCount})
    </button>
  );
}
```

| Campo / método | Descrição |
| - | - |
| `cart` | Carrinho normalizado do backend |
| `items` | Alias `cart.items` |
| `itemCount` | Quantidade total de unidades |
| `total` / `subtotal` | Números de `totalPrice` e `subtotalPrice`. A moeda é `cart.currency`, não um real fixo. `totalDiscount` vem da resposta quando a API envia |
| `checkoutUrl` | Link de pagamento Corvex |
| `loading` | Bootstrap inicial (`ensure`) |
| `mutating` | Operação em andamento |
| `addItem(product, qty, variant?)` | `POST .../items` |
| `updateQuantity(itemId, qty)` | `PATCH .../items/:itemId` |
| `removeItem(itemId)` | `DELETE .../items/:itemId` |
| `clearCart()` | `DELETE .../items` |
| `refresh()` | Re-sincroniza com `GET .../cart/:id` |
| `goToCheckout(options?)` | Redirect para `checkoutUrl` |

Sessão persistida em `localStorage`: `corvex_storefront_cart_{storeId}`.

***

## Contexto de página (`page.cart`)

No template **Carrinho** (`/cart`), a plataforma injeta:

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { usePage } from '@corvex/theme-sdk';

export default function CartTemplate() {
  const { cart } = usePage('cart');

  return (
    <ul>
      {cart.items.map((item) => (
        <li key={item.id}>
          {item.title} × {item.quantity} — R$ {item.linePrice}
        </li>
      ))}
    </ul>
  );
}
```

`useCorvexCart()` e `page.cart` leem o **mesmo carrinho** (deduplicado via `storefront.cart.ensure()`).

***

## Cliente `storefront.cart`

```js theme={"theme":{"light":"github-light","dark":"github-dark"}}
const storefront = createStorefront({ storeId });

// Bootstrap (localStorage + GET ou POST)
const { cart, checkoutUrl } = await storefront.cart.ensure();

// Mutations
await storefront.cart.addItem(cart.id, {
  productId: product.id,
  productVariantId: variant?.id ?? null,
  quantity: 1,
});

await storefront.cart.updateItem(cart.id, lineId, { quantity: 3 });
await storefront.cart.removeItem(cart.id, lineId);
await storefront.cart.clearItems(cart.id);

// Opcional antes do redirect
await storefront.cart.checkout(cart.id, {
  customer: { email: 'maria@email.com' },
});
```

Helper para montar body de `addItem`:

```js theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { resolveCartLineInput } from '@corvex/theme-sdk';

const line = resolveCartLineInput(product, 1, selectedVariant);
await storefront.cart.addItem(cartId, line);
```

***

## Regras importantes

* **Não envie preço manual** — backend resolve preço, título e imagem.
* Envie `productVariantId` quando o produto tem variantes.
* `removeItem` / `updateQuantity` usam **`items[n].id`** (UUID da linha), não `productId`.
* Se `GET` retornar `CART_NOT_FOUND`, o SDK recria a sessão automaticamente.
* Preços na API são números decimais na moeda do carrinho. Use `unitPriceMoney` / `linePriceMoney` ou `formatMoney`. Não prefixe `R$` à mão.
* Se `addItem` com `productVariantId` receber erro interno ou variante inválida, o cliente tenta de novo sem o id da variante (`cart.js`). A linha pode entrar sem a variante escolhida. Isso é comportamento do SDK, não uma garantia de estoque.

***

## Erros comuns

| Código | Ação sugerida na UI |
| - | - |
| `CART_NOT_FOUND` | SDK recria carrinho; opcional toast |
| `PRODUCT_NOT_FOUND` | Produto indisponível |
| `VARIANT_NOT_FOUND` | Variante inválida — pedir seleção |
| `EMPTY_CART` | Bloquear checkout |
| `TOO_MANY_ITEMS` | Citado só nesta página. O cliente deste repositório não trata esse código |

***

## Provider

`CorvexProvider` já inclui `CorvexCartProvider`. Não é necessário wrapper extra.

Separação de responsabilidades:

* **Queries** → catálogo (`products`, `categories`, `search`)
* **Actions** → carrinho (`storefront.cart`, `useCorvexCart`)

Cupom não entra por `storefront.cart`. A validação pública é `storefront.coupons.validate`. O carrinho só reflete `totalDiscount` se a API já devolveu o desconto.

Tarefas prontas, sem repetir o contrato aqui:

* [Card de produto](https://docs-loja.usecorvex.com.br/cookbook/product-card.md)
* [Seletor de variante](https://docs-loja.usecorvex.com.br/cookbook/variant-selector.md)
* [Drawer do carrinho](https://docs-loja.usecorvex.com.br/cookbook/cart-drawer.md) — quantidade, contagem e `goToCheckout`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.