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

# Events

> The typed event surface every element emits.

Every element exposes the same six core events: `onReady`, `onChange`, `onSubmit`, `onError`, `onFocus`, and `onBlur`. Non-wallet elements additionally expose `onEscapeKeyPressed`. Wallet elements (`applePay`, `googlePay`) and Checkout expose `onClick`. Wallet elements, `bank`, and Checkout expose `onExit`.

## Subscribing

Every element handle exposes `.on(name, handler)` returning the same handle for chaining:

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

card
  .on('onReady', ({ elementType }) => { /* element is interactive */ })
  .on('onChange', ({ complete, value, errors }) => {
    submitBtn.disabled = !complete;
  })
  .on('onSubmit', ({ value }) => sendToServer(value))
  .on('onError', ({ code, message, fieldErrors }) => {
    // switch (code); see Error codes.
  })
  .on('onFocus', ({ elementType }) => { /* focus entered */ })
  .on('onBlur', ({ elementType }) => { /* focus left */ })
  .on('onEscapeKeyPressed', ({ elementType }) => { /* shopper pressed Escape */ })
  .mount('#card');
```

Every payload includes `elementType`. Payloads are discriminated by `elementType`, so a single handler that receives an event from any element narrows correctly.

## Event matrix

| Event                                                                  | All elements | Wallets                                    | Checkout                         | Bank                                     |
| ---------------------------------------------------------------------- | ------------ | ------------------------------------------ | -------------------------------- | ---------------------------------------- |
| [`onReady`](/payment-elements/events/on-ready)                         | Yes          | Deferred until availability probe resolves | Yes                              | Yes                                      |
| [`onChange`](/payment-elements/events/on-change)                       | Yes          | Available and unavailability signals       | Yes, with method availability    | Yes                                      |
| [`onSubmit`](/payment-elements/events/on-submit)                       | Yes          | Yes (sheet-driven)                         | Yes                              | Yes                                      |
| [`onError`](/payment-elements/events/on-error)                         | Yes          | `wallet_failed`                            | All codes                        | `plaid_link_failed`, `validation_failed` |
| [`onFocus` / `onBlur`](/payment-elements/events/on-focus-blur)         | Yes          | Best effort                                | Yes                              | Manual mode only                         |
| [`onEscapeKeyPressed`](/payment-elements/events/on-escape-key-pressed) | Yes          | Not emitted                                | Yes                              | Manual mode only                         |
| [`onClick`](/payment-elements/events/on-click)                         | Not emitted  | Yes                                        | Yes (wallet tabs)                | Not emitted                              |
| [`onExit`](/payment-elements/events/on-exit)                           | Not emitted  | Yes                                        | Yes (wallet or bank sub-methods) | Address-lookup mode only                 |

Elements that do not emit a given event omit the key from their event map, so subscribing is a TypeScript error and a runtime no-op (with a console warning).

## Payload envelope

Every payload extends a base:

```typescript theme={null}
type OverflowEventBase<T> = { elementType: T };
```

Per-event extras layer on top:

* `onChange` adds `complete`, `value`, and (optionally) `errors`. Wallets and Checkout add extras (device availability, method availability).
* `onSubmit` adds `value` (non-null by construction).
* `onError` adds `code`, `message`, and (optionally) `fieldErrors` and `cause`.
* `onClick` (wallets and Checkout) adds `preventDefault`, `resolve`, `reject`. Checkout additionally adds `paymentMethod`.
* `onExit` (bank and Checkout) adds Plaid metadata or the `paymentMethod` discriminator.

## `complete` versus `value !== null` versus `errors.length === 0`

These three look interchangeable but are not:

|                                       | `complete`       | `value !== null`   | `errors.length === 0`         |
| ------------------------------------- | ---------------- | ------------------ | ----------------------------- |
| Empty input                           | `false`          | `false`            | `true` (no errors when empty) |
| Mid-typing invalid                    | `false`          | varies per element | `false`                       |
| Valid input                           | `true`           | `true`             | `true`                        |
| Wallet `available: true`, no auth yet | `false` (always) | `false` (always)   | `true`                        |

Always drive submit-button state off `complete`. It is the only flag whose semantics are consistent across every element, including wallets and Checkout.

## See also

* [`onReady`](/payment-elements/events/on-ready)
* [`onChange`](/payment-elements/events/on-change)
* [`onSubmit`](/payment-elements/events/on-submit)
* [`onError`](/payment-elements/events/on-error) · [Error codes](/payment-elements/events/error-codes) · [Field errors](/payment-elements/events/field-errors)
* [`onFocus` and `onBlur`](/payment-elements/events/on-focus-blur) · [`onEscapeKeyPressed`](/payment-elements/events/on-escape-key-pressed)
* [`onClick`](/payment-elements/events/on-click) · [`onExit`](/payment-elements/events/on-exit)
