Skip to main content

Embedded checkout

Use embedded checkout when your application owns the surrounding payment journey and needs to keep Hubpay checkout inside the page.

Embedded checkout is a presentation mode for a hosted payment page. Create a payment request with executionMode set to HOSTED_PAGE, then place the returned paymentUrl in an iframe with the embedded parameters described below.

How embedded mode starts

Add embedded=true to the returned payment URL and load that URL in an iframe. The parameter only takes effect inside an actual iframe. Opening the same URL directly in a browser tab renders the full hosted payment page.

Inside an iframe, embedded checkout:

  • Removes the merchant identity header and hosted-page chrome
  • Skips the initial Start page and opens payment-method selection
  • Skips payment-method selection as well when the payment request has only one available method
  • Reports checkout progress to the parent page through postMessage
  • Keeps completion inside the frame instead of redirecting the top-level page

The frame has a minimum supported width of 360 px. Add allow="payment" so browser wallet payment methods can work when available.

Build the iframe URL

Preserve the returned URL and its access parameters. Use the browser URL API instead of rebuilding it from a hostname or payment reference:

const checkoutUrl = new URL(paymentUrl);

checkoutUrl.searchParams.set("embedded", "true");
checkoutUrl.searchParams.set("origin", window.location.origin);

const iframe = document.querySelector("#hubpay-checkout");
iframe.src = checkoutUrl.toString();
<iframe
id="hubpay-checkout"
title="Payment checkout"
allow="payment"
width="100%"
height="720"
></iframe>

Set the host origin

origin is the exact origin of the page containing the iframe. It consists of the scheme, hostname and port, when present, with no path:

https://merchant.example
https://merchant.example:8443

Hubpay uses this value as the permitted destination for checkout events and to validate host-driven navigation messages. Using window.location.origin with URLSearchParams, as in the example above, supplies and encodes the correct value.

If origin is absent or invalid, the checkout still renders and the payer can continue, but outbound events such as hubpay:ready and hubpay:success are dropped. Hubpay never broadcasts payment events to every framing page.

The embedding page must be served over HTTPS. For local development, use an HTTPS development origin or tunnel rather than plain HTTP localhost.

Receive checkout events

Listen on the parent page and verify both the checkout origin and the sending window before using a message:

const iframe = document.querySelector("#hubpay-checkout");
const checkoutOrigin = new URL(paymentUrl).origin;

window.addEventListener("message", (event) => {
if (event.origin !== checkoutOrigin) return;
if (event.source !== iframe.contentWindow) return;
if (!event.data || typeof event.data !== "object") return;

switch (event.data.type) {
case "hubpay:ready":
// The frame is ready.
break;
case "hubpay:step":
// Read event.data.step, event.data.paid and event.data.remaining.
break;
case "hubpay:success":
// Update the browser journey, then confirm payment server-side.
break;
case "hubpay:error":
// The checkout reached a terminal error state.
break;
case "hubpay:cancel":
// Close the embedded journey or return to your previous screen.
break;
}
});
EventDataMeaning
hubpay:readyNoneThe embedded frame is running
hubpay:stepstep, paid, remainingThe payer reached a checkout step
hubpay:successpaid, remainingThe payer completed the checkout journey
hubpay:errorOptional messageThe checkout reached a terminal error state
hubpay:cancelNoneThe payer backed out of the first embedded step

Browser events control the customer journey; they are not server-side proof that funds were received. Confirm payment status from a signed webhook or API lookup before fulfilment or accounting actions.

Let the host control Back

Add nav=host when your page supplies its own Back control. Hubpay then hides the checkout Back control. Send hubpay:back to the checkout frame when your control is selected:

iframe.contentWindow?.postMessage(
{ type: "hubpay:back" },
new URL(paymentUrl).origin,
);

Required parameters

ParameterValueEffect
embeddedtrueEnables embedded mode inside an iframe
originHost page originEnables browser events and restricts them to the integrating page

Optional parameters

ParameterValueEffect
primaryHex colourOverrides the primary action colour
accentHex colourOverrides highlights such as focus and countdown marks
backgroundHex colourPaints the checkout surface; the frame is transparent when omitted
themedarkSelects the embedded dark theme
navhostLets the parent page control Back navigation
footerhiddenHides the embedded compliance footer when your integration owns that content

See Payment page branding for colour behaviour and accessibility adjustments.

Next steps