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:
| Surface | URL | Shows | Use when |
|---|---|---|---|
| Pricing card | https://<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 cards | https://<slug>.portal.ledgerbee.com/embed/<vanity>?item=<planItemId> | that item's checkout, with the cards loaded behind it | You drop the buyer straight on one item but still let them go Back to the full card set. Always in-frame. |
| Forced single-item checkout | https://<slug>.portal.ledgerbee.com/embed/checkout/<vanity>/<planItemId> | that item's checkout only | You 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
- The companion
embed.jsis 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.