> For the complete documentation index, see [llms.txt](https://developer.paddle.com/llms.txt).

# Express checkout

Mobile-first checkout block with plan selection and a drawer-style payment flow.

---

## What it does

[Express checkout](https://developer.paddle.com/concepts/sell/express-checkout.md) is the highest converting checkout experience for mobile apps and mobile-first workflows.

This component pairs a compact plan picker with a drawer-style express checkout that opens in-place, so customers stay on your page while making their purchase.

## When to use

- Mobile is the primary surface and you want the checkout sheet to slide up rather than open in a new view.
- You're building a marketing or campaign page where the full pricing-then-checkout journey should live in a single hero section.
- You want to keep the page chrome stable so the payment step doesn't feel like a context switch.

Prefer [inline checkout](https://developer.paddle.com/sdks/components/inline-checkout.md) when you need the order summary visible alongside the payment fields, or when you're embedding the checkout inside a longer onboarding flow rather than a standalone landing page.

**Registry:** [`https://developer.paddle.com/r/express-checkout.json`](https://developer.paddle.com/r/express-checkout.json)

## Install

```bash
npx shadcn@latest add @paddle/express-checkout
```

Also runnable with `pnpm dlx shadcn@latest add @paddle/express-checkout` or `yarn dlx shadcn@latest add @paddle/express-checkout`.

## Props

- **clientToken** (string, required): Paddle.js client-side token. Create one in your Paddle dashboard under Developer Tools &gt; Authentication. Sandbox tokens start with test_; live tokens start with live_.
- **environment** ("sandbox" | "production"): Paddle environment. Must match the token above — sandbox token pairs with "sandbox", live token with "production".. Default: `"sandbox"`
- **plans** (PricingSelectPlan[], required): Plans rendered in the picker. Each entry needs a priceId and name; description, badge, and icon are optional.
- **defaultPriceId** (string): Pre-select a plan by priceId. Omit to require the customer to choose before the drawer opens.
- **layout** ("stacked" | "grid"): Layout for the plan picker. stacked is best for mobile and narrow side panels; grid works at wider breakpoints.. Default: `"stacked"`
- **customer** (CheckoutCustomer): Prefills checkout with an existing customer (email, address, business). Skips the checkout's email-collection step.
- **discountCode** (string): Apply a Paddle discount code. Mutually exclusive with discountId.
- **discountId** (string): Apply a discount by its Paddle ID. Mutually exclusive with discountCode.
- **customData** (Record<string, unknown>): Arbitrary metadata attached to the resulting transaction. Available on webhook events for downstream processing.
- **theme** ("light" | "dark"): Override the Paddle checkout iframe's colour scheme. Defaults to matching the host page.
- **locale** (string): BCP 47 locale (e.g. en-GB, fr-FR) for the checkout copy.
- **showNonExpressPaymentMethods** (boolean): Show traditional card/PayPal methods alongside Apple Pay / Google Pay. By default the drawer only surfaces express methods to keep the flow short.. Default: `false`
- **onComplete** ((data: CheckoutCompleteData) => void): Called when the customer completes payment successfully. Use it to grant access, redirect, or fire your own analytics.
- **onError** ((error: Error) => void): Called when Paddle.js fails to initialise or the checkout encounters a non-recoverable error.
- **submitLabel** (string): Override the label on the button that opens the drawer (default: Subscribe now).
- **className** (string): Extra Tailwind classes applied to the root element.

## Usage notes

Each plan requires a price ID (starts with pri_). Create and/or find yours in your Paddle dashboard under Catalog > Prices. Use sandbox price IDs while NEXT_PUBLIC_PADDLE_ENV is 'sandbox'.
