> ## Documentation Index
> Fetch the complete documentation index at: https://primer.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkout component

> Root component that initializes the SDK and provides checkout context.

## \<primer-checkout>

The root container for all Primer payment components. Initializes the SDK, manages checkout state, and provides context to child components. Use as a drop-in solution or customize fully.

## Quick reference

| | |
| - | - |
| **Properties** | `client-token` (required), `options`, `custom-styles`, `loader-disabled` |
| **Slot** | `main` |
| **Emits** | `primer:ready`, `primer:state-change`, `primer:methods-update`, `primer:payment-success`, `primer:payment-failure` |
| **Listens for** | `primer:card-submit`, `primer:vault-submit` |

***

## Examples

### Drop-in (minimal)

```html theme={"dark"}
<primer-checkout client-token="your-client-token"></primer-checkout>
```

Automatically displays all configured payment methods with default styling.

### With primer-main

```html theme={"dark"}
<primer-checkout client-token="your-client-token">
  <primer-main slot="main">
    <div slot="payments">
      <primer-payment-method type="PAYMENT_CARD"></primer-payment-method>
      <primer-payment-method type="PAYPAL"></primer-payment-method>
    </div>
    <div slot="checkout-complete">
      <h2>Thank you for your purchase!</h2>
    </div>
  </primer-main>
</primer-checkout>
```

### Fully custom

```html theme={"dark"}
<primer-checkout client-token="your-client-token">
  <div slot="main" id="custom-checkout">
    <h2>Select Payment Method</h2>
    <primer-payment-method type="PAYMENT_CARD"></primer-payment-method>
    <primer-error-message-container></primer-error-message-container>
  </div>
</primer-checkout>
```

> **Note:** Without `<primer-main>`, you must handle state changes via events.

### Custom content during loading

Render slotted content immediately, before the SDK is ready. Combine with `loader-disabled` to suppress the default loader and show your own UI until the `primer:ready` event fires. The slotted element must use `display: block` to override the default style that hides it during initialization.

```html theme={"dark"}
<primer-checkout client-token="your-client-token" loader-disabled>
  <div slot="main" style="display: block">
    <p>Loading checkout…</p>
    <primer-main></primer-main>
  </div>
</primer-checkout>
```

### With options

```javascript theme={"dark"}
// Set options via JavaScript (recommended)
const checkout = document.querySelector('primer-checkout');
checkout.setAttribute('client-token', 'your-client-token');
checkout.options = {
  locale: 'en-GB',
  card: {
    cardholderName: { required: true }
  }
};
```

> **Note:** Always set `options` via direct JavaScript assignment, not via `setAttribute()`. HTML attributes are only appropriate for simple string values like `client-token`.

### With custom styling

```html theme={"dark"}
<primer-checkout
  client-token="your-client-token"
  custom-styles='{"primerColorBrand":"#4a6cf7"}'
></primer-checkout>
```

### Dark theme

```html theme={"dark"}
<primer-checkout client-token="your-client-token" class="primer-dark-theme">
</primer-checkout>
```

***

## Properties

| Property | Attribute | Type | Default | Description |
| - | - | - | - | - |
| `clientToken` | `client-token` | `string` | `''` | **Required.** Client token from your backend |
| `options` | `options` | `object` | `{}` | SDK configuration options |
| `customStyles` | `custom-styles` | `string` | `''` | JSON string of CSS variables |
| `loaderDisabled` | `loader-disabled` | `boolean` | `false` | Disables the default loading spinner |

### Setting properties

```javascript theme={"dark"}
const checkout = document.querySelector('primer-checkout');

// Use setAttribute for string/boolean attributes
checkout.setAttribute('client-token', 'your-token');
checkout.setAttribute('custom-styles', JSON.stringify({ primerColorBrand: '#4a6cf7' }));
checkout.setAttribute('loader-disabled', 'true');

// Use direct assignment for options object
checkout.options = { locale: 'en-GB' };
```

> **Important:** Use `setAttribute()` for `client-token`, `custom-styles`, and `loader-disabled`. Use direct property assignment for `options`.

***

## Events

### Emitted events

| Event | When | Payload |
| - | - | - |
| `primer:ready` | SDK initialized | `PrimerJS` instance |
| `primer:state-change` | Checkout state changes | `{ isLoading, isProcessing, isSuccessful, paymentFailure, primerJsError }` |
| `primer:methods-update` | Payment methods loaded | `InitializedPaymentMethod[]` |
| `primer:payment-success` | Payment completed | `{ payment, paymentMethodType, timestamp }` |
| `primer:payment-failure` | Payment failed | `{ error, payment?, paymentMethodType, timestamp }` |

### Listened events

| Event | Purpose |
| - | - |
| `primer:card-submit` | Triggers card form submission |
| `primer:vault-submit` | Triggers vault payment submission |

### Event handling example

```javascript theme={"dark"}
const checkout = document.querySelector('primer-checkout');

checkout.addEventListener('primer:payment-success', (event) => {
  const { payment } = event.detail;
  window.location.href = `/confirmation?order=${payment.orderId}`;
});

checkout.addEventListener('primer:payment-failure', (event) => {
  const { error } = event.detail;
  console.error('Payment failed:', error.diagnosticsId);
});

checkout.addEventListener('primer:state-change', (event) => {
  const { isProcessing, isSuccessful, paymentFailure } = event.detail;
  // Update your UI based on state
});
```

***

## Slots

| Slot | Description |
| - | - |
| `main` | Main content area. Defaults to `<primer-main>` with all payment methods if not provided. Slotted content renders immediately, including before the SDK is ready — set `loader-disabled` to suppress the default loader and show your own UI until the `primer:ready` event fires. |

***

## CSS properties

Style via CSS variables or the `custom-styles` attribute:

```css theme={"dark"}
primer-checkout {
  --primer-color-brand: #4a6cf7;
  --primer-radius-base: 4px;
  --primer-typography-brand: 'Inter', sans-serif;
}
```

See [Styling Variables Reference](https://primer.io/docs/sdk/primer-checkout-web/styling-variables.md) for all available properties.

***

## Dependencies

This component is the parent for:

| Component | Purpose |
| - | - |
| [primer-main](https://primer.io/docs/sdk/primer-checkout-web/components/primer-main.md) | State management and slots |
| [primer-payment-method](https://primer.io/docs/sdk/primer-checkout-web/components/primer-payment-method.md) | Individual payment methods |
| [primer-card-form](https://primer.io/docs/sdk/primer-checkout-web/components/primer-card-form/primer-card-form.md) | Card payment form |
| [primer-vault-manager](https://primer.io/docs/sdk/primer-checkout-web/components/primer-vault-manager.md) | Saved payment methods |

***

## States

| State | Description |
| - | - |
| **Loading** | SDK initializing |
| **Ready** | SDK ready, payment methods available |
| **Processing** | Payment in progress |
| **Success** | Payment completed |
| **Failure** | Payment failed |
| **Error** | SDK initialization failed |

***

## Usage guidelines

### Do

* Provide a valid `client-token` from your backend
* Listen for `primer:payment-success` and `primer:payment-failure` to handle outcomes
* Handle both success and failure states
* Use `<primer-error-message-container>` for payment failures

### Don't

* Don't use multiple `<primer-checkout>` instances (single instance per page)
* Don't set `options` via `setAttribute()` — use direct assignment
* Don't call SDK methods before `primer:ready` fires

> [!WARNING]
>
> Only use a single `<primer-checkout>` instance per page. Multiple instances will cause initialization conflicts and unpredictable behavior.

***

## Localization

```javascript theme={"dark"}
checkout.options = { locale: 'fr-FR' };
```

See [Localization Guide](https://primer.io/docs/checkout/primer-checkout/configuration/localization.md) for supported locales. Falls back to `en-GB` if unsupported.

> **Note:** Only left-to-right (LTR) languages are currently supported.

***

## Content guidelines

### Loading state

| Do | Don't |
| - | - |
| Show a spinner or skeleton without text | "Loading checkout…" |
| Keep the container height stable to prevent layout shift | Collapse the container to zero height |

### Error messages (default experience)

| Do | Don't |
| - | - |
| Let the SDK display its built-in, localized messages | Override SDK errors with generic text like "Something went wrong" |
| Supplement with a retry prompt: "Please try again or use a different method" | Show raw error codes to customers |

***

## See also

> [card] [SDK options reference](https://primer.io/docs/sdk/primer-checkout-web/sdk-options-reference.md)
>
> All configuration options

> [card] [Events guide](https://primer.io/docs/checkout/primer-checkout/configuration/events.md)
>
> Event handling patterns

> [card] [Styling variables](https://primer.io/docs/sdk/primer-checkout-web/styling-variables.md)
>
> CSS customization

> [card] [Installation](https://primer.io/docs/checkout/primer-checkout/installation.md)
>
> Getting started


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.