Skip to main content

Import

import { CheckoutModal } from "@billingos/sdk";

Basic usage

const [open, setOpen] = useState(false);

<CheckoutModal
  open={open}
  onOpenChange={setOpen}
  priceId="price_pro_monthly"
  onSuccess={(subscription) => {
    console.log("Paid!", subscription);
    setOpen(false);
  }}
/>
The checkout modal renders in a secure iframe. Card data never touches your servers — it goes directly to Stripe. Checkout modal

Props

open
boolean
required
Whether the modal is visible.
onOpenChange
(open: boolean) => void
required
Called when the modal should open or close.
priceId
string
required
The price ID to charge.
onSuccess
(subscription: any) => void
required
Called after a successful payment.
customer
object
Prefill customer information to skip the email step.
couponCode
string
Apply a discount code automatically.
collectBillingAddress
boolean
Require billing address during checkout.
currency
string
Override the default currency.
existingSubscriptionId
string
Pass an existing subscription ID for upgrades/downgrades. The checkout will show proration details.
metadata
Record<string, string>
Custom key-value pairs attached to the subscription.
adaptivePricing
boolean
Enable localized pricing based on the customer’s location.
locale
string
Locale for the checkout UI.
onError
(error: Error) => void
Called if the payment fails.
onCancel
() => void
Called if the user closes the modal without completing payment.
debug
boolean
default:"false"
Enable debug logging for development.
The checkout modal runs in a secure iframe. Card details are handled entirely by Stripe — your app never processes or stores payment information. This means you’re PCI-compliant by default.

Examples

Upgrade with proration

<CheckoutModal
  open={open}
  onOpenChange={setOpen}
  priceId="price_enterprise_monthly"
  existingSubscriptionId={currentSubscription.id}
  onSuccess={(sub) => {
    toast.success("Upgraded!");
    queryClient.invalidateQueries({ queryKey: ["subscriptions"] });
  }}
/>

With customer prefill and coupon

<CheckoutModal
  open={open}
  onOpenChange={setOpen}
  priceId="price_pro_yearly"
  customer={{
    email: user.email,
    name: user.name,
  }}
  couponCode="LAUNCH20"
  onSuccess={handleSuccess}
  onError={(err) => toast.error(err.message)}
/>

Adaptive pricing

<CheckoutModal
  open={open}
  onOpenChange={setOpen}
  priceId="price_pro_monthly"
  adaptivePricing={true}
  onSuccess={handleSuccess}
/>