<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)
<primer-checkout client-token="your-client-token"></primer-checkout>
Automatically displays all configured payment methods with default styling.
With primer-main
<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
<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.
With Options
// 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
<primer-checkout
client-token="your-client-token"
custom-styles='{"primerColorBrand":"#4a6cf7"}'
></primer-checkout>
Dark Theme
<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
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 | { isProcessing, isSuccessful, paymentFailure, primerJsError } |
primer:methods-update | Payment methods loaded | Payment methods collection |
primer:payment-success | Payment completed | { payment, paymentMethodType } |
primer:payment-failure | Payment failed | { error, paymentMethodType } |
Listened Events
| Event | Purpose |
|---|
primer:card-submit | Triggers card form submission |
primer:vault-submit | Triggers vault payment submission |
Event Handling Example
const checkout = document.querySelector('primer-checkout');
checkout.addEventListener('primer:ready', (event) => {
const primer = event.detail;
primer.onPaymentSuccess = ({ payment }) => {
window.location.href = `/confirmation?order=${payment.orderId}`;
};
primer.onPaymentFailure = ({ error }) => {
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. |
CSS Properties
Style via CSS variables or the custom-styles attribute:
primer-checkout {
--primer-color-brand: #4a6cf7;
--primer-radius-base: 4px;
--primer-typography-brand: 'Inter', sans-serif;
}
See Styling Variables Reference for all available properties.
Dependencies
This component is the parent for:
| Component | Purpose |
|---|
| primer-main | State management and slots |
| primer-payment-method | Individual payment methods |
| primer-card-form | Card payment form |
| primer-vault-manager | 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
- Provide a valid
client-token from your backend
- Listen for
primer:ready before calling SDK methods
- 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
Only use a single <primer-checkout> instance per page. Multiple instances will cause initialization conflicts and unpredictable behavior.
Localization
checkout.options = { locale: 'fr-FR' };
See Localization Guide 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 |