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

Pricing cards & snippet

Custom call-to-action cards ("talk to sales")

A plan's card grid can include a custom call-to-action card — the operator's "talk to sales" or Enterprise tier. In the catalogue it is the item whose itemType is "CUSTOM_CTA". It renders as a normal pricing card, with its own icon, features, and button label, and is visually indistinguishable from a priced tier. It shows no price, its button navigates to an operator-set link instead of starting checkout, and it always renders after every priced card in the grid.

The link (ctaLink) is an absolute https:// URL, a site-relative path (/contact), a mailto: address, or a tel: number. Clicking the button does not start checkout and emits no checkout lifecycle event — there is no checkoutInitiated or checkoutConfirmed, since it is not a checkout. The button respects the iframe target param: target=_top navigates your host page to the link; any other target opens the link in a new tab so your embedding page stays in place. A mailto: or tel: link always hands off to the OS handler.

Set ctaCallback=1 on the iframe to make a custom CTA button hand the click to your page instead of following its link. The button then fires the customCtaClicked event and navigates nothing, so your page owns the action — open a chat widget, a contact modal, or a calendar. The event carries the operator ctaLink, which your handler can navigate to or ignore. This is independent of target, so a host can intercept CTA buttons while still using any checkout mode.

A CUSTOM_CTA item in the backend catalogue read carries itemType: "CUSTOM_CTA", its ctaLink, a ctaPresetKey ("contactUs", "bookDemo", or "scheduleTime", derived from the button label for analytics), and priceMinor: null with sourceSubscriptionId: null. Treat these items as non-purchasable wherever your code expects a buyable card.

Snippet query parameters

ParamValuesDefaultMeaning
langen | daenAll surfaces. Language the cards + checkout render in.
themesystem | light | darksystemAll surfaces. Color theme. system follows the visitor's OS preference.
targetinline | _blank | _top | callbackinlinePricing card only. Where the buy CTA opens checkout (see matrix below). callback opens nothing: the click fires checkoutInitiated and your page owns the action (signup-first funnel; see Defer the buy action). The two item-pinned surfaces are always in-frame and ignore it.
itema <planItemId>(none)Pricing card only. Deep-links the pricing-card embed straight to one item's in-frame checkout while keeping the cards behind it; Back returns to them. For a checkout with no cards, use the path-segment form …/embed/checkout/<vanity>/<planItemId> instead of this query param. Either id comes from the operator's snippet; it is a server-side id, not a value you construct.
ctaCallback1(off)Pricing card only. Defers custom CTA card clicks to your page: the button fires customCtaClicked and navigates nothing, instead of following its ctaLink. Independent of target. Has no effect on priced cards.

The buy CTA starts checkout on every surface. The one exception is target=callback, where your page owns the action.

target × authed checkout-bind — support matrix

The authed checkout-bind works on every surface, in-frame and breakout. An in-frame checkout binds directly. A breakout (_blank / _top) binds via a session-locator redirect: the iframe mints a bound session server-side, then redirects the new tab or host page with only the opaque session id in the URL fragment. With callback, binding happens on the resume surface you send the buyer to.

targetWhere checkout runsBind honored?
inline (+ operator "Allow in-frame checkout" on)in the iframeyes (in-frame)
inline (toggle off)falls back to a new tab (standalone)yes (via the session-locator redirect)
_blanknew tab (standalone)yes (via the session-locator redirect)
_tophost page navigates (standalone)yes (via the session-locator redirect)
callbacknothing opens — your page owns itN/A — bind on the resume surface you build

Binding requires only that your page register a fetchBindToken provider (see Bind to a customer). With no provider the buyer goes through the anonymous flow on every mode.

Breakout binding (new tab / redirect)

A breakout binds by creating the bound session server-side first. On a _blank / _top buy click the iframe:

  1. Requests a fresh bind ref from your fetchBindToken provider (same on-demand handshake as in-frame). No provider or a null ref produces an anonymous breakout to the plain …/checkout/<…> URL.
  2. Mints a bound session server-side and gets back an opaque sessionId.
  3. Redirects the breakout to …/checkout/<planVersionId>/<planItemId>#session=<sessionId> — the session locator in the URL fragment, never the bind ref and never a query param, so it is not sent to any server and not in Referer.

The standalone checkout page reads the #session= fragment, strips it from the URL immediately, and rehydrates the bound session (its quote plus the read-only Details pre-fill). The locator is single-use (consumed at confirm), tenant-scoped, and stripped on arrival. The locator expires after a short TTL; anyone holding the checkout URL can complete checkout until then.

Last modified on June 15, 2026
OverviewLifecycle events
On this page
  • Custom call-to-action cards ("talk to sales")
  • Snippet query parameters
    • target × authed checkout-bind — support matrix
    • Breakout binding (new tab / redirect)