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

# 액션

> 장바구니를 읽고 변경하는 모든 Aftersell Cart SDK 액션: 열기, 닫기, 추가, 제거, 수량 업데이트, 변형 교체, 상태 읽기, 금액 형식 지정입니다.

액션은 **장바구니를 읽고 변경해요**. `window.aftersell.cart.actions` 아래에 있어요.

<Note>
  액션은 **장바구니가 준비된 후**, `ready()` 안이나 [이벤트](/ko/aftersell/cart/sdk-events) 핸들러 안에서 실행하세요.
</Note>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  console.log(state.itemCount, 'items');
});
```

<Note>
  **장바구니가 로드되기 전에는 액션이 스텁(stub)이에요.** 각 액션은 해당 액션 이름이 포함된 콘솔 경고(예: `cart.actions.addItem() called before the cart loaded`)를 기록하고 아무 동작도 하지 않아요. 비동기 액션은 여전히 Promise를 resolve하므로 `.then()` 체인은 예외를 던지지 않고 정상적으로 실행돼요. `getCart()`는 `null`을, `formatMoney()`는 빈 문자열을 반환해요.

  너무 일찍 호출해도 아무것도 깨지지 않지만, 아무 일도 일어나지 않아요. 액션이 아무 동작도 하지 않는 것처럼 보이면 콘솔에서 해당 경고를 확인하세요.
</Note>

<div id="every-action">
  ## 모든 액션
</div>

| 액션                                                       | 시그니처                                 | 반환값                     | 하는 일                     |
| -------------------------------------------------------- | ------------------------------------ | ----------------------- | ------------------------ |
| [`open`](#open-and-close)                                | `open()`                             | 없음                      | 드로어를 열어요.                |
| [`close`](#open-and-close)                               | `close()`                            | 없음                      | 드로어를 닫아요.                |
| [`getCart`](#getcart)                                    | `getCart()`                          | `AftersellCart \| null` | 현재 장바구니를 읽어요.            |
| [`formatMoney`](#formatmoneycents)                       | `formatMoney(cents)`                 | `string`                | 표시용으로 금액 형식을 지정해요.       |
| [`addItem`](#additemvariantid-quantity)                  | `addItem(variantId, quantity?)`      | `Promise`               | 변형을 추가해요.                |
| [`removeItem`](#removeitemkey)                           | `removeItem(key)`                    | `Promise`               | 라인을 제거해요.                |
| [`updateItemQuantity`](#updateitemquantitykey-quantity)  | `updateItemQuantity(key, quantity)`  | `Promise`               | 라인의 수량을 설정해요.            |
| [`replaceLineVariant`](#replacelinevariantkey-variantid) | `replaceLineVariant(key, variantId)` | `Promise`               | 라인의 변형을 교체해요.            |
| [`refresh`](#refresh)                                    | `refresh()`                          | `Promise`               | Shopify에서 장바구니를 다시 가져와요. |
| [`visualRefresh`](#visualrefresh)                        | `visualRefresh()`                    | 없음                      | 다시 가져오지 않고 화면을 다시 그려요.   |

<Warning>
  `cart_updated` 핸들러에서 액션을 호출하면 루프가 생길 수 있어요. 먼저 [두 가지 규칙](/ko/aftersell/cart/sdk-events#the-two-rules)을 읽어 보세요.
</Warning>

***

<div id="drawer">
  ## 드로어
</div>

<div id="open-and-close">
  ### open과 close
</div>

장바구니 드로어를 열거나 닫아요. 둘 다 동기식이며 인수를 받지 않아요.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Open the drawer from your own cart link.
document.querySelector('#my-cart-link').addEventListener('click', (event) => {
  event.preventDefault();
  window.aftersell.cart.actions.open();
});
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Close it after the shopper does something in a custom block.
window.aftersell.cart.actions.close();
```

***

<div id="reading">
  ## 읽기
</div>

<div id="getcart">
  ### getCart()
</div>

현재 [cart 객체](/ko/aftersell/cart/sdk-cart-object)를 반환하거나, 로드되기 전에는 `null`을 반환해요. 결과는 **복사본**이므로, 변경해도 실제 장바구니는 바뀌지 않아요.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  if (!state) return; // the initial load failed

  console.log(state.itemCount, 'items,', state.items.length, 'lines');
  console.log('Total:', window.aftersell.cart.actions.formatMoney(state.totalPrice));
});
```

스냅샷이므로 결과를 계속 보관하지 마세요. 최신 데이터가 필요할 때마다 다시 읽으세요. 이벤트 핸들러에서는 페이로드로 이미 최신 장바구니가 전달되므로 `getCart()`는 불필요해요.

<div id="formatmoneycents">
  ### formatMoney(cents)
</div>

스토어의 금액 형식을 사용해 최소 단위 금액의 형식을 지정해요. SDK의 모든 가격은 센트 단위이므로, 이 함수로 표시 가능한 형태로 변환하세요.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.actions.formatMoney(5779);  // "$57.79"
window.aftersell.cart.actions.formatMoney(0);     // "$0.00"
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Show the cart total in your own header element.
window.aftersell.cart.events.on('cart_updated', (state) => {
  document.querySelector('#header-total').textContent =
    window.aftersell.cart.actions.formatMoney(state.totalPrice);
});
```

[`configure({ money_format })`](/ko/aftersell/cart/sdk-configure#money_format)으로 형식을 재정의하세요.

***

<div id="changing-the-cart">
  ## 장바구니 변경하기
</div>

<Note>
  아이템 액션은 변형 ID가 아니라 Shopify \*\*`key`\*\*로 라인을 식별해요. 장바구니에는 같은 변형이 서로 다른 속성을 가진 여러 라인으로 담길 수 있기 때문이에요. `getCart().items[n].key`에서 읽으세요.
</Note>

<div id="additemvariantid-quantity">
  ### addItem(variantId, quantity?)
</div>

장바구니에 변형을 추가해요. `quantity`의 기본값은 `1`이에요. 장바구니가 안정되면 resolve돼요.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Add one, then show the shopper.
window.aftersell.cart.actions.addItem(41720671830082).then(() => {
  window.aftersell.cart.actions.open();
});
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Add a specific quantity.
window.aftersell.cart.actions.addItem(41720671830082, 3);
```

이미 장바구니에 있는 변형을 추가하면, 기존 라인에 라인 아이템 속성이 없는 한 두 번째 라인을 만드는 대신 해당 라인의 수량이 증가해요. 속성이 있는 라인은 별개의 라인이므로 새 라인이 생겨요.

<div id="removeitemkey">
  ### removeItem(key)
</div>

라인을 완전히 제거해요.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Remove any free line from the cart.
const gift = window.aftersell.cart.actions
  .getCart()
  .items.find((line) => line.finalLinePrice === 0);
if (gift) window.aftersell.cart.actions.removeItem(gift.key);
```

<div id="updateitemquantitykey-quantity">
  ### updateItemQuantity(key, quantity)
</div>

라인의 수량을 설정해요. `0`을 전달하면 라인이 제거돼요.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const line = window.aftersell.cart.actions.getCart().items[0];
if (line) window.aftersell.cart.actions.updateItemQuantity(line.key, 3);
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Cap a line at one unit.
window.aftersell.cart.events.on('cart_updated', (state) => {
  state.items.forEach((line) => {
    if (line.variantId === LIMITED_VARIANT_ID && line.quantity > 1) {
      window.aftersell.cart.actions.updateItemQuantity(line.key, 1);
    }
  });
});
```

두 번째 예제는 두 번째 실행에서 `> 1` 검사가 false가 되므로 `cart_updated`에서 실행해도 안전해요. [두 가지 규칙](/ko/aftersell/cart/sdk-events#the-two-rules)을 참고하세요.

<div id="replacelinevariantkey-variantid">
  ### replaceLineVariant(key, variantId)
</div>

라인의 수량과 속성을 유지하면서 변형을 교체해요. 장바구니 안의 사이즈 또는 맛 전환기에 유용해요.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const line = window.aftersell.cart.actions.getCart().items[0];
window.aftersell.cart.actions.replaceLineVariant(line.key, 41720671862850);
```

<Warning>
  교체 시 라인의 **판매 플랜이 초기화돼요**. 플랜을 다시 적용하지 않으면 구독 라인이 일회성 구매가 돼요.
</Warning>

교체는 제자리 편집이 아니라 추가 후 제거이므로, 결과는 **새 라인**이에요: 새 `key`를 받고 장바구니 끝에 배치돼요. 전달했던 key를 재사용하지 말고 이후에 `getCart()`를 다시 읽으세요.

***

<div id="refreshing">
  ## 새로 고침
</div>

<div id="refresh">
  ### refresh()
</div>

Shopify에서 장바구니를 다시 가져와요. SDK 외부에서 무언가가 장바구니를 변경했는데 드로어가 이를 감지하지 못했을 때 사용하세요.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// After a raw Ajax API call of your own.
fetch('/cart/add.js', { method: 'POST', /* … */ })
  .then(() => window.aftersell.cart.actions.refresh())
  .then(() => { window.aftersell.cart.actions.open(); });
```

Aftersell은 이미 Shopify의 표준 장바구니 이벤트를 수신하고 스스로 다시 가져오기 때문에 대부분의 경우 이 함수는 필요 없어요. 커스텀 통합이 이를 우회할 때 사용하세요.

<div id="visualrefresh">
  ### visualRefresh()
</div>

Shopify에서 장바구니를 다시 가져오지 않고 렌더링 변환을 다시 실행해요. 거의 필요 없어요: [라인 변환](/ko/aftersell/cart/sdk-hooks#registerlinetransform), [비교자](/ko/aftersell/cart/sdk-hooks#registerlinecomparator), [인리처](/ko/aftersell/cart/sdk-hooks#registercartenricher), 또는 두 [구독 훅](/ko/aftersell/cart/sdk-hooks#registersubscriptionoptionstransform) 중 하나를 등록(또는 등록 해제)하면 자동으로 실행돼요. 화면에 이미 표시된 것을 바꾸지 않는 두 개의 장바구니 담기 훅만 실행되지 않아요.

변환이 *의존하는* 무언가는 변경되었지만 장바구니 자체는 변경되지 않았을 때 사용하세요:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// A currency switcher changed the format: repaint prices already on screen.
window.myTheme.onCurrencyChange((currency) => {
  window.aftersell.cart.configure({ money_format: FORMATS[currency] });
  window.aftersell.cart.actions.visualRefresh();
});
```

***

<div id="notes-and-edge-cases">
  ## 참고 사항 및 엣지 케이스
</div>

* **비동기 액션은 변경이 안정되면 resolve돼요.** await하면 장바구니가 실제로 업데이트된 후 작업을 순차적으로 진행할 수 있어요.
* **`getCart()`는 복사본을 반환해요.** 변경해도 실제 장바구니에는 아무 영향이 없어요.
* **할인 코드용 액션은 없어요.** 적용된 코드는 장바구니(`discountCodes`, `totalDiscount`)와 라인별(`discountAllocations`)로 읽을 수 있으며, 쇼핑객은 [할인 코드](/ko/aftersell/cart/discount-code-block) 블록을 통해 적용해요.
* **장바구니 속성이나 메모용 액션은 없어요.** 속성은 cart 객체에서 읽을 수 있고, 쇼핑객은 [메모](/ko/aftersell/cart/notes-block) 블록을 통해 메모를 작성해요.
* **라인을 제거하는 대신 숨기려면** [`registerLineTransform`](/ko/aftersell/cart/sdk-hooks#registerlinetransform)을 사용하세요. 제거는 쇼핑객의 합계를 변경하지만 숨기기는 그렇지 않아요.

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

* **[Cart 객체](/ko/aftersell/cart/sdk-cart-object)**: `getCart()`가 반환하는 것이에요.
* **[이벤트](/ko/aftersell/cart/sdk-events)**: 이 액션들을 실행할 시점이에요.
* **[훅](/ko/aftersell/cart/sdk-hooks)**: 장바구니를 변경하는 대신 라인이 렌더링되는 방식을 변경하세요.
* **[사용 사례](/ko/aftersell/cart/sdk-use-cases)**: 일반적인 요청에 대한 완전한 솔루션이에요.
