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

# Adicionar automaticamente um brinde ao atingir um limite

> Um caso de uso do Cart SDK que adiciona um brinde quando o total do carrinho cruza um limite, e o remove se o total cair abaixo.

Observe o total do carrinho e mantenha um brinde sincronizado com ele: adicione o brinde quando o comprador cruzar um limite de gasto e remova-o se ele voltar a ficar abaixo.

<Note>
  Para uma versão configurável pelo lojista com níveis, regras por mercado e uma barra de progresso, use o bloco [Rewards](/pt/aftersell/cart/rewards-block), sem código. Isto é para quando sua regra é algo que o bloco não consegue expressar.
</Note>

<div id="the-snippet">
  ## O snippet
</div>

Cole em **Cart settings → Custom script → Initialization** e defina as duas constantes:

```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">
  ## Como funciona
</div>

**`reconcileGift`** descreve o estado em que o carrinho *deveria* estar, e então faz no máximo uma alteração para chegar lá:

* Qualifica e o brinde não está lá → [`addItem`](/pt/aftersell/cart/sdk-actions#additemvariantid-quantity) o adiciona.
* Não qualifica e o brinde está lá → [`removeItem`](/pt/aftersell/cart/sdk-actions#removeitemkey) o remove, pela `key` da linha.
* Caso contrário → não faz nada.

Ela executa tanto em [`cart_loaded`](/pt/aftersell/cart/sdk-events#cart_loaded) (para que um carrinho que já qualifica no carregamento da página receba o brinde) quanto em [`cart_updated`](/pt/aftersell/cart/sdk-events#cart_updated) (para reagir a cada mudança depois disso). Como `cart_loaded` é reproduzido para assinantes tardios, isso funciona não importa quando seu script executa.

<Warning>
  **As guardas `!gift` / `gift` são o que impede um loop.** Adicionar o brinde dispara `cart_updated`, que executa `reconcileGift` de novo, e a segunda passagem encontra o brinde já presente, então não faz nada. Remova as guardas e você terá um loop infinito. Veja [as duas regras](/pt/aftersell/cart/sdk-events#the-two-rules).
</Warning>

Note que adicionar o brinde **aumenta o total do carrinho**, então um limite próximo ao preço de um produto pode oscilar: adicionar um brinde de \$0 é seguro, mas um brinde com preço poderia empurrar o carrinho acima do limite sozinho. Mantenha o brinde grátis, ou compare com um total que o exclua.

<div id="adapting-it">
  ## Adaptando
</div>

**Condicione pela contagem de itens em vez do gasto:**

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

**Condicione por um produto específico estar no carrinho:**

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

**Só em certos países.** Leia [`context`](/pt/aftersell/cart/sdk-overview#context), que está disponível antes de o carrinho carregar:

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

**Exclua o brinde do limite** para que ele não sustente a si mesmo:

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

**Marque o brinde para que ele pareça um brinde.** Um [line transform](/pt/aftersell/cart/sdk-hooks#registerlinetransform) pode mudar o título de uma linha, o título da variante, o estado oculto e as propriedades internas — então renomeie-o:

```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>
  Um line transform **não pode ocultar os controles de quantidade de uma linha** — seus únicos setters são `setTitle`, `setVariantTitle`, `setHidden` e `setInternalProperties`. Se um comprador mudar a quantidade do brinde, corrija a partir de um handler de `cart_updated`.
</Note>

<div id="where-to-go-next">
  ## Para onde ir a seguir
</div>

* **[Bloco Rewards](/pt/aftersell/cart/rewards-block)**: a versão sem código, com níveis.
* **[Actions](/pt/aftersell/cart/sdk-actions)**: `addItem`, `removeItem` e o resto.
* **[Events](/pt/aftersell/cart/sdk-events)**: por que as guardas importam.
