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

# Events reference

> Complete API reference for all Primer SDK events, instance methods, and type definitions

export const EVENT_LIFECYCLE_PHASES = [{
  name: 'Initialization',
  description: 'SDK loads, connects to the session, and signals readiness.',
  events: [{
    name: 'primer:ready',
    direction: 'sdk',
    payload: 'PrimerJS instance'
  }, {
    name: 'primer:methods-update',
    direction: 'sdk',
    payload: 'available methods'
  }, {
    name: 'primer:vault-methods-update',
    direction: 'sdk',
    payload: 'saved methods'
  }],
  action: 'Access SDK methods and pre-fill fields via PrimerJS'
}, {
  name: 'User Interaction',
  description: 'User enters card details; SDK detects BIN data and card network in real time.',
  events: [{
    name: 'primer:bin-data-loading-change',
    direction: 'sdk',
    payload: 'loading: true'
  }, {
    name: 'primer:bin-data-available',
    direction: 'sdk',
    payload: 'BIN data + network'
  }, {
    name: 'primer:bin-data-loading-change',
    direction: 'sdk',
    payload: 'loading: false'
  }],
  action: 'Update UI with card brand logo and issuer info'
}, {
  name: 'Payment Processing',
  description: 'User submits; SDK creates the payment and communicates with the server.',
  events: [{
    name: 'primer:card-submit',
    direction: 'app',
    payload: '(or button click)'
  }, {
    name: 'primer:payment-start',
    direction: 'sdk',
    payload: 'intercept with preventDefault()'
  }, {
    name: 'primer:state-change',
    direction: 'sdk',
    payload: 'isProcessing: true'
  }],
  action: 'Show spinner, disable submit button'
}, {
  name: 'Outcome',
  description: 'Server responds; SDK dispatches success or failure.',
  branches: [{
    type: 'success',
    label: 'Success',
    events: ['primer:payment-success', 'state-change → isSuccessful: true']
  }, {
    type: 'failure',
    label: 'Failure',
    events: ['primer:payment-failure', 'state-change → paymentFailure: {...}']
  }],
  action: 'Handle primer:payment-success to redirect, or show error'
}];

export const PhaseTimeline = ({phases}) => {
  const phaseColors = {
    1: {
      border: '#3b82f6',
      text: '#3b82f6'
    },
    2: {
      border: '#8b5cf6',
      text: '#8b5cf6'
    },
    3: {
      border: '#f59e0b',
      text: '#f59e0b'
    },
    4: {
      border: '#10b981',
      text: '#10b981'
    }
  };
  const directionStyles = {
    sdk: {
      color: '#3b82f6',
      label: 'SDK'
    },
    app: {
      color: '#10b981',
      label: 'APP'
    }
  };
  return <div style={{
    display: 'flex',
    flexDirection: 'column',
    gap: '0',
    position: 'relative',
    paddingLeft: '40px'
  }}>
      <div style={{
    position: 'absolute',
    left: '18px',
    top: '18px',
    bottom: '18px',
    width: '2px',
    backgroundColor: 'var(--tw-prose-hr, #e5e7eb)'
  }} />

      {phases.map((phase, phaseIndex) => {
    const colors = phaseColors[phaseIndex + 1] || phaseColors[4];
    const isOutcome = phase.branches && phase.branches.length > 0;
    return <div key={phase.name} style={{
      position: 'relative',
      paddingBottom: '24px'
    }}>
            <div className="phase-timeline-circle" style={{
      position: 'absolute',
      left: '-40px',
      top: '0',
      width: '36px',
      height: '36px',
      borderRadius: '50%',
      border: '2px solid ' + colors.border,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      fontWeight: '600',
      fontSize: '14px',
      color: colors.text,
      zIndex: 1
    }}>
              {phaseIndex + 1}
            </div>

            <div style={{
      marginLeft: '16px'
    }}>
              <div style={{
      fontWeight: '600',
      fontSize: '16px',
      color: 'var(--tw-prose-headings, #111827)',
      marginBottom: '4px'
    }}>
                {phase.name}
              </div>

              {phase.description && <div style={{
      fontSize: '14px',
      color: 'var(--tw-prose-body, #6b7280)',
      marginBottom: '16px'
    }}>
                  {phase.description}
                </div>}

              {!isOutcome && phase.events && <div style={{
      display: 'flex',
      flexDirection: 'column',
      gap: '8px',
      marginBottom: phase.action ? '12px' : '0'
    }}>
                  {phase.events.map(event => {
      const dir = directionStyles[event.direction] || directionStyles.sdk;
      return <div key={event.name} style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'space-between',
        padding: '10px 14px',
        border: '1px solid var(--tw-prose-hr, #e5e7eb)',
        borderRadius: '6px',
        gap: '12px'
      }}>
                        <div style={{
        display: 'flex',
        alignItems: 'center',
        gap: '10px'
      }}>
                          <span style={{
        display: 'inline-flex',
        alignItems: 'center',
        gap: '4px',
        padding: '2px 8px',
        border: '1px solid ' + dir.color,
        color: dir.color,
        borderRadius: '4px',
        fontSize: '11px',
        fontWeight: '600',
        whiteSpace: 'nowrap'
      }}>
                            {dir.label} {'→'}
                          </span>
                          <code style={{
        fontFamily: 'var(--font-mono, monospace)',
        fontSize: '13px',
        fontWeight: '500',
        color: 'var(--tw-prose-code, #111827)'
      }}>
                            {event.name}
                          </code>
                        </div>
                        {event.payload && <span style={{
        fontSize: '12px',
        color: 'var(--tw-prose-body, #9ca3af)',
        whiteSpace: 'nowrap'
      }}>
                            {event.payload}
                          </span>}
                      </div>;
    })}
                </div>}

              {isOutcome && <div style={{
      display: 'grid',
      gridTemplateColumns: 'repeat(2, 1fr)',
      gap: '12px',
      marginBottom: phase.action ? '12px' : '0'
    }}>
                  {phase.branches.map(branch => <div key={branch.label} style={{
      padding: '14px',
      border: '1px solid ' + (branch.type === 'success' ? '#10b981' : '#ef4444'),
      borderRadius: '6px'
    }}>
                      <div style={{
      fontWeight: '600',
      fontSize: '12px',
      textTransform: 'uppercase',
      letterSpacing: '0.05em',
      color: branch.type === 'success' ? '#10b981' : '#ef4444',
      marginBottom: '8px'
    }}>
                        {branch.label}
                      </div>
                      <div style={{
      display: 'flex',
      flexDirection: 'column',
      gap: '4px',
      fontFamily: 'var(--font-mono, monospace)',
      fontSize: '13px',
      color: 'var(--tw-prose-body, #374151)'
    }}>
                        {branch.events.map(e => <div key={e}>{e}</div>)}
                      </div>
                    </div>)}
                </div>}

              {phase.action && <div style={{
      padding: '10px 14px',
      borderLeft: '3px solid var(--tw-prose-hr, #e5e7eb)',
      fontSize: '13px',
      color: 'var(--tw-prose-body, #6b7280)'
    }}>
                  {phase.action}
                </div>}
            </div>
          </div>;
  })}
    </div>;
};

This page is the complete API reference for every event and instance method exposed by Primer Checkout. Each entry documents the event name, when it dispatches, its payload shape, and the TypeScript types involved.

<Info>
  For integration guidance — where to listen, which events to combine, and real-world implementation patterns — see the [Events Guide](/checkout/primer-checkout/configuration/events).
</Info>

## Quick navigation

| Category                                                | Items                                                                                                     |
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| [Initialization Events](#initialization-events)         | `primer:ready`, `primer:methods-update`                                                                   |
| [State Events](#state-events)                           | `primer:state-change`                                                                                     |
| [Card Form Events](#card-form-events)                   | `primer:bin-data-available`, `primer:bin-data-loading-change`, `primer:card-success`, `primer:card-error` |
| [Payment Events](#payment-events)                       | `primer:payment-start`, `primer:payment-success`, `primer:payment-failure`, `primer:payment-cancel`       |
| [Vault Events](#vault-events)                           | `primer:vault-methods-update`, `primer:vault-selection-change`, `primer:show-other-payments-toggled`      |
| [Triggerable Events](#triggerable-events)               | `primer:card-submit`, `primer:vault-submit`, `primer:show-other-payments-toggle`                          |
| [PrimerJS Instance Methods](#primerjs-instance-methods) | `refreshSession()`, `getPaymentMethods()`, `setCardholderName()`, `vault.*`                               |
| [Type Definitions](#type-definitions)                   | All TypeScript interfaces                                                                                 |

***

## Event lifecycle

<PhaseTimeline phases={EVENT_LIFECYCLE_PHASES} />

***

## DOM events

All Primer events are [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) objects dispatched with `bubbles: true` and `composed: true`, allowing them to propagate through shadow DOM boundaries.

***

## Initialization events

### primer:ready

Dispatched once when the SDK is fully initialized.

**Payload:** [`PrimerJS`](#primerjs-instance-methods) instance

The `PrimerJS` instance is the primary interface for invoking SDK methods. See [PrimerJS Instance Methods](#primerjs-instance-methods) for the full surface.

```javascript theme={"dark"}
checkout.addEventListener('primer:ready', (event) => {
  const primer = event.detail; // PrimerJS instance
});
```

***

### primer:methods-update

Dispatched when available payment methods are loaded. Also re-dispatched after `refreshSession()`.

**Payload:** [`InitializedPaymentMethod[]`](#initializedpaymentmethod)

The payload is an array of available payment methods.

```javascript theme={"dark"}
checkout.addEventListener('primer:methods-update', (event) => {
  const methods = event.detail; // InitializedPaymentMethod[]
  
  methods.forEach(method => {
    console.log(method.type); // e.g., 'PAYMENT_CARD', 'APPLE_PAY'
  });
});
```

***

## State events

### primer:state-change

Dispatched when SDK state changes during the payment lifecycle. Fires multiple times during a single payment flow.

**Payload:** [`SdkState`](#sdkstate)

| Property         | Type                                           | Description                              |
| ---------------- | ---------------------------------------------- | ---------------------------------------- |
| `isLoading`      | `boolean`                                      | SDK is loading resources                 |
| `isProcessing`   | `boolean`                                      | Payment is in progress                   |
| `isSuccessful`   | `boolean`                                      | Payment succeeded                        |
| `primerJsError`  | `Error \| null`                                | SDK-level error (network, configuration) |
| `paymentFailure` | [`PaymentFailure`](#paymentfailure) ` \| null` | Payment failure details                  |

```javascript theme={"dark"}
checkout.addEventListener('primer:state-change', (event) => {
  const state = event.detail; // SdkState
});
```

***

## Card form events

### primer:bin-data-available

Dispatched when BIN data is detected from user input in the card number field. Provides card network information, co-badged network alternatives, and additional issuer details when available.

**Payload:** [`BinDataAvailableEvent`](#bindataavailableevent)

| Property       | Type                                                | Description                                                                                        |
| -------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `preferred`    | [`BinDataDetails`](#bindatadetails) ` \| undefined` | Recommended network based on `orderedAllowedCardNetworks`, or `undefined` if no network is allowed |
| `alternatives` | [`BinDataDetails[]`](#bindatadetails)               | All detected networks excluding preferred, including disallowed ones                               |
| `status`       | `'complete' \| 'partial'`                           | `complete` when full BIN data is available (8+ digits), `partial` for local-only detection         |
| `firstDigits`  | `string \| undefined`                               | The first digits (BIN prefix) of the card number, when available                                   |

```javascript theme={"dark"}
checkout.addEventListener('primer:bin-data-available', (event) => {
  const { preferred, alternatives, status } = event.detail; // BinDataAvailableEvent
});
```

***

### primer:bin-data-loading-change

Dispatched when BIN data retrieval starts or finishes. Use this to show a loading indicator while card information is being fetched from Primer's servers.

**Payload:** [`BinDataLoadingChangeEvent`](#bindataloadingchangeevent)

| Property  | Type      | Description                                                      |
| --------- | --------- | ---------------------------------------------------------------- |
| `loading` | `boolean` | `true` when BIN data retrieval starts, `false` when it completes |

```javascript theme={"dark"}
checkout.addEventListener('primer:bin-data-loading-change', (event) => {
  const { loading } = event.detail; // BinDataLoadingChangeEvent
});
```

***

### primer:card-success

Dispatched when card form submission succeeds.

**Payload:** [`CardSubmitSuccessPayload`](#cardsubmitsuccesspayload)

| Property           | Type      | Description          |
| ------------------ | --------- | -------------------- |
| `result.success`   | `boolean` | Submission succeeded |
| `result.token`     | `string`  | Payment token        |
| `result.paymentId` | `string`  | Payment ID           |

```javascript theme={"dark"}
checkout.addEventListener('primer:card-success', (event) => {
  const payload = event.detail; // CardSubmitSuccessPayload
});
```

***

### primer:card-error

Dispatched when card form validation fails on submission.

**Payload:** [`CardSubmitErrorsPayload`](#cardsubmiterrorspayload)

| Property | Type                                              | Description                              |
| -------- | ------------------------------------------------- | ---------------------------------------- |
| `errors` | [`InputValidationError[]`](#inputvalidationerror) | Validation errors for each invalid field |

```javascript theme={"dark"}
checkout.addEventListener('primer:card-error', (event) => {
  const payload = event.detail; // CardSubmitErrorsPayload
});
```

***

## Payment events

### primer:payment-start

Dispatched when payment creation begins. Use `event.preventDefault()` to intercept the payment flow for validation.

**Payload:** [`PaymentStartData`](#paymentstartdata)

| Property                  | Type              | Description                                                     |
| ------------------------- | ----------------- | --------------------------------------------------------------- |
| `paymentMethodType`       | `string`          | Payment method being used (e.g., `"PAYMENT_CARD"`)              |
| `abortPaymentCreation`    | `() => void`      | Call to cancel payment creation                                 |
| `continuePaymentCreation` | `(data?) => void` | Call to proceed with payment (optionally with `idempotencyKey`) |
| `timestamp`               | `number`          | Unix timestamp (seconds)                                        |

```javascript theme={"dark"}
checkout.addEventListener('primer:payment-start', (event) => {
  const { paymentMethodType, continuePaymentCreation, abortPaymentCreation } = event.detail;
  
  // Intercept payment for validation
  event.preventDefault();
  
  if (termsAccepted) {
    continuePaymentCreation();
  } else {
    abortPaymentCreation();
  }
});
```

<Warning>
  If you call `event.preventDefault()`, you must call either `continuePaymentCreation()` or `abortPaymentCreation()`. If neither is called, the payment will hang indefinitely.
</Warning>

***

### primer:payment-success

Dispatched when payment completes successfully.

**Payload:** [`PaymentSuccessData`](#paymentsuccessdata)

| Property            | Type                                | Description                           |
| ------------------- | ----------------------------------- | ------------------------------------- |
| `payment`           | [`PaymentSummary`](#paymentsummary) | PII-filtered payment data             |
| `paymentMethodType` | `string`                            | e.g., `"PAYMENT_CARD"`, `"APPLE_PAY"` |
| `timestamp`         | `number`                            | Unix timestamp (seconds)              |

```javascript theme={"dark"}
checkout.addEventListener('primer:payment-success', (event) => {
  const { payment, paymentMethodType } = event.detail;
  console.log('Payment ID:', payment.id);
  window.location.href = '/confirmation';
});
```

***

### primer:payment-failure

Dispatched when payment fails.

**Payload:** [`PaymentFailureData`](#paymentfailuredata)

| Property            | Type                                                                                                | Description                                   |
| ------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| `error`             | `{ code: string; message: string; diagnosticsId?: string \| null; data?: Record<string, unknown> }` | Structured error information                  |
| `payment`           | [`PaymentSummary`](#paymentsummary) ` \| undefined`                                                 | Payment data, if available at time of failure |
| `paymentMethodType` | `string`                                                                                            | Payment method used                           |
| `timestamp`         | `number`                                                                                            | Unix timestamp (seconds)                      |

```javascript theme={"dark"}
checkout.addEventListener('primer:payment-failure', (event) => {
  const { error, payment } = event.detail;
  console.error('Payment failed:', error.message);
});
```

***

### primer:payment-cancel

Dispatched when a payment is cancelled by the user (e.g., dismissing Apple Pay or closing a payment popup).

**Payload:** [`PaymentCancelData`](#paymentcanceldata)

| Property            | Type                                                | Description                                                                    |
| ------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------ |
| `paymentMethodType` | `string`                                            | Payment method that was being used                                             |
| `payment`           | [`PaymentSummary`](#paymentsummary) ` \| undefined` | Payment data, available when a payment was already created before cancellation |
| `timestamp`         | `number`                                            | Unix timestamp (seconds)                                                       |

```javascript theme={"dark"}
document.addEventListener('primer:payment-cancel', (event) => {
  const { paymentMethodType, payment } = event.detail; // PaymentCancelData
});
```

***

## Vault Events

### primer:vault-methods-update

Dispatched when vaulted payment methods are loaded or updated.

**Payload:** [`VaultedMethodsUpdateData`](#vaultedmethodsupdatedata)

| Property          | Type                                                            | Description                      |
| ----------------- | --------------------------------------------------------------- | -------------------------------- |
| `vaultedPayments` | [`VaultedPaymentMethodSummary[]`](#vaultedpaymentmethodsummary) | Array of vaulted methods         |
| `cvvRecapture`    | `boolean`                                                       | Whether CVV re-entry is required |
| `timestamp`       | `number`                                                        | Unix timestamp (seconds)         |

```javascript theme={"dark"}
checkout.addEventListener('primer:vault-methods-update', (event) => {
  const { vaultedPayments, cvvRecapture } = event.detail;
  
  vaultedPayments.forEach(method => {
    console.log(method.paymentInstrumentData?.last4Digits);
  });
});
```

***

### primer:vault-selection-change

Dispatched when a vaulted payment method is selected or deselected.

**Payload:** [`VaultSelectionChangeData`](#vaultselectionchangedata)

| Property          | Type             | Description                                        |
| ----------------- | ---------------- | -------------------------------------------------- |
| `paymentMethodId` | `string \| null` | ID of the selected method, or `null` if deselected |
| `timestamp`       | `number`         | Unix timestamp (seconds)                           |

```javascript theme={"dark"}
checkout.addEventListener('primer:vault-selection-change', (event) => {
  const { paymentMethodId } = event.detail;
});
```

***

### primer:show-other-payments-toggled

Dispatched when the "show other payments" toggle state changes.

**Payload:** [`ShowOtherPaymentsToggledPayload`](#showotherpaymentstoggledpayload)

| Property   | Type      | Description          |
| ---------- | --------- | -------------------- |
| `expanded` | `boolean` | Current toggle state |

```javascript theme={"dark"}
checkout.addEventListener('primer:show-other-payments-toggled', (event) => {
  const { expanded } = event.detail;
});
```

***

## Triggerable events

These events can be dispatched by your code to control the SDK. All triggerable events must be dispatched with `bubbles: true` and `composed: true` to cross shadow DOM boundaries.

### primer:card-submit

Triggers card form submission programmatically.

```javascript theme={"dark"}
document.dispatchEvent(new CustomEvent('primer:card-submit', {
  bubbles: true,
  composed: true,
}));
```

***

### primer:vault-submit

Triggers vault payment submission programmatically.

```javascript theme={"dark"}
document.dispatchEvent(new CustomEvent('primer:vault-submit', {
  bubbles: true,
  composed: true,
}));
```

***

### primer:show-other-payments-toggle

Toggles the "other payment methods" section.

```javascript theme={"dark"}
document.dispatchEvent(new CustomEvent('primer:show-other-payments-toggle', {
  bubbles: true,
  composed: true,
}));
```

***

## PrimerJS instance methods

The `PrimerJS` instance is received from the `primer:ready` event.

### refreshSession()

Synchronizes the client-side SDK with server-side session updates. Triggers a new `primer:methods-update` event.

| Parameter   | Type            | Description                    |
| ----------- | --------------- | ------------------------------ |
| *(none)*    | —               | —                              |
| **Returns** | `Promise<void>` | Resolves when sync is complete |

```javascript theme={"dark"}
await primer.refreshSession();
```

***

### getPaymentMethods()

Returns the cached list of available payment methods.

| Parameter   | Type                  | Description               |
| ----------- | --------------------- | ------------------------- |
| *(none)*    | —                     | —                         |
| **Returns** | `PaymentMethodInfo[]` | Available payment methods |

```javascript theme={"dark"}
const methods = primer.getPaymentMethods();
```

***

### setCardholderName()

Sets the cardholder name field programmatically. Must be called after `primer:ready`.

| Parameter   | Type     | Description     |
| ----------- | -------- | --------------- |
| `name`      | `string` | Cardholder name |
| **Returns** | `void`   | —               |

```javascript theme={"dark"}
primer.setCardholderName('Jane Doe');
```

***

## Vault API

### vault.createCvvInput()

Creates a CVV input element for CVV recapture in headless mode.

| Parameter             | Type                        | Description                            |
| --------------------- | --------------------------- | -------------------------------------- |
| `options.cardNetwork` | `string`                    | Card network (e.g. `'VISA'`)           |
| `options.container`   | `string`                    | CSS selector for the container element |
| `options.placeholder` | `string`                    | Placeholder text                       |
| **Returns**           | `Promise<CvvInputInstance>` | The created CVV input                  |

```javascript theme={"dark"}
const cvvInput = await primer.vault.createCvvInput({
  cardNetwork: 'VISA',
  container: '#cvv-container',
  placeholder: 'CVV',
});
```

***

### vault.startPayment()

Initiates payment with the selected vaulted method.

| Parameter         | Type            | Description                                      |
| ----------------- | --------------- | ------------------------------------------------ |
| `paymentMethodId` | `string`        | ID of the vaulted payment method                 |
| `options`         | `object`        | Optional payment options                         |
| `options.cvv`     | `string`        | CVV value for card payments requiring re-capture |
| **Returns**       | `Promise<void>` | Resolves when payment flow is initiated          |

```javascript theme={"dark"}
// Basic usage
await primer.vault.startPayment(paymentMethodId);

// With CVV for cards requiring re-capture
await primer.vault.startPayment(paymentMethodId, { cvv: '123' });
```

***

### vault.delete()

Deletes a vaulted payment method.

| Parameter         | Type            | Description                        |
| ----------------- | --------------- | ---------------------------------- |
| `paymentMethodId` | `string`        | ID of the vaulted payment method   |
| **Returns**       | `Promise<void>` | Resolves when deletion is complete |

```javascript theme={"dark"}
await primer.vault.delete(paymentMethodId);
```

For a complete headless vault implementation walkthrough, see the [Headless Vault Guide](/sdk/primer-checkout-web/components/primer-vault-manager#headless-vault-implementation).

***

## Type definitions

### PaymentStartData

```typescript theme={"dark"}
interface PaymentStartData {
  paymentMethodType: string;
  abortPaymentCreation: () => void;
  continuePaymentCreation: (data?: { idempotencyKey?: string }) => void;
  timestamp: number;
}
```

### PaymentSuccessData

```typescript theme={"dark"}
interface PaymentSuccessData {
  payment: PaymentSummary;
  paymentMethodType?: string;
  timestamp: number;
}
```

### PaymentFailureData

```typescript theme={"dark"}
interface PaymentFailureData {
  error: {
    code: string;
    message: string;
    diagnosticsId?: string | null;
    data?: Record<string, unknown>;
  };
  payment?: PaymentSummary;
  paymentMethodType?: string;
  timestamp: number;
}
```

### PaymentCancelData

```typescript theme={"dark"}
interface PaymentCancelData {
  paymentMethodType: string;
  payment?: PaymentSummary;
  timestamp: number;
}
```

### PaymentSummary

A PCI-compliant payment summary with minimal PII exposure. Contains payment identifiers and filtered payment method data.

```typescript theme={"dark"}
interface PaymentSummary {
  /** Payment ID from Primer API */
  id: string;
  /** Order ID/reference from merchant */
  orderId: string;
  /** Filtered payment method data (only safe fields exposed) */
  paymentMethodData?: {
    /** Payment method type (e.g., "PAYMENT_CARD", "PAYPAL") */
    paymentMethodType?: string;
    /** Last 4 digits of card (cards only) */
    last4Digits?: string;
    /** Card network (e.g., "VISA", "MASTERCARD") - cards only */
    network?: string;
    /** Last 4 digits of account number (ACH only) */
    accountNumberLastFourDigits?: string;
    /** Bank name (ACH only) */
    bankName?: string;
  };
}
```

### PaymentFailure

```typescript theme={"dark"}
interface PaymentFailure {
  code: string;
  message: string;
  diagnosticsId?: string | null;
  data?: Record<string, unknown>;
}
```

### SdkState

```typescript theme={"dark"}
interface SdkState {
  isSuccessful: boolean;
  isProcessing: boolean;
  primerJsError: Error | null;
  isLoading: boolean;
  paymentFailure: PaymentFailure | null;
}
```

### BinDataAvailableEvent

```typescript theme={"dark"}
interface BinDataAvailableEvent {
  /** Recommended network based on orderedAllowedCardNetworks */
  preferred?: BinDataDetails;
  /** All detected networks excluding preferred */
  alternatives: BinDataDetails[];
  /** 'complete' when full BIN data is available, 'partial' for local-only detection */
  status: 'complete' | 'partial';
  /** First digits (BIN prefix) of the card number */
  firstDigits?: string;
}
```

### BinDataDetails

```typescript theme={"dark"}
interface BinDataDetails {
  /** Human-readable name for the card network */
  displayName: string;
  /** Card network identifier in Primer's systems */
  network: string;
  /** Whether the network is allowed per orderedAllowedCardNetworks */
  allowed: boolean;
  /** ISO 3166-1 alpha-2 country code of the card issuer */
  issuerCountryCode?: string;
  /** Name of the card issuer (e.g., bank name) */
  issuerName?: string;
  /** Account funding type (e.g., "CREDIT", "DEBIT", "PREPAID") */
  accountFundingType?: string;
  /** Whether a prepaid card is reloadable */
  prepaidReloadableIndicator?: string;
  /** Usage type of the card product (e.g., "CONSUMER", "COMMERCIAL") */
  productUsageType?: string;
  /** Product code assigned by the card network */
  productCode?: string;
  /** Product name assigned by the card network (e.g., "Visa Signature") */
  productName?: string;
  /** ISO 4217 currency code associated with the card issuer */
  issuerCurrencyCode?: string;
  /** Regional restrictions that apply to the card */
  regionalRestriction?: string;
  /** Type of account number (e.g., "PAN", "TOKEN") */
  accountNumberType?: string;
}
```

### BinDataLoadingChangeEvent

```typescript theme={"dark"}
interface BinDataLoadingChangeEvent {
  /** true when BIN data retrieval starts, false when it completes */
  loading: boolean;
}
```

### CardSubmitSuccessPayload

```typescript theme={"dark"}
interface CardSubmitSuccessPayload {
  result: {
    success: boolean;
    token: string;
    paymentId: string;
  };
}
```

### CardSubmitErrorsPayload

```typescript theme={"dark"}
interface CardSubmitErrorsPayload {
  errors: InputValidationError[];
}
```

### InputValidationError

```typescript theme={"dark"}
interface InputValidationError {
  field: string;
  name: string;
  error: string;
}
```

### VaultedMethodsUpdateData

```typescript theme={"dark"}
interface VaultedMethodsUpdateData {
  vaultedPayments: VaultedPaymentMethodSummary[];
  cvvRecapture: boolean;
  timestamp: number;
}
```

### VaultedPaymentMethodSummary

```typescript theme={"dark"}
interface VaultedPaymentMethodSummary {
  id: string;
  analyticsId: string;
  paymentMethodType: string;
  paymentInstrumentType: string;
  paymentInstrumentData?: {
    // Card fields
    last4Digits?: string;
    network?: string;
    cardholderName?: string;
    expirationMonth?: string;
    expirationYear?: string;
    // PayPal fields
    email?: string;
    firstName?: string;
    lastName?: string;
    externalPayerId?: string;
  };
  isSelected?: boolean;
}
```

### VaultSelectionChangeData

```typescript theme={"dark"}
interface VaultSelectionChangeData {
  paymentMethodId: string | null;
  timestamp: number;
}
```

### ShowOtherPaymentsToggledPayload

```typescript theme={"dark"}
interface ShowOtherPaymentsToggledPayload {
  expanded: boolean;
}
```

### InitializedPaymentMethod

```typescript theme={"dark"}
interface InitializedPaymentMethod {
  type: string;
  // Additional properties vary by payment method type
}
```

***

## See also

<CardGroup cols={2}>
  <Card title="Events guide" icon="bolt" href="/checkout/primer-checkout/configuration/events">
    When, why, and how to use events in your integration
  </Card>

  <Card title="SDK options reference" icon="gear" href="/sdk/primer-checkout-web/sdk-options-reference">
    Configuration options for `<primer-checkout>`
  </Card>

  <Card title="Headless vault guide" icon="bookmark" href="/sdk/primer-checkout-web/components/primer-vault-manager#headless-vault-implementation">
    Custom vault UI implementation
  </Card>
</CardGroup>
