> ## 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.

# Obiekt koszyka

> Struktura koszyka Aftersell Cart SDK i jego pozycji: każde pole na koszyku, pozycje koszyka, zestawy (bundles) i plany sprzedaży.

Przez całe SDK przepływa jedna struktura obiektu. To ona jest zwracana przez [`getCart()`](/pl/aftersell/cart/sdk-actions#getcart), przekazywana Twojemu handlerowi przez [`cart_loaded` i `cart_updated`](/pl/aftersell/cart/sdk-events) oraz otrzymywana przez [blok Custom code](/pl/aftersell/cart/custom-code-blocks).

<Note>
  **Wszystkie kwoty są w jednostce mniejszej waluty** (centach dla USD), nigdy jako sformatowany string. `5779` to \$57.79. Do wyświetlenia użyj [`formatMoney`](/pl/aftersell/cart/sdk-actions#formatmoneycents).
</Note>

<div id="the-cart">
  ## Koszyk
</div>

| Pole                   | Typ                      | Opis                                                                                                                                               |
| ---------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `token`                | `string`                 | Token koszyka Shopify.                                                                                                                             |
| `items`                | `AftersellCartLine[]`    | Pozycje koszyka. Zobacz [pozycje koszyka](#cart-lines).                                                                                            |
| `itemCount`            | `number`                 | Łączna liczba produktów, tak jak widzi ją klient.                                                                                                  |
| `hasSubscriptionItems` | `boolean`                | `true`, gdy co najmniej jedna pozycja w `items` ma plan sprzedaży, w tym pozycje dodatków pomijane przez `itemCount`. `false` przy pustym koszyku. |
| `totalPrice`           | `number`                 | Bieżąca suma, w centach.                                                                                                                           |
| `originalTotalPrice`   | `number`                 | Suma przed rabatami, w centach.                                                                                                                    |
| `totalDiscount`        | `number`                 | Suma rabatów, w centach.                                                                                                                           |
| `compareAtTotalPrice`  | `number \| null`         | Suma cen porównawczych (MSRP) każdej pozycji × ilość, w centach. `null`, gdy niedostępna — wtedy użyj `originalTotalPrice`.                        |
| `currency`             | `string`                 | Kod waluty.                                                                                                                                        |
| `discountCodes`        | `string[]`               | Kody rabatowe zaakceptowane na koszyku, posortowane. `[]`, gdy ich nie ma.                                                                         |
| `attributes`           | `Record<string, string>` | Atrybuty koszyka. Tylko do odczytu z poziomu SDK.                                                                                                  |

<Warning>
  **`itemCount` nie zawsze jest sumą `items`.** `items` odzwierciedla prawdziwy koszyk Shopify, w tym pozycje dodatków, które drawer ukrywa, np. ochronę przesyłki. `itemCount` to liczba widoczna dla klienta, zgodna z plakietką koszyka. Aby wiedzieć, „ile rzeczy wybrał klient”, użyj `itemCount`; aby iterować po pozycjach renderowanych przez koszyk, użyj `items`.

  Dwie rzeczy w ogóle nie występują w `items`: pozycje ukryte za pomocą [`setHidden`](/pl/aftersell/cart/sdk-hooks#registerlinetransform) oraz [dzieci zestawów](#bundles), które przenoszą się na swoją pozycję główną (anchor). Obie nadal wliczają się do sum koszyka, które pochodzą prosto z 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">
  ## Pozycje koszyka
</div>

Każdy wpis w `items` oraz `item` w [`item_added`](/pl/aftersell/cart/sdk-events#item_added) i [`item_removed`](/pl/aftersell/cart/sdk-events#item_removed):

| Pole                  | Typ                              | Opis                                                                                                                                                                       |
| --------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`                 | `string`                         | Klucz Shopify pozycji. Przekazuj go do [akcji](/pl/aftersell/cart/sdk-actions) na pozycjach.                                                                               |
| `productId`           | `number`                         | ID produktu Shopify.                                                                                                                                                       |
| `variantId`           | `number`                         | ID wariantu Shopify.                                                                                                                                                       |
| `handle`              | `string`                         | Handle produktu.                                                                                                                                                           |
| `title`               | `string`                         | Wyświetlany tytuł.                                                                                                                                                         |
| `productTitle`        | `string`                         | Tytuł produktu bez wariantu.                                                                                                                                               |
| `variantTitle`        | `string \| null`                 | Etykieta wariantu lub `null`.                                                                                                                                              |
| `variantOptions`      | `Array<{ name, value }>`         | Wybrane opcje, np. `[{ name: 'Size', value: 'Medium' }]`. Shopify emituje `Title: Default Title` dla produktu z jednym wariantem.                                          |
| `quantity`            | `number`                         | Ilość tej pozycji.                                                                                                                                                         |
| `linePrice`           | `number`                         | Cena pozycji, w centach.                                                                                                                                                   |
| `finalLinePrice`      | `number`                         | Cena pozycji po rabatach, w centach.                                                                                                                                       |
| `originalLinePrice`   | `number`                         | Cena pozycji przed rabatami, w centach.                                                                                                                                    |
| `compareAtPrice`      | `number \| null`                 | Cena porównawcza wariantu (MSRP) **za sztukę**, w centach. `null`, gdy jej nie ma.                                                                                         |
| `properties`          | `Record<string, string> \| null` | Właściwości pozycji (line item properties).                                                                                                                                |
| `internalProperties`  | `Record<string, string>`         | Nakładka tylko do renderowania z [`registerLineTransform`](/pl/aftersell/cart/sdk-hooks#registerlinetransform). Nigdy nie jest zapisywana w Shopify. `{}`, gdy jej nie ma. |
| `discountAllocations` | `Array<{ title, amount }>`       | Rabaty zastosowane do tej pozycji. `amount` jest w centach. `[]`, gdy ich nie ma.                                                                                          |
| `isGiftCard`          | `boolean`                        | Czy pozycja jest kartą podarunkową.                                                                                                                                        |
| `sellingPlan`         | `{ id, name } \| null`           | Aktywny plan subskrypcji lub `null` dla zakupu jednorazowego.                                                                                                              |
| `bundle`              | `AftersellCartBundle \| null`    | Model widoku [zestawu](#bundles) na pozycji głównej; `null` na pozycjach niebędących zestawami i dzieciach.                                                                |
| `metadata`            | `Record<string, unknown>`        | Dane [wzbogacenia](/pl/aftersell/cart/sdk-hooks#registercartenricher) kluczowane po `id` wzbogacacza. `{}`, dopóki wzbogacacz ich nie wypełni.                             |

<Warning>
  `properties` może zawierać dane wprowadzone przez klienta, np. pole niestandardowego tekstu z formularza produktu. Renderuj je jako tekst, nigdy jako surowy HTML.
</Warning>

<div id="identifying-a-line">
  ### Identyfikowanie pozycji
</div>

Używaj `key` do wszystkiego, co działa na pozycji, a `variantId` lub `productId` do wszystkiego, co identyfikuje *produkt*:

```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);
```

Ten sam wariant może pojawić się w kilku pozycjach, gdy różnią się właściwościami. Dwa grawerowane kubki z różnymi tekstami graweru to dwie pozycje dzielące jedno `variantId`. Dlatego akcje przyjmują `key`.

<div id="prices-on-a-line">
  ### Ceny na pozycji
</div>

Trzy ceny, łatwe do pomylenia:

| Chcesz                                | Użyj                          |
| ------------------------------------- | ----------------------------- |
| Ile klient płaci za tę pozycję        | `finalLinePrice`              |
| Ile kosztowała przed rabatami koszyka | `originalLinePrice`           |
| Przekreślona cena MSRP, za sztukę     | `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">
  ## Zestawy (bundles)
</div>

Gdy pozycje są zgrupowane w zestaw, pozycja **główna (anchor)** niesie obiekt `bundle`. Dzieci są do niego wchłaniane i nie pojawiają się już samodzielnie w `items`. Zobacz [Grupowanie pozycji zestawów z innej aplikacji](/pl/aftersell/cart/sdk-use-case-bundles), aby dowiedzieć się, jak konfiguruje się grupowanie.

| Pole           | Typ                      | Opis                                                           |
| -------------- | ------------------------ | -------------------------------------------------------------- |
| `id`           | `string`                 | Identyfikator zestawu.                                         |
| `source`       | `'native' \| 'grouped'`  | Natywny zestaw Shopify lub pozycje zgrupowane przez Aftersell. |
| `memberKeys`   | `string[]`               | `key` każdej pozycji w zestawie.                               |
| `children`     | `AftersellBundleChild[]` | Zawartość zestawu.                                             |
| `displayPrice` | `number`                 | Cena wyświetlana dla zestawu, w centach.                       |

Każde dziecko niesie `key` (`null` dla natywnego komponentu), `title`, `variantTitle`, `quantity`, `perAnchorQty`, `imageUrl`, `finalLinePrice`, `originalLinePrice` i `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">
  ## Plany subskrypcji
</div>

Aktywny plan pozycji to `sellingPlan` lub `null` dla zakupu jednorazowego. Aby uzyskać odpowiedź dla całego koszyka, odczytaj `hasSubscriptionItems`, zamiast samodzielnie skanować pozycje, ponieważ liczy on także pozycje dodatków, które `items` pokazuje, a `itemCount` pomija:

```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');
```

*Dostępne* plany na pozycji, te widoczne w selektorze, nie znajdują się na obiekcie koszyka. Kształtuj je za pomocą [`registerSubscriptionOptionsTransform`](/pl/aftersell/cart/sdk-hooks#registersubscriptionoptionstransform) i [`registerDefaultSubscriptionOptionSelector`](/pl/aftersell/cart/sdk-hooks#registerdefaultsubscriptionoptionselector).

<div id="where-to-go-next">
  ## Co dalej
</div>

* **[Akcje](/pl/aftersell/cart/sdk-actions)**: odczytuj i zmieniaj koszyk.
* **[Zdarzenia](/pl/aftersell/cart/sdk-events)**: skąd pochodzi ten obiekt.
* **[Hooki](/pl/aftersell/cart/sdk-hooks)**: dodawaj własne dane do pozycji za pomocą wzbogacacza.
* **[Przypadki użycia](/pl/aftersell/cart/sdk-use-cases)**: kompletne rozwiązania odczytujące te pola.
