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

# Objeto cart

> La forma del cart del Cart SDK de Aftersell y sus líneas: cada campo del carrito, líneas del carrito, bundles y planes de venta.

Una sola forma de objeto fluye por todo el SDK. Es lo que [`getCart()`](/es/aftersell/cart/sdk-actions#getcart) devuelve, lo que [`cart_loaded` y `cart_updated`](/es/aftersell/cart/sdk-events) entregan a tu handler, y lo que recibe un [bloque Custom code](/es/aftersell/cart/custom-code-blocks).

<Note>
  **Todo el dinero está en la unidad menor de la moneda** (centavos para USD), nunca una cadena formateada. `5779` es \$57.79. Usa [`formatMoney`](/es/aftersell/cart/sdk-actions#formatmoneycents) para mostrarlo.
</Note>

<div id="the-cart">
  ## El carrito
</div>

| Campo                  | Tipo                     | Descripción                                                                                                                                              |
| ---------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `token`                | `string`                 | El token del carrito de Shopify.                                                                                                                         |
| `items`                | `AftersellCartLine[]`    | Las líneas de artículos. Consulta [líneas del carrito](#cart-lines).                                                                                     |
| `itemCount`            | `number`                 | Cantidad total de artículos, como la ve el comprador.                                                                                                    |
| `hasSubscriptionItems` | `boolean`                | `true` cuando al menos una línea en `items` lleva un plan de venta, incluyendo líneas de complemento que `itemCount` omite. `false` en un carrito vacío. |
| `totalPrice`           | `number`                 | Total actual, en centavos.                                                                                                                               |
| `originalTotalPrice`   | `number`                 | Total antes de descuentos, en centavos.                                                                                                                  |
| `totalDiscount`        | `number`                 | Total de descuentos, en centavos.                                                                                                                        |
| `compareAtTotalPrice`  | `number \| null`         | Suma del precio de comparación (MSRP) de cada línea × cantidad, en centavos. `null` cuando no está disponible, así que recurre a `originalTotalPrice`.   |
| `currency`             | `string`                 | Código de moneda.                                                                                                                                        |
| `discountCodes`        | `string[]`               | Códigos de descuento aceptados en el carrito, ordenados. `[]` cuando no hay ninguno.                                                                     |
| `attributes`           | `Record<string, string>` | Atributos del carrito. De solo lectura desde el SDK.                                                                                                     |

<Warning>
  **`itemCount` no siempre es la suma de `items`.** `items` refleja el carrito real de Shopify, incluyendo líneas de complemento que el drawer oculta, como la protección de envío. `itemCount` es el número visible para el comprador que coincide con la insignia del carrito. Para "cuántas cosas ha elegido el comprador", usa `itemCount`; para iterar sobre las líneas que el carrito está renderizando, usa `items`.

  Dos cosas faltan por completo en `items`: las líneas ocultas con [`setHidden`](/es/aftersell/cart/sdk-hooks#registerlinetransform), y los [hijos de bundle](#bundles), que se mueven a su ancla. Ambos siguen contando para los totales del carrito, que vienen directamente de Shopify.
</Warning>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('cart_updated', (state) => {
  console.log(state.itemCount, 'items');
  console.log('Total:', window.aftersell.cart.actions.formatMoney(state.totalPrice));
  console.log('Saved:', window.aftersell.cart.actions.formatMoney(state.totalDiscount));
  console.log('Codes:', state.discountCodes.join(', ') || 'none');
});
```

<div id="cart-lines">
  ## Líneas del carrito
</div>

Cada entrada en `items`, y el `item` en [`item_added`](/es/aftersell/cart/sdk-events#item_added) e [`item_removed`](/es/aftersell/cart/sdk-events#item_removed):

| Campo                 | Tipo                             | Descripción                                                                                                                                                                   |
| --------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`                 | `string`                         | La key de Shopify de la línea. Pásala a las [acciones](/es/aftersell/cart/sdk-actions) de artículos.                                                                          |
| `productId`           | `number`                         | ID del producto de Shopify.                                                                                                                                                   |
| `variantId`           | `number`                         | ID de la variante de Shopify.                                                                                                                                                 |
| `handle`              | `string`                         | Handle del producto.                                                                                                                                                          |
| `title`               | `string`                         | Título de visualización.                                                                                                                                                      |
| `productTitle`        | `string`                         | Título del producto sin la variante.                                                                                                                                          |
| `variantTitle`        | `string \| null`                 | Etiqueta de la variante, o `null`.                                                                                                                                            |
| `variantOptions`      | `Array<{ name, value }>`         | Opciones seleccionadas, p. ej. `[{ name: 'Size', value: 'Medium' }]`. Shopify emite `Title: Default Title` para un producto de una sola variante.                             |
| `quantity`            | `number`                         | Cantidad de esta línea.                                                                                                                                                       |
| `linePrice`           | `number`                         | Precio de la línea, en centavos.                                                                                                                                              |
| `finalLinePrice`      | `number`                         | Precio de la línea después de descuentos, en centavos.                                                                                                                        |
| `originalLinePrice`   | `number`                         | Precio de la línea antes de descuentos, en centavos.                                                                                                                          |
| `compareAtPrice`      | `number \| null`                 | Precio de comparación (MSRP) de la variante **por unidad**, en centavos. `null` cuando no hay ninguno.                                                                        |
| `properties`          | `Record<string, string> \| null` | Propiedades de la línea de artículo.                                                                                                                                          |
| `internalProperties`  | `Record<string, string>`         | Superposición de solo renderizado de [`registerLineTransform`](/es/aftersell/cart/sdk-hooks#registerlinetransform). Nunca se persiste en Shopify. `{}` cuando no hay ninguna. |
| `discountAllocations` | `Array<{ title, amount }>`       | Descuentos aplicados a esta línea. `amount` está en centavos. `[]` cuando no hay ninguno.                                                                                     |
| `isGiftCard`          | `boolean`                        | Si la línea es una tarjeta de regalo.                                                                                                                                         |
| `sellingPlan`         | `{ id, name } \| null`           | El plan de suscripción activo, o `null` para una compra única.                                                                                                                |
| `bundle`              | `AftersellCartBundle \| null`    | View model del [bundle](#bundles) en la línea ancla; `null` en líneas que no son bundle y en los hijos.                                                                       |
| `metadata`            | `Record<string, unknown>`        | Datos de [enriquecimiento](/es/aftersell/cart/sdk-hooks#registercartenricher) indexados por `id` del enriquecedor. `{}` hasta que un enriquecedor lo llena.                   |

<Warning>
  `properties` puede llevar entrada proporcionada por el comprador, como el campo de texto personalizado de un formulario de producto. Renderízalo como texto, nunca como HTML sin procesar.
</Warning>

<div id="identifying-a-line">
  ### Identificar una línea
</div>

Usa `key` para cualquier cosa que actúe sobre una línea, y `variantId` o `productId` para cualquier cosa que identifique un *producto*:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// ✅ Acting on a line: use key.
window.aftersell.cart.actions.removeItem(line.key);

// ✅ Recognising a product: use variantId.
const hasGift = state.items.some((line) => line.variantId === GIFT_VARIANT_ID);
```

La misma variante puede aparecer en varias líneas cuando las propiedades difieren. Dos tazas grabadas con distinto texto de grabado son dos líneas que comparten un mismo `variantId`. Por eso las acciones toman `key`.

<div id="prices-on-a-line">
  ### Precios en una línea
</div>

Tres precios, fáciles de confundir:

| Quieres                                            | Usa                           |
| -------------------------------------------------- | ----------------------------- |
| Lo que el comprador paga por esta línea            | `finalLinePrice`              |
| Lo que costaba antes de los descuentos del carrito | `originalLinePrice`           |
| El tachado de MSRP, por unidad                     | `compareAtPrice` × `quantity` |

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Is this line discounted?
const isDiscounted = line.finalLinePrice < line.originalLinePrice;

// Is it free? (A common way to detect a gift line.)
const isFree = line.finalLinePrice === 0;
```

<div id="bundles">
  ## Bundles
</div>

Cuando las líneas se agrupan en un bundle, la línea **ancla** lleva un objeto `bundle`. Los hijos se pliegan dentro de él y ya no aparecen en `items` por su cuenta. Consulta [Agrupar líneas de bundle de otra app](/es/aftersell/cart/sdk-use-case-bundles) para ver cómo se configura la agrupación.

| Campo          | Tipo                     | Descripción                                                    |
| -------------- | ------------------------ | -------------------------------------------------------------- |
| `id`           | `string`                 | Identificador del bundle.                                      |
| `source`       | `'native' \| 'grouped'`  | Un bundle nativo de Shopify, o líneas agrupadas por Aftersell. |
| `memberKeys`   | `string[]`               | La `key` de cada línea del bundle.                             |
| `children`     | `AftersellBundleChild[]` | El contenido del bundle.                                       |
| `displayPrice` | `number`                 | El precio mostrado para el bundle, en centavos.                |

Cada hijo lleva `key` (`null` para un componente nativo), `title`, `variantTitle`, `quantity`, `perAnchorQty`, `imageUrl`, `finalLinePrice`, `originalLinePrice` y `compareAtPrice`.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Skip bundle children when totalling your own line list.
const topLevel = state.items.filter((line) => !isBundleChild(line, state));
```

<div id="subscription-plans">
  ## Planes de suscripción
</div>

El plan activo de una línea es `sellingPlan`, o `null` para una compra única. Para una respuesta a nivel de todo el carrito, lee `hasSubscriptionItems` en lugar de escanear las líneas tú mismo, ya que también cuenta líneas de complemento que `items` presenta pero `itemCount` omite:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
if (state.hasSubscriptionItems) {
  // The cart contains at least one subscription line.
}

const subscriptions = state.items.filter((line) => line.sellingPlan);
console.log(subscriptions.length, 'subscription lines');
```

Los planes *disponibles* en una línea, los del selector, no están en el objeto cart. Dales forma con [`registerSubscriptionOptionsTransform`](/es/aftersell/cart/sdk-hooks#registersubscriptionoptionstransform) y [`registerDefaultSubscriptionOptionSelector`](/es/aftersell/cart/sdk-hooks#registerdefaultsubscriptionoptionselector).

<div id="where-to-go-next">
  ## Adónde ir después
</div>

* **[Acciones](/es/aftersell/cart/sdk-actions)**: lee y cambia el carrito.
* **[Eventos](/es/aftersell/cart/sdk-events)**: de dónde viene este objeto.
* **[Hooks](/es/aftersell/cart/sdk-hooks)**: agrega tus propios datos a una línea con un enriquecedor.
* **[Casos de uso](/es/aftersell/cart/sdk-use-cases)**: soluciones completas que leen estos campos.
