Checkout

Embedded checkout

Show TuCapi Business checkout inside your site, in an iframe, with events for your UI.

1Authorize your site

In the dashboard, open Embedded checkout and add each site under Authorized sites.

  • The exact origin, without a path: https://www.yourstore.com.
  • Each subdomain is separate. https://yourstore.com and https://www.yourstore.com are two sites.
  • https:// only. For local testing, http://localhost and http://127.0.0.1 are allowed, with or without a port.
  • No wildcards (*.yourstore.com). Up to 20 sites.

A site that isn't listed can't load your checkout

The browser blocks the iframe through frame-ancestors. Changes take up to one minute. Only the owner or a manager can edit the list.

2Paste the code

The dashboard gives you this code, ready, for the link you choose:

  • data-tucapi-checkoutstringRequired
    The link slug, or the full embedUrl of an API charge.
  • data-localees | enOptional
    Language. Without it, your customer's browser language.
  • data-themelight | darkOptional
    Theme. Without it, your customer's system theme.
  • data-checkout-originstringOptional
    Only if you use your own checkout domain, e.g. https://pay.yourstore.com.

The frame adjusts its height on its own as the content changes.

index.html
HTML
<div  data-tucapi-checkout="LINK_SLUG"  data-locale="en"  data-theme="light"></div><script src="https://pay.tucapi.com/embed.js" async></script>

3With an API charge

POST /v1/charges returns embedUrl alongside checkoutUrl.

Pass it as is to your frontend, in data-tucapi-checkout.

index.html
HTML
<div data-tucapi-checkout="https://pay.tucapi.com/embed/k7x2m9qz"></div><script src="https://pay.tucapi.com/embed.js" async></script>
POST /v1/charges
{  "checkoutUrl": "https://pay.tucapi.com/k7x2m9qz",  "embedUrl": "https://pay.tucapi.com/embed/k7x2m9qz"}

4Mount it from JavaScript

If you'd rather control mounting, use TucapiCheckout.mount(container, options).

  • slugstringOptional
    The link slug. Use slug or url.
  • urlstringOptional
    A charge's embedUrl.
  • localees | enOptional
    Checkout language.
  • themelight | darkOptional
    Checkout theme.
  • onEventfunctionOptional
    Gets every event: { type, slug, data }.
  • checkoutOriginstringOptional
    Your own checkout domain, if you have one.
  • titlestringOptional
    Accessible iframe title. Defaults to Checkout.
  • minHeightnumberOptional
    Initial height in pixels. Defaults to 520.

mount returns an object with destroy() to remove the checkout.

checkout.js
JavaScript
const checkout = TucapiCheckout.mount("#checkout", {  slug: "k7x2m9qz", // or url: charge.embedUrl  locale: "en",  theme: "light",  onEvent: (e) => console.log(e.type, e.data),});​// To remove itcheckout.destroy();

5Listen to events

Events reach onEvent and fire as a CustomEvent on the container, prefixed with tucapi:.

EventWhendata
readyCheckout loaded.{}
resizeThe height changed. embed.js already resizes the iframe.{ height }
order.createdYour customer picked a method and an order was created.{ orderId, paymentMethod }
payment.processingThe payment is being verified.{ orderId }
payment.succeededThe payment was confirmed.{ orderId }
payment.failedIt failed, expired, was canceled or was rejected.{ orderId, reason }

reason is failed, expired, cancelled or rejected. In order.created, paymentMethod is uppercase (PAYPAL, STRIPE…).

Events don't confirm the payment

Any script on your page can fake an event. Before delivering a product, confirm with the order.paid webhook or with GET /v1/charges/{id} from your server.
checkout.js
JavaScript
document  .querySelector("#checkout")  .addEventListener("tucapi:payment.succeeded", (e) => {    // UI hint only. Confirm the payment on your server.    showThankYou(e.detail.data.orderId);  });

How each method behaves

  • Card. Paid inside the frame. If the bank asks for 3-D Secure, its window opens on top, without leaving your page. Apple Pay and Google Pay aren't offered inside the iframe.
  • PayPal. PayPal can't open inside an iframe, so it opens in a separate window. The frame shows “Confirming your payment” and moves on by itself. If the browser blocks the window, checkout offers to open PayPal in a tab.
  • Zelle. Same as the regular checkout, inside the frame.

Security

  • Only the origins on your list can embed your checkout. The regular checkout can't be embedded anywhere.
  • The list is per merchant. Your site can't embed another merchant's links, or the other way around.
  • Events are sent with postMessage only to your site's exact origin, never to *.
  • Your page never sees card, PayPal or bank account data.

Troubleshooting

SymptomCause
The frame is empty or shows a broken page.Your origin isn't on the list. Check www, the scheme and the port. The console shows a frame-ancestors error.
No events arrive.The page origin doesn't match the list, or the code sits inside another iframe.
The link shows as unavailable.It's paused, expired or already paid.
The PayPal window doesn't open.A popup blocker. Checkout shows a button to open it in a tab.