Skip to main content
The express checkout button is a small, drop-in button that lets customers pay without first navigating to a separate checkout page. It auto-detects Apple Pay on supported browsers and falls back to a Whop Pay button that opens checkout in a dialog over your page. It’s a thinner surface than the full embedded checkout — use it when you want to add a single buy button to a landing page, product card, or pricing tier, rather than embed the entire checkout form.

What renders

The button picks one method per browser, in this order:
BrowserRendersNotes
Safari (macOS/iOS) with an Apple Pay card set upNative Apple Pay buttonSubmits inline; no dialog
Chrome / Android with Google PayNative Google Pay buttonSubmits inline; no dialog
Anything elseWhop Pay buttonOpens checkout in a dialog over your page
If you only request apple-pay and the browser can’t render it, the button signals back to your page (via the express-method-resolved event) so you can hide the slot.

React setup

Step 1: Install the package

npm install @whop/checkout

Step 2: Add the button

import { WhopExpressCheckoutButton } from "@whop/checkout/react";

export default function PricingCard() {
	return (
		<WhopExpressCheckoutButton
			planId="plan_XXXXXXXXX"
			returnUrl="https://yoursite.com/checkout/complete"
		/>
	);
}
The returnUrl is required on the express button (unlike the regular embedded checkout, where it’s optional). Payments started here may complete inside the Whop Pay dialog via a redirect-based payment method (3DS, Sezzle, etc.) and the user needs somewhere to land that closes the loop on your page. When the customer is redirected back, check the status query parameter:
  • success: The payment succeeded.
  • error: The payment failed or was canceled.

Step 3: (optional) Configure - Available properties

planId

Required (or checkoutConfigurationId) - The plan id you want to checkout. Provide either this or checkoutConfigurationId, not both.

checkoutConfigurationId

Required (or planId) - An API-created checkout configuration id. Use this to mount the button against a pre-configured checkout (e.g. with attached metadata, a pre-applied promo, or a multi-line cart) instead of creating a new session at mount time. Provide either this or planId, not both.

returnUrl

Required - The URL to return to after payment authorization flows.

methods

Optional - Which methods the button is allowed to render, in priority order. Defaults to ["apple-pay", "whop-pay"].
  • apple-pay — the native Apple Pay / Google Pay button (auto-resolved per browser).
  • whop-pay — a Whop Pay button that opens checkout in a dialog.
<WhopExpressCheckoutButton
	methods={["apple-pay"]}
	planId="plan_XXXXXXXXX"
	returnUrl="https://yoursite.com/checkout/complete"
/>
If you only allow apple-pay and the browser doesn’t support it, nothing renders and the onExpressMethodResolved callback fires with { rendered: "none" }.

theme

Optional - The theme for the button and the dialog. Possible values are light, dark, or system.

themeOptions

Optional - Theme tuning for the Whop Pay dialog.
<WhopExpressCheckoutButton
	planId="plan_XXXXXXXXX"
	returnUrl="https://yoursite.com/checkout/complete"
	theme="dark"
	themeOptions={{ accentColor: "violet", highContrast: true }}
/>

prefill

Optional - Prefill the email or address inside the Whop Pay dialog. Same shape as the regular embedded checkout — see prefill options.
<WhopExpressCheckoutButton
	planId="plan_XXXXXXXXX"
	returnUrl="https://yoursite.com/checkout/complete"
	prefill={{ email: "example@domain.com" }}
/>

affiliateCode

Optional - Attribute the sale to an affiliate.

promoCode

Optional - Apply a promo code on the session.

adaptivePricing

Optional - Set to true to present prices in the buyer’s local currency where supported. Defaults to false.

skipRedirect

Optional - Set to true to skip the final redirect and keep your page loaded. Automatically true when onComplete is provided.

onComplete

Optional - Fires when the checkout completes successfully.
Setting this implies skipRedirect = true.
<WhopExpressCheckoutButton
	planId="plan_XXXXXXXXX"
	returnUrl="https://yoursite.com/checkout/complete"
	onComplete={(planId, receiptId) => {
		console.log("paid", planId, receiptId);
	}}
/>

onExpressMethodResolved

Optional - Fires once the button decides which method it will render.
<WhopExpressCheckoutButton
	planId="plan_XXXXXXXXX"
	returnUrl="https://yoursite.com/checkout/complete"
	onExpressMethodResolved={({ rendered }) => {
		// rendered: "apple-pay" | "google-pay" | "whop-pay" | "none"
		if (rendered === "none") hidePricingCard();
	}}
/>
rendered: "none" means the button won’t show anything — typically because the only requested method is apple-pay and the browser can’t render it. Use this to hide the surrounding slot so you don’t leave an empty space on the page.

Other websites

Step 1: Add the script tag

<script
	async
	defer
	src="https://js.whop.com/static/checkout/loader.js"
></script>

Step 2: Add the button

The express button is a custom element. Once the script loads it registers <whop-express-checkout-button>:
<whop-express-checkout-button
	plan-id="plan_XXXXXXXXX"
	return-url="https://yoursite.com/checkout/complete"
></whop-express-checkout-button>

Step 3: (optional) Configure - Available attributes

AttributeRequiredDescription
plan-idyes (or checkout-configuration-id)The plan to check out.
checkout-configuration-idyes (or plan-id)An API-created checkout configuration to resume instead of creating a new session at mount.
return-urlyesWhere to return after redirect-based authorization.
methodsnoComma-separated list — apple-pay, whop-pay. Defaults to both.
themenolight, dark, or system.
theme-accent-colornoFrosted UI accent color name (e.g. violet).
theme-high-contrastno"true" or "false".
prefill-emailnoPrefill the buyer’s email.
prefill-namenoPrefill the buyer’s name.
prefill-address-line1noPrefill billing address line 1.
prefill-address-line2noPrefill billing address line 2.
prefill-address-citynoPrefill billing city.
prefill-address-statenoPrefill billing state.
prefill-address-countrynoPrefill billing country code.
prefill-address-postal-codenoPrefill billing postal code.
prefill-shipping-namenoPrefill shipping name.
prefill-shipping-address-line1noPrefill shipping address line 1.
prefill-shipping-address-line2noPrefill shipping address line 2.
prefill-shipping-address-citynoPrefill shipping city.
prefill-shipping-address-statenoPrefill shipping state.
prefill-shipping-address-countrynoPrefill shipping country code.
prefill-shipping-address-postal-codenoPrefill shipping postal code.
affiliate-codenoAffiliate attribution.
promo-codenoApply a promo code on the session.
state-idnoResume a previously-created session.
adaptive-pricingno"true" to present buyer-local currency.
skip-redirectno"true" to keep your page loaded after payment.
setup-future-usagenoSet to off_session to save the payment method for future charges.
environmentnoOverride the API environment (rarely needed).
wuidnoStable per-buyer identifier for analytics.

Step 4: Listening for events

The custom element dispatches DOM events you can listen for:
<whop-express-checkout-button
	id="my-button"
	plan-id="plan_XXXXXXXXX"
	return-url="https://yoursite.com/checkout/complete"
></whop-express-checkout-button>

<script>
	const button = document.getElementById("my-button");

	button.addEventListener("express-method-resolved", (event) => {
		// event.detail.rendered: "apple-pay" | "google-pay" | "whop-pay" | "none"
		if (event.detail.rendered === "none") button.style.display = "none";
	});

	button.addEventListener("complete", (event) => {
		// event.detail: { planId, receiptOrSetupIntentId }
		console.log("paid", event.detail);
	});

	button.addEventListener("overlay-open", () => {
		// the Whop Pay dialog opened
	});

	button.addEventListener("overlay-close", () => {
		// the Whop Pay dialog closed (cancelled or completed)
	});
</script>
EventFires when
readyThe button has mounted and measured itself.
express-method-resolvedThe button decided which method it will render. event.detail.rendered is "apple-pay", "google-pay", "whop-pay", or "none".
overlay-openThe Whop Pay dialog opened.
overlay-closeThe Whop Pay dialog closed (for any reason).
completePayment completed successfully. event.detail has planId and receiptOrSetupIntentId.