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

# Wymagaj akceptacji regulaminu przed checkoutem

> Przypadek użycia Cart SDK, który dodaje checkbox regulaminu do koszyka Aftersell Cart i blokuje checkout, dopóki kupujący nie zaakceptuje warunków.

Dodaj checkbox pod przyciskiem checkoutu i powstrzymaj kupującego przed przejściem dalej, dopóki go nie zaznaczy. Przydatne dla akceptacji regulaminu, bramek wiekowych i potwierdzeń zamówień na zamówienie.

<Warning>
  **Zdarzenie `checkout` nie może anulować checkoutu.** Odpala się jako powiadomienie tuż przed nawigacją przeglądarki, więc zwrócenie `false` lub wywołanie `preventDefault` nic nie daje. Jedynym sposobem na bramkowanie checkoutu jest sprawienie, by przycisk przestał reagować na kliknięcia *zanim* zostanie naciśnięty — i to właśnie pokazuje ta strona.

  Traktuj to jako środek odstraszający w interfejsie, a nie gwarancję prawną. Zdeterminowany kupujący nadal może dotrzeć do checkoutu bezpośrednio.
</Warning>

<div id="how-it-works">
  ## Jak to działa
</div>

Trzy elementy:

1. **Blok Custom code** pod przyciskiem checkoutu renderuje checkbox.
2. Dopóki pole jest odznaczone, blok dodaje klasę do przycisków checkoutu i płatności ekspresowych koszyka poprzez [shadow root](/pl/aftersell/cart/sdk-overview#shadowroot).
3. **Custom CSS** sprawia, że ta klasa wyłącza kliknięcia.

<div id="step-1-add-the-checkbox-block">
  ## Krok 1: Dodaj blok z checkboxem
</div>

Dodaj [blok Custom code](/pl/aftersell/cart/custom-code-blocks) pod blokiem przycisku Checkout, przełącz go w tryb **React component** i wklej:

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

Kliknij **Compile**, a następnie włącz **"Use custom template"**. Blok nie renderuje niczego, dopóki tego nie zrobisz.

Zależność `props.cart` ma znaczenie: ponownie stosuje klasę po ponownym renderze koszyka, który w przeciwnym razie by ją wymazał.

<div id="step-2-add-the-css">
  ## Krok 2: Dodaj CSS
</div>

W **Cart settings → Custom CSS**:

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

To `pointer-events: none` faktycznie blokuje kliknięcie; przezroczystość jedynie pokazuje kupującemu dlaczego.

<div id="step-3-test-it">
  ## Krok 3: Przetestuj
</div>

W [podglądzie](/pl/aftersell/cart/previewing-carts) potwierdź, że:

* Przycisk checkoutu jest przygaszony i nie reaguje na kliknięcia przy załadowaniu.
* Zaznaczenie pola go włącza; odznaczenie ponownie wyłącza przycisk.
* Przyciski płatności ekspresowych też są bramkowane.
* Dodanie lub usunięcie produktu nie włącza ponownie przycisku, gdy pole jest odznaczone.

Ten ostatni punkt to typowa usterka. Jeśli przycisk sam się włącza po zmianie koszyka, efekt nie uruchamia się ponownie. Sprawdź, czy `props.cart` znajduje się w tablicy zależności.

<div id="tracking-who-accepted">
  ## Śledzenie, kto zaakceptował
</div>

Checkbox to stan wyłącznie w przeglądarce; nigdy nie trafia do zamówienia. Aby zapisać akceptację, oznacz każdą pozycję właściwością w momencie dodania do koszyka:

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

Dodaj to do formularza produktu w motywie. Shopify odczytuje `properties[...]` bezpośrednio z formularza, więc wartość dociera do zamówienia niezależnie od tego, kto wykonuje dodanie: Aftersell, motyw czy inna aplikacja.

Właściwość z przedrostkiem `_` pozostaje poza pozycją widoczną dla kupującego, ale nadal dociera do Shopify, więc pojawia się na zamówieniu. To zapisuje, *która* wersja regulaminu obowiązywała, a nie to, że kupujący zaznaczył pole.

<div id="things-to-get-right">
  ## Rzeczy, które trzeba zrobić dobrze
</div>

* **Celuj tylko w klasy `cart-external-*`.** Bliźniacze `cart-internal-*` to wewnętrzna maszyneria koszyka, a nie uchwyt dla Twojego kodu. Zobacz [Custom CSS](/pl/aftersell/cart/custom-css).
* **Sprawdzaj, czy `shadowRoot` istnieje**, zanim go użyjesz. Jest `undefined`, dopóki koszyk nie wystartuje.
* **Blok nie renderuje niczego przed załadowaniem koszyka**, więc przycisk checkoutu nigdy nie jest przez chwilę aktywny, zanim zadziała bramka.
* **Blok React, który rzuci błąd, nie renderuje niczego**, a reszta koszyka działa dalej, co tutaj oznacza niezabezpieczony przycisk checkoutu. Przetestuj w podglądzie przed publikacją.

<div id="where-to-go-next">
  ## Co dalej
</div>

* **[Bloki Custom code](/pl/aftersell/cart/custom-code-blocks)**: tryb React i jego propsy.
* **[Custom CSS](/pl/aftersell/cart/custom-css)**: konwencja publicznych klas.
* **[Events](/pl/aftersell/cart/sdk-events#checkout)**: co zdarzenie `checkout` może, a czego nie może.
