Skip to main content
This page documents @whop/elements@1.0.0-beta.0 and @whop/elements-react@1.0.0-beta.0.
Pre-release, not yet part of a stable release.

Playground

Assemble the elements with example data. Drive the controls, add and arrange elements, and watch events fire live:

Options

Pass these to whop.payments.create({ … }), or as props on <Payments> in React.
string
Account ID, prefixed biz_. Omit only when calling static methods without a collection surface.
string
Plan ID, prefixed plan_. It resolves client-side to currency, amount, and method configuration. Pass a plan or inline currency and amount, never both.
undefined
Minor-unit feeInclusive and feeFree totals used to gate methods when checkout re-prices amount for a fee-free method such as BNPL. Each method is checked against its matching total, preventing the selected fee-free method from disappearing. When omitted, amount gates every method.
string
Return URL for off-site bank or 3DS steps. Defaults to the mounting page.
"off_session" | "on_session"
Displays consent to save the payment method and marks the token for off_session or on_session use.
WalletAvailability
Wallet availability override for deterministic previews. Live checkouts probe the host.
{ id: string; clientSecret: string; }
Checkout session updated when a buyer signs in. Pass its chs_-prefixed id and client_secret. Without them, sign-in succeeds but the session does not record the buyer.
string
Lowercase three-letter ISO 4217 payment currency code. It filters the payment-method matrix.
number
Payment amount in minor units. Methods whose bounds exclude it aren’t offered.
{ enabled?: string[] | undefined; disabled?: string[] | undefined; include_platform_defaults?: boolean | undefined; }
Account payment-method filters in the API’s enabled, disabled, and include_platform_defaults format. disabled removes types, enabled restores offered types, and include_platform_defaults: false leaves only enabled types. Plans provide their own configuration.
Appearance
Visual customization for this group’s elements. Overrides the global WhopElements({ appearance }). Change it live with update({ appearance }).
WhopElementsLocale
Locale for this group’s element UI text. Set it to one of the app’s built locales to override the global configuration. Any other value falls back to the default locale.
The options are a union. Provide exactly one of these shapes, plus the shared event callbacks below:
  • { accountId: string; plan: string; offerAmounts?: undefined; returnUrl?: string; setupFutureUsage?: "off_session" | "on_session"; previewWalletAvailability?: WalletAvailability; checkoutSession?: { id: string; clientSecret: string; } }
  • { accountId: string; currency: string; amount: number; offerAmounts?: { feeInclusive: number; feeFree: number; }; paymentMethodConfiguration?: { enabled?: string[] | undefined; disabled?: string[] | undefined; include_platform_defaults?: boolean | undefined; }; returnUrl?: string; setupFutureUsage?: "off_session" | "on_session"; previewWalletAvailability?: WalletAvailability; checkoutSession?: { id: string; clientSecret: string; } }
  • { accountId?: undefined; plan?: undefined; currency?: undefined; amount?: undefined; offerAmounts?: undefined; paymentMethodConfiguration?: undefined; returnUrl?: string; setupFutureUsage?: "off_session" | "on_session"; previewWalletAvailability?: WalletAvailability; checkoutSession?: { id: string; clientSecret: string; } }

Events

Pass callbacks in the create options or React props.

onLoadingChange

Runs when the grouped loading state changes. The value is true while any mounted element is still loading. Signature: ((loading: boolean) => void)

Methods

Call these on the Payments handle from whop.payments.create({ … }) or usePayments().

createConfirmationToken

Creates a confirmation token for the selected method from your pay button. Pass the checkout’s billing details. They must include email. Cards also need name and an address containing line1 and country. Wallet selections open their sheet during the pay-button interaction. Confirm the returned confirmationToken server-side, then call WhopElements.payments.handleNextAction(…). Runs on your page (host-side), not in the controller iframe. Signature: (input: { billingDetails?: { email?: string | undefined; name?: string | undefined; address?: { country?: string | undefined; line1?: string | undefined; line2?: string | undefined; city?: string | undefined; state?: string | undefined; postal_code?: string | undefined; } | undefined; } | undefined; }) => Promise<{ confirmationToken: string; type: string; }>

update

Merges new handle options into every mounted element. In React, change the namespace props instead. Signature: (options: Partial<PaymentsOptions>) => void

Static methods

Call these without mounting: whop.payments.<method>(…) in vanilla or useWhop().payments.<method>(…) in React.

handleNextAction

Completes a confirmed payment’s pending step without mounting an element. clientSecret identifies the payment. You don’t need a payment ID. Inline steps open in a dialog and resolve with redirected: false. Dismissing the dialog returns the payment’s current status, which can remain pending. Full-page steps redirect with redirected: true to return_url, or a hosted receipt when the payment has no return URL. They reject with code FULL_PAGE_STEP_IN_FRAME inside subordinate frames. Set returnUrl to update the destination before presentation. An update failure rejects before any step runs. Inline steps never navigate to that URL. A payment with no pending step resolves immediately. Signature: (input: { clientSecret: string; returnUrl?: string | undefined; pollIntervalMs?: number | undefined; }) => Promise<{ status: string; redirected: boolean; lastPaymentError: { code?: string | null | undefined; decline_code?: string | null | undefined; message?: string | null | undefined; } | null; }>

Resources

Create these SDK objects without mounting an element. Each has its own page:

PaymentRequest

Low-level Apple Pay or Google Pay sheet for custom buttons, express checkout, and shipping callbacks. Wallet tiles automate this flow through payments.createConfirmationToken. Await canMakePayment() to check availability and prime the sheet, then call show(type) synchronously in the user-interaction handler. The resolved ctok is a ctok_-prefixed confirmation token. Confirm it server-side like an element-minted token.

Types

Named types used throughout this page.

WalletAvailability

Host-probed wallet availability after checking offered methods, device capability, and Google Pay origin approval.

applePay

Signature: boolean

googlePay

Signature: boolean

CardNetworkArt

The slice of a matrix card network the fields need: identity plus the API-served square art.

brand

Signature: "visa" | "mastercard" | "amex" | "discover" | "jcb" | "diners" | "unionpay" | "elo" | "maestro"

icons

Signature: { square: { light: { svg: string; }; dark: { svg: string; }; }; }

PaymentRequestLineItem

Fields on PaymentRequestLineItem.

label

Signature: string

amount

Minor units, same as amount. Signature: number

PaymentRequestShippingOption

Fields on PaymentRequestShippingOption.

id

Signature: string

label

Signature: string

detail

Signature: string | undefined

amount

Minor-unit display value. The resource doesn’t calculate shipping. Update amount from your handler. Signature: number

PaymentRequestAddress

Fields on PaymentRequestAddress.

line1

Signature: string | undefined

line2

Signature: string | undefined

city

Signature: string | undefined

state

Signature: string | undefined

postal_code

Signature: string | undefined

country

Signature: string | undefined

recipient

Signature: string | undefined

phone

Signature: string | undefined

PaymentRequestResult

Fields on PaymentRequestResult.

ctok

Confirmation token ID, prefixed ctok_. Confirm it server-side with your secret key. Signature: string

type

Signature: "apple_pay" | "google_pay"

payer

Signature: { email?: string | undefined; name?: string | undefined; phone?: string | undefined; }

shipping

Signature: { address?: PaymentRequestAddress | undefined; option?: PaymentRequestShippingOption | undefined; } | null

PaymentRequestError

Fields on PaymentRequestError.

code

Signature: "shipping_address_invalid" | "shipping_address_unserviceable" | "shipping_option_invalid" | "other" | undefined

message

Signature: string

PaymentRequestUpdate

Fields on PaymentRequestUpdate.

amount

Signature: number | undefined

lineItems

Signature: PaymentRequestLineItem[] | undefined

shippingOptions

Signature: PaymentRequestShippingOption[] | undefined

errors

Signature: PaymentRequestError[] | undefined

ShippingAddressChangeEvent

Fields on ShippingAddressChangeEvent.

address

Vendor-normalized pre-authorization address. It includes only city, state, postal code, and country. Signature: PaymentRequestAddress

updateWith

Call this exactly once, or the sheet stalls until the vendor times it out. Signature: (update: PaymentRequestUpdate) => void

ShippingOptionChangeEvent

Fields on ShippingOptionChangeEvent.

option

Always includes the selected id. It includes the full option when it matches one of yours. Signature: { id: string; } & Partial<PaymentRequestShippingOption>

updateWith

Signature: (update: PaymentRequestUpdate) => void

BillingAddressChangeEvent

Fields on BillingAddressChangeEvent.

address

Vendor-normalized pre-authorization billing address. It includes only city, state, postal code, and country. Signature: PaymentRequestAddress

updateWith

Call this exactly once. An event left unanswered keeps the current total when the reply deadline passes. Signature: (update: PaymentRequestUpdate) => void

Elements

The elements this group mounts. Each has its own page:

AddressElement

Collects a billing or shipping address. Fields, order, and validation follow the selected country. Includes street autocomplete and methods to read or validate the address.

EmailElement

Collects the buyer’s email and passes it to payments.createConfirmationToken() while mounted. Explicit billingDetails.email wins. A matching Whop account shows optional sign-in with code verification. Successful sign-in unlocks saved payment methods in the payment element. Buyers can continue as guests.

TaxIdElement

Collects a business tax registration accepted by the API. Labels use buyer-facing names. The placeholder matches the selected format. country preselects a type. onChange emits committed pairs. The host supplies API validation errors.
Alternatives. Mount one at a time. Destroy it before mounting another:

PaymentElement

Shows available payment methods and collects the selected method’s required fields and disclosures. Use change to enable your pay button. In its activation handler, call payments.createConfirmationToken(). Confirm the token server-side, then pass any pending step to payments.handleNextAction(…). Use addressChange for address-dependent updates.

CardElement

Prearranged fields for card number, expiration, and security code. Create with payments.create("card"), enable your payment button from onChange, and confirm with payments.createConfirmationToken(). Card numbers remain in PCI-isolated hosted fields. layout supports stacked (default) and compact.

CardFields

Three separately mountable, PCI-isolated card fields for custom layouts: number, expiration, and security code. Create with payments.create("cardFields"), place each field, enable your payment button from onChange, and confirm with payments.createConfirmationToken(). Card numbers remain in hosted fields. (sub-controller, 3 elements)

Flow surfaces

These internal elements open automatically during guided flows. They aren’t part of the consumer API, so you don’t mount or configure them.
  • AddressSuggestionsElement (addressSuggestions): The address autocomplete overlay — suggestion rows plus Enter address manually, anchored beside the street field.
  • BillingAddressSuggestionsElement (billingAddressSuggestions): The billing address autocomplete overlay — suggestion rows plus Enter address manually, anchored beside the billing street field.
  • VerificationCodeElement (verificationCode): The payments controller opens this buyer sign-in dialog when a recognized buyer chooses to sign in. It verifies a one-time code with the pending session’s client_secret. The dialog enforces the resend window and shows verification failures, including expired or incorrect codes, rate limits, and required email-link steps. On success, it sends the session token to the controller and closes.
  • CompletePaymentElement (completePayment): Detached modal opened by payments.handleNextAction to finish a pending payment step. It handles embedded provider flows, bank-transfer instructions, and confirmation waits. The surface polls payment status with its scoped client_secret and closes when no action remains. Consumers never mount it directly.
  • PhoneVerificationElement (phoneVerification): Dialog opened by the payments controller for a checkout’s verify_phone step. It collects the buyer’s phone number, sends a confirmation code, and verifies it with the buyer’s signed-in credential. It closes after verification succeeds. Accounts requiring a verified phone block the sale until this two-pane flow succeeds. Consumers never mount it directly.