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

# PaymentElement

> The drop-in payment method picker: shows the payment methods this seller accepts for the charge — filtered live by currency, amount, and seller configuration — and collects what the chosen method needs: card fields, billing address, method-specific inputs, and any required disclosures. Drive your pay button off the `change` event, call `payments.createConfirmationToken()` on click, confirm the token server-side with your secret key, then pass any pending step to `payments.handleNextAction(...)`. Two arrangements via `layout`: a stacked list (default) or a horizontal tile row.

{/* whop-elements-docs-channel: upcoming */}

<Info>**Upcoming** — generated from the latest merged element source; documents unreleased development. Use the channel picker at the top of the sidebar for the docs of a published release.</Info>

{/* whop-elements-since: unreleased */}*In development — not yet part of a stable release.*

Belongs to the [`Payments`](/elements/upcoming/payments/overview) group. Render `<PaymentElement />` inside it (React), or call `payments.create('payment', { … })` on the handle (vanilla) — consumer props and `on<Event>` callbacks both go in the create options / JSX props.

<Note>**Exclusive** — when using `PaymentElement`, you can't mount `CardElement` or `CardFields` in the same Payments handle: these are alternatives — mount one at a time; destroy it to mount another.</Note>

## Preview

A live, interactive demo of this element with sample data:

<div data-whop-demo-shell style={{ position: "relative", minHeight: "320px", transition: "min-height 200ms ease" }}>
  <div data-whop-demo-skeleton style={{ position: "absolute", inset: "0", borderRadius: "12px", background: "rgba(140, 140, 140, 0.12)", pointerEvents: "none", transition: "opacity 200ms ease" }} />

  <iframe data-whop-demo src="https://js.whop.cloud/elements/amber/payments/payment/en/demo/index.html" title="PaymentElement demo" height="320" allow="payment; publickey-credentials-get; clipboard-write" style={{ position: "relative", width: "100%", border: "0", borderRadius: "12px", background: "transparent", colorScheme: "normal" }} />
</div>

## Usage

<div data-whop-usage="payments/payment">
  <CodeGroup>
    ```tsx React theme={null}
    import { WhopElements, Payments, PaymentElement } from "@whop/elements-react";
    import { loadWhop } from "@whop/elements";

    function Example() {
      return (
        <WhopElements elements={loadWhop()}>
          <Payments /* options */>
            <PaymentElement onChange={(payload) => console.log("change", payload)} />
          </Payments>
        </WhopElements>
      );
    }
    ```

    ```html Vanilla theme={null}
    <script src="https://js.whop.cloud/elements/amber/elements.js" data-whop-elements></script>
    <script type="module">
      const payments = window.WhopElements().payments.create({ /* options */ });
      payments.create('payment', { onChange: (payload) => console.log("change", payload) }).mount('#payments-payment');
    </script>
    ```
  </CodeGroup>
</div>

## Props

<ResponseField name="fields" type="{ billingDetails?: &#x22;full&#x22; | &#x22;minimal&#x22; | &#x22;never&#x22; | undefined; }">
  Which internal collection blocks render. `billingDetails: 'minimal'` (default) collects each method's DECLARED payment minimum — exactly the billing fields the method's matrix entry declares (card: name on card, country, postal code — never a street address; most redirect and wallet methods declare nothing and render no block at all). `'full'` opts every fresh method into name plus the complete country format — for hosts who want a full billing address (tax-style collection is a checkout concern, not a payment requirement). `'never'` hides the block — pass the address in `createConfirmationToken({ billingDetails })` instead. The block's country select offers only the countries the method supports for the charge currency (a single-country method locks it). Defaults to `{"billingDetails":"minimal"}`.
</ResponseField>

<ResponseField name="layout" type="&#x22;accordion&#x22; | &#x22;horizontal&#x22;">
  Presentation of the method picker: 'accordion' (default) stacks the methods in a vertical list, each expanding its detail inline; 'horizontal' lays the methods out as a row of equal-width tiles (never scrolling — beyond four methods the row ends in a More tile whose native selector lists the rest, and a method picked there holds the last tile spot until the next pick) with the selected method's detail below. Selection and confirm behavior are identical in both. Defaults to `"accordion"`.
</ResponseField>

<ResponseField name="separated" type="boolean">
  Accordion layout only: render each method as its own visually separate card with spacing between items, instead of the fused list. Ignored while `layout` is 'horizontal'. Defaults to `false`.
</ResponseField>

<ResponseField name="order" type="string[]">
  Display ordering of the methods, in every layout: listed types render first in the given order, unlisted types keep their relative order after them. Presentation only — never affects which methods are available. Defaults to `[]`.
</ResponseField>

<ResponseField name="autoSelect" type="boolean">
  Select the first offered method automatically once the methods resolve (default true) — respects `order` and emits `selected` + `change` exactly like a click. One-shot: it never re-fires after the buyer interacts, and it does nothing when no method is offered. Set false to mount with nothing selected. Separately from this flag, when a live charge update drops the SELECTED method off the list the selection falls back to the first offered method (an element with nothing selected stays blank). Defaults to `true`.
</ResponseField>

## Events

Pass a callback in the create options (or React prop) to receive these.

### `onChange`

The selection changed — `complete: true` means a method is chosen (and, for card, its fields are filled; for methods declaring required inputs, those are filled and valid) so the confirm can run; drive your pay button off it. `method` carries the selected entry's matrix metadata (category, per-currency country list, amount bounds) so your page can react — e.g. narrow its own country field.

**Signature:** `((payload: { complete: boolean; type?: string | undefined; method?: { type: string; category: string; template: string; display_name: string; countries: ({ country: string; min_amount: number | null; max_amount: number | null; })[]; min_amount: number | null; max_amount: number | null; } | undefined; }) => void)`

### `onLoaderStart`

Fired the moment the element's own loading skeleton has painted inside its frame — the earliest point a consumer-managed loading state can hand off without ever exposing a blank. Always precedes `onReady`; most consumers only need `onReady`.

**Signature:** `(() => void)`

### `onReady`

Fired once the element has booted and painted its first complete frame.

**Signature:** `(() => void)`

### `onError`

Fired when the element fails to load or crashes; the element shows its own error fallback. `message` is human-readable; framework refusals also carry `code` (e.g. `HOST_SOURCE_FAILED`, with `sourceKey` naming the failed hostState key) so hosts can switch on codes, never message text.

**Signature:** `((e: { message: string; code?: string | undefined; sourceKey?: string | undefined; }) => void)`

## Methods

Call these on the element handle — the return of `create` (vanilla) or the component `ref` (React).

### `select`

Select a payment method imperatively. `select('cashapp')` runs the same path a buyer's click does — the tile expands, `selected` and `change` fire (a card selection stays `complete: false` until its fields are filled). A type that isn't offered — unknown, seller-disabled, or amount-gated off the list — refuses with `code: 'METHOD_NOT_OFFERED'`. `select(null)` clears the selection, emitting `change { complete: false }`. Pair with `autoSelect={false}` (which mounts the element blank) for full external control of the selection.

**Signature:** `(input: string | null) => Promise<void>`

### `mount`

Place the element on the page: appends its container to `target` (a CSS selector or an element) and starts loading. Nothing renders until this is called. React consumers never call it — the component mounts itself.

**Signature:** `(target: string | HTMLElement) => void`

### `destroy`

Remove the element from the page and release its frame and subscriptions. Safe to call more than once. React consumers never call it — unmounting the component does it.

**Signature:** `() => void`

### `update`

Change this element's consumer props after mount — it re-renders with the merged props. React consumers never call it — updating the JSX props does the same.

**Signature:** `(options: Partial<PaymentElementProps>) => void`

## Styling

Each part below is a stable class name — safe to depend on. Restyle a part by mapping its class to a **style declaration object** under `appearance.classes` (properties camelCase or kebab-case, values as strings with units — the same shape as React's `style` prop). The element renders in its own frame, so page stylesheets can't reach it: these declarations are sanitized against a safe-property allowlist and injected inside the frame for you.

| Class                              | Targets                                                                                                                                                                         |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `.whop-Address`                    | The address form root                                                                                                                                                           |
| `.whop-AddressErrorSummary`        | The summary line shown when validation reveals missing or invalid fields                                                                                                        |
| `.whop-AddressField`               | One field cell in the address form                                                                                                                                              |
| `.whop-AddressFieldError`          | The error line under an address field (full layout)                                                                                                                             |
| `.whop-AddressFieldInput`          | A text input in the address form                                                                                                                                                |
| `.whop-AddressFieldInputInvalid`   | Added to an address input while it fails validation                                                                                                                             |
| `.whop-AddressFieldInvalid`        | Added to a compact field cell while it fails validation                                                                                                                         |
| `.whop-AddressFieldLabel`          | The label above an address field (full layout)                                                                                                                                  |
| `.whop-AddressFieldSelect`         | A select (country, state, organization type) in the address form                                                                                                                |
| `.whop-AddressLine2Toggle`         | The "Add address line 2" text button shown while line 2 is collapsed                                                                                                            |
| `.whop-AddressManualEntry`         | The "Enter address manually" text button below the collapsed form — expands the full country format                                                                             |
| `.whop-AddressSuggestion`          | One suggestion row in the autocomplete overlay                                                                                                                                  |
| `.whop-AddressSuggestionActive`    | Added to the keyboard/pointer-active suggestion row                                                                                                                             |
| `.whop-AddressSuggestionManual`    | The "Enter address manually" row closing the suggestions list                                                                                                                   |
| `.whop-AddressSuggestions`         | The autocomplete suggestions overlay anchored to the address line 1 field                                                                                                       |
| `.whop-CardField`                  | One card field cell — number, expiry, or CVC                                                                                                                                    |
| `.whop-CardFieldError`             | The Invalid / Incomplete message under a card field                                                                                                                             |
| `.whop-CardFieldGroup`             | The grouped card fields — number on top, expiry and CVC below                                                                                                                   |
| `.whop-CardFieldInput`             | The bordered input container around a PCI field                                                                                                                                 |
| `.whop-CardFieldInputFocused`      | Added to the input container while its field is focused                                                                                                                         |
| `.whop-CardFieldInputInvalid`      | Added to the input container while its field is invalid or incomplete                                                                                                           |
| `.whop-CardLabel`                  | The "Card information" label above the field group                                                                                                                              |
| `.whop-Payment`                    | The payment element root                                                                                                                                                        |
| `.whop-PaymentBillingBlock`        | The payment element's internal billing address block                                                                                                                            |
| `.whop-PaymentCardFields`          | The inline card fields panel                                                                                                                                                    |
| `.whop-PaymentDetailIcon`          | The template icon beside the detail region's explainer                                                                                                                          |
| `.whop-PaymentDetailRegion`        | The expanded detail region for a selected method — collection surfaces first (inline card fields, declared inputs), then the explainer and disclosure lines as the bottom block |
| `.whop-PaymentDetailSubtext`       | The consent subtext under the explainer on wallet methods                                                                                                                       |
| `.whop-PaymentDetailText`          | The detail region's explainer line                                                                                                                                              |
| `.whop-PaymentError`               | The error pane shown when methods cannot load or none are available                                                                                                             |
| `.whop-PaymentFieldError`          | The Invalid message under a declared input                                                                                                                                      |
| `.whop-PaymentFieldInput`          | A declared method input in the detail region                                                                                                                                    |
| `.whop-PaymentFieldInputInvalid`   | Added to a declared input while its value fails the declared format                                                                                                             |
| `.whop-PaymentFieldLabel`          | The label above a declared method input in the detail region                                                                                                                    |
| `.whop-PaymentMandateLink`         | The mandate terms link inside the mandate notice                                                                                                                                |
| `.whop-PaymentMandateNotice`       | The mandate authorization notice on methods whose matrix config declares a mandate                                                                                              |
| `.whop-PaymentMethod`              | One payment method — the row plus its expanding detail region                                                                                                                   |
| `.whop-PaymentMethodDetail`        | The expanding region that reveals the selected method's detail — inline card fields, explainer, or declared inputs                                                              |
| `.whop-PaymentMethodIcon`          | The method icon on a row                                                                                                                                                        |
| `.whop-PaymentMethodLabel`         | The method display name on a row                                                                                                                                                |
| `.whop-PaymentMethodMoreSelect`    | The invisible native select stretched over the More tile                                                                                                                        |
| `.whop-PaymentMethodMoreTile`      | The compact overflow tile ending the capped tile row — stacked overflow-method icons over a chevron, its native select lists the remaining methods                              |
| `.whop-PaymentMethodPanel`         | The selected method's detail panel below the tile row (horizontal layout)                                                                                                       |
| `.whop-PaymentMethodRadio`         | The radio indicator on a method row                                                                                                                                             |
| `.whop-PaymentMethodRadioSelected` | Added to the radio indicator while its method is selected                                                                                                                       |
| `.whop-PaymentMethodRow`           | The clickable payment method row                                                                                                                                                |
| `.whop-PaymentMethodRowSelected`   | Added to the method row while it is the selected method                                                                                                                         |
| `.whop-PaymentMethods`             | The payment method list                                                                                                                                                         |
| `.whop-PaymentMethodSeparated`     | Added to a method item while it renders as its own separated card                                                                                                               |
| `.whop-PaymentMethodsSeparated`    | Added to the method list while separated accordion items are on                                                                                                                 |
| `.whop-PaymentMethodTile`          | One method tile in the horizontal tile row                                                                                                                                      |
| `.whop-PaymentMethodTileRow`       | The method tile row (horizontal layout) — never scrolls; beyond the tile cap the overflow methods live in the compact More tile                                                 |
| `.whop-PaymentMethodTileSelected`  | Added to a method tile while it is the selected method                                                                                                                          |
| `.whop-PaymentMoreRow`             | The "N more payment methods" expander row                                                                                                                                       |
| `.whop-PaymentSaveNotice`          | The save-for-future-purchases consent line closing the detail region                                                                                                            |
| `.whop-PaymentSettlementNotice`    | The settlement-window hint on methods whose matrix config declares one                                                                                                          |

```ts theme={null}
const payments = whop.payments.create({
  appearance: {
    classes: {
      'whop-Address': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressErrorSummary': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressField': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressFieldError': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressFieldInput': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressFieldInputInvalid': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressFieldInvalid': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressFieldLabel': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressFieldSelect': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressLine2Toggle': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressManualEntry': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressSuggestion': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressSuggestionActive': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressSuggestionManual': { borderRadius: '8px', fontWeight: '600' },
      'whop-AddressSuggestions': { borderRadius: '8px', fontWeight: '600' },
      'whop-CardField': { borderRadius: '8px', fontWeight: '600' },
      'whop-CardFieldError': { borderRadius: '8px', fontWeight: '600' },
      'whop-CardFieldGroup': { borderRadius: '8px', fontWeight: '600' },
      'whop-CardFieldInput': { borderRadius: '8px', fontWeight: '600' },
      'whop-CardFieldInputFocused': { borderRadius: '8px', fontWeight: '600' },
      'whop-CardFieldInputInvalid': { borderRadius: '8px', fontWeight: '600' },
      'whop-CardLabel': { borderRadius: '8px', fontWeight: '600' },
      'whop-Payment': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentBillingBlock': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentCardFields': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentDetailIcon': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentDetailRegion': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentDetailSubtext': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentDetailText': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentError': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentFieldError': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentFieldInput': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentFieldInputInvalid': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentFieldLabel': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMandateLink': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMandateNotice': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethod': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodDetail': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodIcon': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodLabel': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodMoreSelect': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodMoreTile': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodPanel': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodRadio': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodRadioSelected': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodRow': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodRowSelected': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethods': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodSeparated': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodsSeparated': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodTile': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodTileRow': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMethodTileSelected': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentMoreRow': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentSaveNotice': { borderRadius: '8px', fontWeight: '600' },
      'whop-PaymentSettlementNotice': { borderRadius: '8px', fontWeight: '600' }
    }
  }
});

// restyle live at any point — the same shape through update()
payments.update({
  appearance: { classes: { 'whop-Address': { fontWeight: '700' } } }
});
```

In React, pass the same object as the `appearance` prop on `<Payments>`; `appearance` also applies globally at `WhopElements({ appearance })`.
