> ## 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 SDK 사용 사례예요.

카트 총액을 관찰하며 무료 사은품을 동기화 상태로 유지하세요: 쇼핑객이 지출 기준을 넘으면 사은품을 추가하고, 다시 아래로 내려가면 제거해요.

<Note>
  티어, 마켓별 규칙, 진행률 표시줄이 포함된 머천트 구성 버전은 코드 없이 [Rewards](/ko/aftersell/cart/rewards-block) 블록을 사용하세요. 이 방법은 블록으로 표현할 수 없는 규칙이 필요할 때를 위한 거예요.
</Note>

<div id="the-snippet">
  ## 스니펫
</div>

**Cart settings → Custom script → Initialization**에 붙여넣고 두 상수를 설정하세요:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const FREE_GIFT_VARIANT_ID = 1234567890; // the gift product's variant id
const THRESHOLD_CENTS = 5000;            // $50.00, since totals are in cents

function reconcileGift(state) {
  const gift = state.items.find((line) => line.variantId === FREE_GIFT_VARIANT_ID);
  const qualifies = state.totalPrice >= THRESHOLD_CENTS;

  if (qualifies && !gift) {
    window.aftersell.cart.actions.addItem(FREE_GIFT_VARIANT_ID, 1);
  } else if (!qualifies && gift) {
    window.aftersell.cart.actions.removeItem(gift.key);
  }
}

window.aftersell.cart.events.on('cart_loaded', reconcileGift);
window.aftersell.cart.events.on('cart_updated', reconcileGift);
```

<div id="how-it-works">
  ## 작동 방식
</div>

\*\*`reconcileGift`\*\*는 카트가 *있어야 할* 상태를 기술한 다음, 그 상태에 도달하기 위해 최대 한 번의 변경만 수행해요:

* 조건을 충족하는데 사은품이 없으면 → [`addItem`](/ko/aftersell/cart/sdk-actions#additemvariantid-quantity)이 추가해요.
* 조건을 충족하지 않는데 사은품이 있으면 → [`removeItem`](/ko/aftersell/cart/sdk-actions#removeitemkey)이 라인의 `key`로 제거해요.
* 그 외에는 → 아무것도 하지 않아요.

[`cart_loaded`](/ko/aftersell/cart/sdk-events#cart_loaded)(페이지 로드 시 이미 조건을 충족한 카트가 사은품을 받도록)와 [`cart_updated`](/ko/aftersell/cart/sdk-events#cart_updated)(이후의 모든 변경에 반응하도록) 양쪽에서 실행돼요. `cart_loaded`는 늦게 구독한 경우에도 재생되므로, 스크립트가 언제 실행되든 작동해요.

<Warning>
  **`!gift` / `gift` 가드가 무한 반복을 막아 줘요.** 사은품을 추가하면 `cart_updated`가 발생해 `reconcileGift`가 다시 실행되는데, 두 번째 실행에서는 사은품이 이미 있으므로 아무것도 하지 않아요. 가드를 제거하면 무한 루프가 발생해요. [두 가지 규칙](/ko/aftersell/cart/sdk-events#the-two-rules)을 참고하세요.
</Warning>

사은품을 추가하면 **카트 총액이 올라가므로**, 상품 가격 근처의 기준 금액은 진동할 수 있다는 점에 유의하세요: \$0 사은품 추가는 안전하지만, 가격이 있는 사은품은 그 자체로 카트를 기준 위로 밀어 올릴 수 있어요. 사은품을 무료로 유지하거나, 사은품을 제외한 총액과 비교하세요.

<div id="adapting-it">
  ## 응용하기
</div>

**지출 대신 상품 수량으로 게이트하기:**

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const qualifies = state.itemCount >= 3;
```

**특정 상품이 카트에 있는지로 게이트하기:**

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const qualifies = state.items.some((line) => line.productId === TRIGGER_PRODUCT_ID);
```

**특정 국가에서만 적용.** 카트가 로드되기 전에 사용할 수 있는 [`context`](/ko/aftersell/cart/sdk-overview#context)를 읽으세요:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const ELIGIBLE = ['US', 'CA'];

// Only register the handlers for eligible countries.
if (ELIGIBLE.includes(window.aftersell.cart.context.customer_country)) {
  window.aftersell.cart.events.on('cart_loaded', reconcileGift);
  window.aftersell.cart.events.on('cart_updated', reconcileGift);
}
```

**기준 금액에서 사은품 제외**하여 사은품 스스로 조건을 유지하지 못하게 하기:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const subtotalWithoutGift = state.items.reduce(
  (sum, line) => (line.variantId === FREE_GIFT_VARIANT_ID ? sum : sum + line.finalLinePrice),
  0
);
const qualifies = subtotalWithoutGift >= THRESHOLD_CENTS;
```

**사은품임을 알 수 있게 표시하기.** [라인 트랜스폼](/ko/aftersell/cart/sdk-hooks#registerlinetransform)은 라인의 제목, 옵션 제목, 숨김 상태, 내부 속성을 변경할 수 있으므로 레이블을 바꿔 보세요:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerLineTransform((line) => {
  if (line.variantId === FREE_GIFT_VARIANT_ID) {
    line.setTitle('Free gift 🎁');
  }
});
```

<Note>
  라인 트랜스폼은 **라인의 수량 컨트롤을 숨길 수 없어요** — 설정 가능한 것은 `setTitle`, `setVariantTitle`, `setHidden`, `setInternalProperties`뿐이에요. 쇼핑객이 사은품 수량을 변경하면 `cart_updated` 핸들러에서 수정하세요.
</Note>

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

* **[Rewards 블록](/ko/aftersell/cart/rewards-block)**: 티어가 포함된 노코드 버전.
* **[Actions](/ko/aftersell/cart/sdk-actions)**: `addItem`, `removeItem` 등.
* **[Events](/ko/aftersell/cart/sdk-events)**: 가드가 중요한 이유.
