Skip to main content
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.
In development — not yet part of a stable release.

Playground

Assemble the elements with sample data — drive the controls, add and arrange elements, and watch events fire live:

Usage

Options

Pass these to whop.checkout.create({ … }) — or as props on <Checkout> in React.
string
An existing plan id (plan_…) — the element creates a checkout session for it. The plan IS the price; nothing about amounts can be asserted client-side. Set at create only: the session is minted from it, and changing it later refuses.
number
How many units to purchase. Plans that disallow multiples refuse values above 1. Set at create only: the session is minted with it, and changing it later refuses.
string
A promo code to apply before the buyer ever sees the price — the discount is on the first quote, and the buyer can still change or remove it. Pass the code a marketing link carried: a code that has expired or was never valid opens the checkout at full price with the reason on the promo row, never a checkout that will not open. Set at create only.
string
The affiliate this checkout is attributed to. Set at create only.
{ utmSource?: string | undefined; utmMedium?: string | undefined; utmCampaign?: string | undefined; utmTerm?: string | undefined; utmContent?: string | undefined; trackingLinkId?: string | undefined; funnelId?: string | undefined; source?: string | undefined; }
Where this sale came from, for the seller’s reporting: the campaign parameters of the link the buyer arrived on. Everything here is recorded against the order and is never shown to the buyer. Set at create only.
Record<string, string>
Your own key/value pairs to record against the order and read back on the payment — order ids, cart ids, anything you reconcile against. Up to 40 string pairs. Set at create only.
string
Where the buyer lands after an off-site payment step. Https-only (http for localhost). Set at create only.
string
RESUME — a checkout session’s client_secret your integration already holds (the session id is baked into it). The element restores that session instead of creating one. Set at create only: changing it later refuses (mount a fresh checkout for a different session).
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 — one of the app’s built locales, overriding the global config; 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):
  • { plan: string; quantity?: number; promoCode?: string; affiliateCode?: string; attribution?: { utmSource?: string | undefined; utmMedium?: string | undefined; utmCampaign?: string | undefined; utmTerm?: string | undefined; utmContent?: string | undefined; trackingLinkId?: string | undefined; funnelId?: string | undefined; source?: string | undefined; }; metadata?: Record<string, string>; returnUrl?: string }
  • { session: string }

Events

Pass a callback in the create options / React props.

onChange

The checkout advanced — fired after every confirm attempt with the session status and payment id (if one succeeded). Signature: ((payload: { status: string; payment: string | null; }) => void)

onCompleted

The checkout finished — the confirm succeeded and the session is completed. payment is the created payment (pay_…). Signature: ((payload: { payment: string; }) => void)

onLoadingChange

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

Methods

Call these on the Checkout handle — the return of whop.checkout.create({ … }) (vanilla) or useCheckout() (React).

update

Update the handle live: any of its options (appearance and locale included), propagated to every mounted element. React consumers never call it — updating the namespace component’s props does the same. Signature: (options: Partial<CheckoutOptions>) => void

Elements

The elements this group mounts — each has its own page: Alternatives — these are exclusive; mount one at a time (destroy it to mount another):

CheckoutElement

The full checkout surface — order summary with the live quote, promo code entry, the currency the buyer pays in, everything this checkout has to collect from the buyer, the composed payment methods surface, and the pay flow. What it collects is whatever the seller set up (email, their own questions, a phone number, an explicit agreement to their terms), rendered together on one screen in the order they chose — so a seller who starts asking for something new needs no change here. Renders the whole purchase; the checkout controller owns the session and the credential. After a payment that needs an off-site step, this same surface renders the outcome the server reports when the buyer comes back.

Flow surfaces

These internal elements open automatically during flows (for example a confirmation or verification step). They are not part of the consumer API — you never mount, configure, or subscribe to them directly.
  • CheckoutDetailsElement (checkoutDetails) — The order-details sheet a narrow checkout opens for the promo code, currency and totals.