Skip to main content
CheckoutButton starts checkout for one plan through BillingProvider and opens Razorpay, redirects, hands you a Stripe client secret, or reports a completed or scheduled change. When to use
  • A plan card or marketing section that sells one plan.
  • An onboarding step that subscribes the new customer.
  • Anywhere you need checkout without the full PricingTable.
CheckoutButton labelled Get Pro, light theme

Importing CheckoutButton

Rendering CheckoutButton

CheckoutButton must be inside a BillingProvider with createCheckout. Your merchant route creates the checkout with your secret key; see Implement the merchant endpoint.
app/pricing/buy-pro.tsx
The button needs no customer data. It reads createCheckout, verifyCheckout and getCheckoutStatus from BillingProvider.

What a click does

  1. The button calls createCheckout({ idempotencyKey, planCode, returnUrl, registerMandate? }). It keeps one idempotency key per plan and reuses it when the customer clicks again, so a retry reopens the same pending checkout. A second click while the first is running does nothing.
  2. For a razorpay result it loads Razorpay and opens it. A captured payment is checked with verifyCheckout, then polled with getCheckoutStatus up to 30 times, one second apart. A failed payment shows “Payment failed. You can retry checkout.”
  3. For a processing result it polls the same way and continues with the checkout it returns.
  4. For a hosted result, or a result with a url, it redirects the page.
  5. For a stripe result it passes the client secret to onStripeClientSecret.
  6. For a completed or scheduled result it calls onComplete or onScheduled.
After a completed or scheduled result, reload the customer’s billing data, for example with useBillingRefresh() from the hooks. See checkout result types.

Examples

Embedded Stripe checkout and results

Pass onStripeClientSecret and render Checkout with the secret. onComplete and onScheduled report changes that need no payment step.

Razorpay

For Razorpay, give the provider verifyCheckout and getCheckoutStatus. Each calls your backend, which scopes the request to the signed-in customer.

API reference

string
required
The plan to check out, sent to createCheckout.
string
default:"Get Started"
Button text. While checkout starts, the button reads “Loading…” and is disabled.
string
Sent to createCheckout, where the provider returns the customer after payment. Defaults to the current URL.
boolean
Sent to createCheckout when set, to ask for a recurring payment mandate. Not sent when left out.
(clientSecret: string) => void
Fires for an embedded Stripe checkout and receives its client secret; render Checkout with it. Without it, a Stripe result fails with “onStripeClientSecret is required for embedded Stripe checkout”.
(result: CompletedCheckoutResult) => void
Fires for a completed result and receives it: the change took effect without a payment step, or a resumed checkout succeeded.
(result: ScheduledCheckoutResult) => void
Fires for a scheduled result, such as a downgrade at renewal, and receives it.
(paymentId: string) => void
Razorpay only. Fires when the payment is captured and the plan is fulfilled, and receives the Razorpay payment ID.
(status: CheckoutStatus) => void
Fires with each status while the button waits for a payment to be confirmed, and receives that status.
() => void
Razorpay only. Fires when the customer closes the Razorpay window without paying.
(error: Error) => void
Fires when checkout fails and receives the error. The message also shows next to the button in a role="alert" element.
string
Deprecated and not used. The Razorpay key comes from the checkout result.
string
Class name on the button.
CSSProperties
Inline styles on the button, on top of the theme’s.
Appearance
Theme, variables and element overrides. Defaults to the provider’s. See Appearance.

States

Appearance

checkoutButton (the button).Style them with appearance.elements. See Elements.

Checkout

Renders the Stripe payment step for the client secret.

PricingTable

Plan cards that start checkout the same way.

UpgradeButton

Confirms a plan change before checkout.

Checkout result types

Every result createCheckout can return.