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

# Cart 객체

> Aftersell Cart SDK의 cart와 라인의 구조: cart, 장바구니 라인, 번들, 판매 플랜의 모든 필드입니다.

하나의 객체 구조가 SDK 전체를 흐르고 있어요. [`getCart()`](/ko/aftersell/cart/sdk-actions#getcart)가 반환하는 것, [`cart_loaded`와 `cart_updated`](/ko/aftersell/cart/sdk-events)가 핸들러에 전달하는 것, [커스텀 코드 블록](/ko/aftersell/cart/custom-code-blocks)이 받는 것이 모두 이것이에요.

<Note>
  **모든 금액은 통화의 최소 단위**(USD는 센트)이며, 형식이 지정된 문자열이 아니에요. `5779`는 \$57.79예요. 표시할 때는 [`formatMoney`](/ko/aftersell/cart/sdk-actions#formatmoneycents)를 사용하세요.
</Note>

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

| 필드                     | 타입                       | 설명                                                                                                |
| ---------------------- | ------------------------ | ------------------------------------------------------------------------------------------------- |
| `token`                | `string`                 | Shopify 장바구니 토큰이에요.                                                                               |
| `items`                | `AftersellCartLine[]`    | 라인 아이템이에요. [장바구니 라인](#cart-lines)을 참고하세요.                                                         |
| `itemCount`            | `number`                 | 쇼핑객에게 보이는 총 상품 수량이에요.                                                                             |
| `hasSubscriptionItems` | `boolean`                | `items`의 라인 중 하나 이상이 판매 플랜을 갖고 있으면 `true`예요. `itemCount`가 제외하는 애드온 라인도 포함해요. 빈 장바구니에서는 `false`예요. |
| `totalPrice`           | `number`                 | 현재 합계(센트 단위)예요.                                                                                   |
| `originalTotalPrice`   | `number`                 | 할인 전 합계(센트 단위)예요.                                                                                 |
| `totalDiscount`        | `number`                 | 할인 합계(센트 단위)예요.                                                                                   |
| `compareAtTotalPrice`  | `number \| null`         | 각 라인의 정가(MSRP) × 수량의 합(센트 단위). 사용할 수 없으면 `null`이므로 `originalTotalPrice`로 대체하세요.                   |
| `currency`             | `string`                 | 통화 코드예요.                                                                                          |
| `discountCodes`        | `string[]`               | 장바구니에 적용된 할인 코드(정렬됨). 없으면 `[]`예요.                                                                 |
| `attributes`           | `Record<string, string>` | 장바구니 속성. SDK에서는 읽기 전용이에요.                                                                         |

<Warning>
  **`itemCount`가 항상 `items`의 합계인 것은 아니에요.** `items`는 배송 보호처럼 드로어가 숨기는 애드온 라인을 포함해 실제 Shopify 장바구니를 그대로 반영해요. `itemCount`는 장바구니 배지와 일치하는 쇼핑객 대상 숫자예요. "쇼핑객이 몇 개를 선택했는가"에는 `itemCount`를, 장바구니가 렌더링하는 라인을 순회하려면 `items`를 사용하세요.

  `items`에서 완전히 빠지는 두 가지가 있어요: [`setHidden`](/ko/aftersell/cart/sdk-hooks#registerlinetransform)으로 숨긴 라인과, 앵커로 이동하는 [번들 하위 항목](#bundles)이에요. 둘 다 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">
  ## 장바구니 라인
</div>

`items`의 각 항목과 [`item_added`](/ko/aftersell/cart/sdk-events#item_added) 및 [`item_removed`](/ko/aftersell/cart/sdk-events#item_removed)의 `item`이에요:

| 필드                    | 타입                               | 설명                                                                                                                               |
| --------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `key`                 | `string`                         | 라인의 Shopify 키예요. 아이템 [액션](/ko/aftersell/cart/sdk-actions)에 이 값을 전달하세요.                                                           |
| `productId`           | `number`                         | Shopify 상품 ID예요.                                                                                                                 |
| `variantId`           | `number`                         | Shopify 변형 ID예요.                                                                                                                 |
| `handle`              | `string`                         | 상품 핸들이에요.                                                                                                                        |
| `title`               | `string`                         | 표시 제목이에요.                                                                                                                        |
| `productTitle`        | `string`                         | 변형을 제외한 상품 제목이에요.                                                                                                                |
| `variantTitle`        | `string \| null`                 | 변형 레이블 또는 `null`이에요.                                                                                                             |
| `variantOptions`      | `Array<{ name, value }>`         | 선택된 옵션. 예: `[{ name: 'Size', value: 'Medium' }]`. 단일 변형 상품에는 Shopify가 `Title: Default Title`을 내보내요.                              |
| `quantity`            | `number`                         | 이 라인의 수량이에요.                                                                                                                     |
| `linePrice`           | `number`                         | 라인 가격(센트 단위)이에요.                                                                                                                 |
| `finalLinePrice`      | `number`                         | 할인 후 라인 가격(센트 단위)이에요.                                                                                                            |
| `originalLinePrice`   | `number`                         | 할인 전 라인 가격(센트 단위)이에요.                                                                                                            |
| `compareAtPrice`      | `number \| null`                 | 변형의 **단위당** 정가(MSRP)(센트 단위). 없으면 `null`이에요.                                                                                      |
| `properties`          | `Record<string, string> \| null` | 라인 아이템 속성이에요.                                                                                                                    |
| `internalProperties`  | `Record<string, string>`         | [`registerLineTransform`](/ko/aftersell/cart/sdk-hooks#registerlinetransform)에서 온 렌더링 전용 오버레이. Shopify에 절대 저장되지 않아요. 없으면 `{}`예요. |
| `discountAllocations` | `Array<{ title, amount }>`       | 이 라인에 적용된 할인. `amount`는 센트 단위예요. 없으면 `[]`예요.                                                                                     |
| `isGiftCard`          | `boolean`                        | 라인이 기프트 카드인지 여부예요.                                                                                                               |
| `sellingPlan`         | `{ id, name } \| null`           | 활성 구독 플랜 또는 일회성 구매의 경우 `null`이에요.                                                                                                |
| `bundle`              | `AftersellCartBundle \| null`    | 앵커 라인의 [번들](#bundles) 뷰 모델. 번들이 아닌 라인과 하위 항목에서는 `null`이에요.                                                                       |
| `metadata`            | `Record<string, unknown>`        | 인리처 `id`를 키로 하는 [인리치먼트](/ko/aftersell/cart/sdk-hooks#registercartenricher) 데이터. 인리처가 채우기 전까지는 `{}`예요.                            |

<Warning>
  `properties`에는 상품 폼의 커스텀 텍스트 필드 같은 쇼핑객이 입력한 값이 포함될 수 있어요. 원시 HTML이 아니라 텍스트로 렌더링하세요.
</Warning>

<div id="identifying-a-line">
  ### 라인 식별하기
</div>

라인에 대해 동작하는 모든 경우에는 `key`를, *상품*을 식별하는 모든 경우에는 `variantId` 또는 `productId`를 사용하세요:

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

속성이 다르면 같은 변형이 여러 라인에 나타날 수 있어요. 각각 다른 각인 문구를 가진 두 개의 각인 머그잔은 하나의 `variantId`를 공유하는 두 개의 라인이에요. 그래서 액션이 `key`를 받는 거예요.

<div id="prices-on-a-line">
  ### 라인의 가격
</div>

혼동하기 쉬운 세 가지 가격이 있어요:

| 원하는 값                 | 사용할 필드                        |
| --------------------- | ----------------------------- |
| 쇼핑객이 이 라인에 대해 지불하는 금액 | `finalLinePrice`              |
| 장바구니 할인 전 가격          | `originalLinePrice`           |
| 단위당 MSRP 취소선 가격       | `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">
  ## 번들
</div>

라인들이 번들로 묶이면 **앵커** 라인이 `bundle` 객체를 가져요. 하위 항목은 그 안으로 접혀 들어가며 더 이상 `items`에 개별적으로 나타나지 않아요. 그룹화 설정 방법은 [다른 앱의 번들 라인 그룹화하기](/ko/aftersell/cart/sdk-use-case-bundles)를 참고하세요.

| 필드             | 타입                       | 설명                                        |
| -------------- | ------------------------ | ----------------------------------------- |
| `id`           | `string`                 | 번들 식별자예요.                                 |
| `source`       | `'native' \| 'grouped'`  | Shopify 네이티브 번들 또는 Aftersell이 그룹화한 라인이에요. |
| `memberKeys`   | `string[]`               | 번들에 포함된 모든 라인의 `key`예요.                   |
| `children`     | `AftersellBundleChild[]` | 번들의 콘텐츠예요.                                |
| `displayPrice` | `number`                 | 번들에 표시되는 가격(센트 단위)이에요.                    |

각 하위 항목은 `key`(네이티브 구성 요소는 `null`), `title`, `variantTitle`, `quantity`, `perAnchorQty`, `imageUrl`, `finalLinePrice`, `originalLinePrice`, `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">
  ## 구독 플랜
</div>

라인의 활성 플랜은 `sellingPlan`이고, 일회성 구매의 경우 `null`이에요. 장바구니 전체에 대한 답이 필요하면 라인을 직접 스캔하지 말고 `hasSubscriptionItems`를 읽으세요. 이 필드는 `items`에는 표시되지만 `itemCount`에서는 제외되는 애드온 라인도 포함하기 때문이에요:

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

라인에서 *선택 가능한* 플랜, 즉 선택기에 표시되는 플랜은 cart 객체에 없어요. 이는 [`registerSubscriptionOptionsTransform`](/ko/aftersell/cart/sdk-hooks#registersubscriptionoptionstransform)과 [`registerDefaultSubscriptionOptionSelector`](/ko/aftersell/cart/sdk-hooks#registerdefaultsubscriptionoptionselector)로 구성하세요.

<div id="where-to-go-next">
  ## 다음 단계
</div>

* **[액션](/ko/aftersell/cart/sdk-actions)**: 장바구니를 읽고 변경하세요.
* **[이벤트](/ko/aftersell/cart/sdk-events)**: 이 객체가 어디서 오는지 알아보세요.
* **[훅](/ko/aftersell/cart/sdk-hooks)**: 인리처로 라인에 자체 데이터를 추가하세요.
* **[사용 사례](/ko/aftersell/cart/sdk-use-cases)**: 이 필드들을 읽는 완전한 솔루션이에요.
