LedgerBee Developer
  • Getting started
  • Conventions
  • Products
  • API Reference
Subscriptions
Products & Pricing
Billing documents
WebhooksMCP (AI agents)
Customer Portal
    Portal SSO
    Embedded Checkout
      OverviewPricing cards & snippetLifecycle eventsBind to a customerGated plansFulfillment & errors
Embedded Checkout

Embedded Checkout

Embed a tenant's pricing cards and checkout into your own site. The cards render in a sandboxed iframe served from the tenant's portal origin (https://<slug>.portal.ledgerbee.com). Checkout runs in-frame or breaks out to a new tab. Card capture stays on the payment provider's hosted window, so your page never touches card data.

Placeholders: <slug> is your tenant subdomain. <vanity> is a plan's public vanity slug — the same slug as its /p/<vanity> page (e.g. pro-plan), never a plan UUID. <planItemId> is a specific item's id, required for the item-pinned and forced-checkout surfaces (see "Three surfaces"). All three appear in the operator UI at Settings → Portal → Embedding, which generates a ready-made snippet with the ids filled in. Copy that snippet rather than hand-building the URL.

This guide is split across pages: Pricing cards & snippet, Lifecycle events, Bind to a customer, Gated (non-public) plans, and Fulfillment & errors.

Three surfaces (same embed.js)

These three surfaces address a plan by its public <vanity> slug, so they require a public plan (published + a vanity URL + an allow-all routing rule). To embed a non-public plan for a buyer you've already identified, use the by-id surfaces in Gated (non-public) plans instead.

Checkout always targets one item. There is no standalone vanity-only checkout — that is the pricing card. The three surfaces are:

SurfaceURLShowsUse when
Pricing cardhttps://<slug>.portal.ledgerbee.com/embed/<vanity>the plan's card(s)The buyer compares options; the buy CTA starts the chosen item's checkout.
Item checkout — keeps cardshttps://<slug>.portal.ledgerbee.com/embed/<vanity>?item=<planItemId>that item's checkout, with the cards loaded behind itYou drop the buyer straight on one item but still let them go Back to the full card set. Always in-frame.
Forced single-item checkouthttps://<slug>.portal.ledgerbee.com/embed/checkout/<vanity>/<planItemId>that item's checkout onlyYou want one item, no cards and no Back. Always in-frame.

All three carry the data-ledgerbee-pricing attribute so embed.js manages them (resize plus the on-demand bind handshake). Every surface requests a fresh bind ref at checkout-start, not on load — see the token lifecycle.

The first path segment is the plan's vanity slug, not a UUID. <planItemId> is a server-side id; do not guess it. Both are filled in by the operator's snippet generator at Settings → Portal → Embedding — pick a snippet type (Pricing cards, Checkout (with cards), or Checkout (item only)) and copy the result rather than constructing the URL by hand.

Quick start (pricing card)

Code
<iframe src="https://<slug>.portal.ledgerbee.com/embed/<vanity>?lang=en&target=inline&theme=system" data-ledgerbee-pricing loading="lazy" style="width:100%;border:0;min-height:520px" title="Pricing"></iframe> <script src="https://<slug>.portal.ledgerbee.com/embed.js" async></script>
  • The companion embed.js is optional but recommended. It auto-resizes the iframe to the content height (no inner scrollbar), re-dispatches lifecycle events as DOM events on your page, and performs the bind-token handshake. It carries no tenant or plan knowledge; one copy serves every embed on the page.
  • The embed renders only once the plan is publicly reachable — the operator must publish it and allow it via a portal routing rule. Otherwise the iframe shows a "not found" state. See Errors.
Last modified on June 15, 2026
Portal SSOPricing cards & snippet
On this page
  • Three surfaces (same embed.js)
  • Quick start (pricing card)