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

# Concepts

> The four building blocks of Payment Elements: elements, options, events, and theming.

Every element in Payment Elements is built on the same four concepts. Once you understand them, every element in the SDK feels familiar.

## The Overflow instance

You create one `Overflow` instance per page and keep it. The instance owns your publishable key, page-wide options (locale, theme, validation debounce), and every element you create. Do not construct a new `Overflow(...)` to change options at runtime — call `overflow.update({ ... })` on the existing instance instead.

```javascript theme={null}
const overflow = new Overflow('live_pub_...', {
  locale: 'en-US',
  appearance: { variables: { colorPrimary: '#0a3783' } },
});
```

Publishable keys use one of two prefixes:

* `live_pub_…` for production.
* `test_pub_…` for staging or test.

Call `overflow.destroy()` when you are done to tear down the instance and every element it created.

## Elements

An **element** is a self-contained payment UI component you mount into a host node on your page. You create one by calling a factory on your `Overflow` instance.

```javascript theme={null}
const card = overflow.card();
const bank = overflow.bank();
const applePay = overflow.applePay();
const checkout = overflow.checkout();
```

Every element exposes the same lifecycle:

```javascript theme={null}
const element = overflow.card(options);   // create
element.on('onChange', handler);            // subscribe to events
element.mount('#host');                     // render into your DOM
element.submit();                           // validate and emit onSubmit
element.unmount();                          // remove from DOM
element.destroy();                          // tear down and drop callbacks
```

Elements fall into a few categories:

* **Checkout**: a composite element that renders a full payment form. Use it as your primary integration.
* **Payment methods**: `card`, `bank`, `applePay`, `googlePay`. Mount standalone or nest inside Checkout.
* **Address elements**: `billingAddress`, `shippingAddress`, with optional autocomplete.
* **Contact elements**: `email`, `fullName`, `phone`, `companyName`.
* **Custom elements**: `text`, `number`, `select`, `checkbox` for arbitrary metadata.
* **Submit button**: a themed submit CTA (`submitButton`).

## Options

Every element factory accepts an options object with a uniform shape:

* **Top-level keys control behavior.** Examples: `splitMode` on `fullName`, `defaultCountry` on `phone`, `mode` on `bank`, `paymentMethods` on `checkout`.
* **`fields`** carries per-input customization: `label`, `placeholder`, `disabled`, `hidden`, and so on.
* **`BaseElementOptions`** are common to every element: `disabled`, `readOnly`, `id`, `ariaLabel`, `locale`, `required`, `validate?`. The cascade flows from the element to its fields; per-field overrides win.
* **Compound elements** (Checkout) nest the standalone options shape under each per-method key. What you configure standalone works the same way inside Checkout.

```javascript theme={null}
overflow.card({
  disabled: false,
  fields: {
    cardNumber: { label: 'Card number' },
    holderName: { label: 'Name on card', hidden: false },
    postalCode: { hidden: true },
  },
});
```

See [Options overview](/payment-elements/options/overview) for the shared knobs.

## Events

Every element emits six core events. Some elements emit more where it matters.

| Event                | Fires                                                                                                   |
| -------------------- | ------------------------------------------------------------------------------------------------------- |
| `onReady`            | Once, when the element is mounted and interactive.                                                      |
| `onChange`           | On every value or completeness change, with `{ value, complete, errors }`.                              |
| `onSubmit`           | After a successful `.submit()` call or wallet authorization, with the tokenized payload.                |
| `onError`            | When validation or a runtime action fails, with `{ elementType, code, message, fieldErrors?, cause? }`. |
| `onFocus` / `onBlur` | When focus enters or leaves the element.                                                                |

Wallets add `onClick` (for pre-sheet gating) and `onExit` (when the shopper dismisses the sheet). Non-wallet, non-button elements add `onEscapeKeyPressed`.

```javascript theme={null}
overflow.card()
  .on('onReady', () => console.log('ready'))
  .on('onChange', ({ complete, errors }) => {
    payButton.disabled = !complete;
  })
  .on('onSubmit', ({ value }) => forwardToServer(value))
  .on('onError', ({ code, message }) => console.error(code, message));
```

Subscribing to an unsupported event is rejected at compile time. See [Events overview](/payment-elements/events/overview).

## Theming

Pass design tokens on the `Overflow` instance. Every mounted element inherits them.

```javascript theme={null}
new Overflow('live_pub_...', {
  appearance: {
    size: 'normal',               // 'compact' | 'normal' | 'large'
    shadowSize: 'md',              // optional elevation preset
    variables: {
      colorPrimary: '#0a3783',
      colorBorder: '#ededed',
      borderRadius: '6px',
    },
  },
});
```

Every optional token has a documented default. Element-scoped overrides layer on top for standalone elements; sub-elements inside Checkout share the parent's theme. See [Theming](/payment-elements/theming/overview).

## `complete` vs `value`

Two concepts govern when a form is ready to submit:

* **`value`** is the current tokenized or typed data for an element. For payment methods it is `null` until submission produces a token; for input elements it is the current shopper input.
* **`complete`** is a boolean that flips `true` when the element passes validation. For a card element, that means every required field is filled and format-valid; for an email element, that means the value matches the email schema.

Use `complete` from `onChange` to gate your Pay button. Read `value` from `onSubmit` to forward to your server.

```javascript theme={null}
card.on('onChange', ({ complete }) => {
  payButton.disabled = !complete;
});

card.on('onSubmit', ({ value }) => {
  fetch('/api/authorize', { method: 'POST', body: JSON.stringify(value) });
});
```

## Standalone vs Checkout

You have two integration shapes:

* **Checkout** renders shopper contact, addresses, and payment methods in one mount. One `onSubmit` returns the whole payload. Use this when you want a turnkey form.
* **Standalone** mounts one element at a time. You gate your submit button on `onChange.complete` for each element, forward each `.onSubmit` payload yourself, and control the layout.

Start with Checkout unless you have a specific layout requirement it cannot meet. See [Compose standalone elements](/payment-elements/guides/compose-standalone-elements) for the standalone path.

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/payment-elements/quickstart">
    Mount your first element.
  </Card>

  <Card title="Checkout" icon="cart-shopping" href="/payment-elements/elements/checkout/introduction">
    Start with the composite element.
  </Card>

  <Card title="Elements" icon="grid" href="/payment-elements/elements/overview">
    Browse every element.
  </Card>

  <Card title="Events" icon="signal-stream" href="/payment-elements/events/overview">
    Full event reference.
  </Card>
</CardGroup>
