JamiDev

Checkout Links & Embed

Long-lived shareable URLs, multi-product pickers, embedded checkout and merchant redirects.

A checkout link is a long-lived entity (unlike checkout sessions, which expire in 30 minutes). Create them in Store → Checkout Links:

https://jami.bio/jamidev/c/cl_Q4sp2Xr5ybOi
  • One product → the link goes straight to that product's checkout.

  • Several products → buyers see a picker and choose one per checkout.

  • Metadata on the link is merged into the order's metadata (link keys win over product keys) — perfect for campaign attribution.

  • Success URL (optional) sends buyers back to your site after paying, with the {CHECKOUT_ID} placeholder replaced by the checkout session id:

    https://yoursite.com/thanks?checkout={CHECKOUT_ID}

Deactivating a link makes its URL stop resolving immediately; it can be reactivated later.

Redirect resolution

After a payment finishes, buyers land on Jami's hosted result page, which then forwards them (with a short interstitial) using this precedence:

  1. successUrl passed to the checkout API by an authenticated caller
  2. the checkout link's success URL
  3. your organization's default redirect URLs (Settings → Buyer redirect URLs — success, cancel and failure each configurable)
  4. Jami's branded result page

Merchant URLs are validated when saved and never read from query parameters, so the flow can't be abused as an open redirect.

Embedded checkout

Sell from your own site without redirecting visitors away. Add the script once and mark any element:

<script defer src="https://jami.bio/jamidev-embed.js"></script>

<a href="https://jami.bio/jamidev/c/cl_Q4sp2Xr5ybOi" data-jami-checkout>Buy now</a>

Clicking the element opens checkout in a centered overlay iframe — styled however you like, as long as the data-jami-checkout attribute stays. Optional data-jami-checkout-theme="light" | "dark" passes a theme hint.

Events

The embed dispatches CustomEvents on window:

window.addEventListener('jami:checkout:loaded', () => console.log('checkout visible'));
window.addEventListener('jami:checkout:success', (e) => {
	console.log('paid! order:', e.detail.orderId);
});
window.addEventListener('jami:checkout:close', () => console.log('dismissed'));

jami:checkout:success fires as soon as the payment confirms — including for direct (phone-confirmed) payments — so you can unlock content without waiting for your webhook. Treat it as a UX signal only; authorize on your backend via webhooks, never from the browser event.

On this page