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

# Exigir aceite de termos antes do checkout

> Um caso de uso do Cart SDK que adiciona uma caixa de seleção de termos e condições ao Aftersell Cart e bloqueia o checkout até o comprador aceitar.

Adicione uma caixa de seleção abaixo do botão de checkout e impeça o comprador de prosseguir até que ele a marque. Útil para aceite de termos, verificações de idade e confirmações de produtos sob encomenda.

<Warning>
  **O evento `checkout` não pode cancelar o checkout.** Ele dispara como uma notificação logo antes de o navegador navegar, então retornar `false` ou chamar `preventDefault` não faz nada. A única forma de controlar o checkout é impedir que o botão responda a cliques *antes* de ser pressionado, que é o que esta página mostra.

  Trate isto como um obstáculo de UI, não uma garantia legal. Um comprador determinado ainda pode chegar ao checkout diretamente.
</Warning>

<div id="how-it-works">
  ## Como funciona
</div>

Três peças:

1. Um **bloco Custom code** abaixo do botão de checkout renderiza a caixa de seleção.
2. Enquanto a caixa está desmarcada, o bloco adiciona uma classe aos botões de checkout e de pagamento expresso do carrinho através do [shadow root](/pt/aftersell/cart/sdk-overview#shadowroot).
3. O **Custom CSS** faz essa classe desativar os cliques.

<div id="step-1-add-the-checkbox-block">
  ## Passo 1: adicione o bloco da caixa de seleção
</div>

Adicione um [bloco Custom code](/pt/aftersell/cart/custom-code-blocks) abaixo do seu bloco de botão Checkout, mude-o para o modo **React component** e cole:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  const [accepted, setAccepted] = useState(false);

  useEffect(() => {
    const root = window.aftersell?.cart?.shadowRoot;
    if (!root) return;

    const targets = root.querySelectorAll(
      '.cart-external-checkout-button, .cart-external-express-buttons'
    );
    targets.forEach((el) => el.classList.toggle('checkout-gated', !accepted));
  }, [accepted, props.cart]);

  return (
    <div style={{ width: '100%', fontSize: '14px', textAlign: 'center' }}>
      <label style={{ display: 'flex', gap: '6px', justifyContent: 'center', alignItems: 'center' }}>
        <input
          type="checkbox"
          checked={accepted}
          onChange={(e) => setAccepted(e.target.checked)}
        />
        <span>
          I accept the{' '}
          <a href="https://yourstore.com/terms" target="_blank" rel="noopener noreferrer">
            Terms &amp; Conditions
          </a>
        </span>
      </label>
      {!accepted && (
        <div style={{ color: '#c00', fontWeight: 600, marginTop: '6px' }}>
          Please accept the terms above to continue.
        </div>
      )}
    </div>
  );
}
```

Clique em **Compile** e então ative **"Use custom template"**. O bloco não renderiza nada até você fazer isso.

A dependência `props.cart` importa: ela reaplica a classe depois que o carrinho re-renderiza, o que de outra forma a apagaria.

<div id="step-2-add-the-css">
  ## Passo 2: adicione o CSS
</div>

Em **Cart settings → Custom CSS**:

```css theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
.checkout-gated {
  pointer-events: none !important;
  opacity: 0.5 !important;
}
```

`pointer-events: none` é o que realmente bloqueia o clique; a opacidade só mostra ao comprador o porquê.

<div id="step-3-test-it">
  ## Passo 3: teste
</div>

Na [pré-visualização](/pt/aftersell/cart/previewing-carts), confirme que:

* O botão de checkout fica esmaecido e não responde a cliques ao carregar.
* Marcar a caixa o habilita; desmarcá-la desativa o botão novamente.
* Os botões de pagamento expresso também estão bloqueados.
* Adicionar ou remover um item não reabilita o botão enquanto a caixa está desmarcada.

Esse último é a falha comum. Se o botão se reabilita sozinho após uma mudança no carrinho, o effect não está reexecutando. Verifique se `props.cart` está no array de dependências.

<div id="tracking-who-accepted">
  ## Registrando quem aceitou
</div>

A caixa de seleção é um estado só do navegador; ela nunca chega ao pedido. Para registrar o aceite, carimbe-o em cada linha como uma property no momento do adicionar ao carrinho:

```html theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
<input type="hidden" name="properties[_terms_version]" value="2026-01">
```

Adicione isso ao formulário de produto do seu tema. O Shopify lê `properties[...]` direto do formulário, então o valor chega ao pedido seja quem for que realize a adição: Aftersell, o tema ou outro app.

Uma property com prefixo `_` fica fora da linha visível ao comprador, mas ainda chega à Shopify, então aparece no pedido. Isso registra *qual* versão dos termos estava no ar, não que o comprador marcou a caixa.

<div id="things-to-get-right">
  ## Coisas para acertar
</div>

* **Mire apenas em classes `cart-external-*`.** As gêmeas `cart-internal-*` são o encanamento interno do carrinho, não um ponto de apoio para seu código. Veja [Custom CSS](/pt/aftersell/cart/custom-css).
* **Verifique se `shadowRoot` existe** antes de usá-lo. Ele é `undefined` até o carrinho inicializar.
* **O bloco não renderiza nada até o carrinho carregar**, então o botão de checkout nunca fica ativo por um instante antes de o bloqueio ser aplicado.
* **Um bloco React que lança um erro não renderiza nada** e o resto do carrinho continua, o que aqui significa um botão de checkout sem proteção. Teste na pré-visualização antes de publicar.

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

* **[Custom code blocks](/pt/aftersell/cart/custom-code-blocks)**: o modo React e suas props.
* **[Custom CSS](/pt/aftersell/cart/custom-css)**: a convenção de classes públicas.
* **[Events](/pt/aftersell/cart/sdk-events#checkout)**: o que o evento `checkout` pode e não pode fazer.
