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;
}
});
| Event | Data | Meaning |
|---|---|---|
hubpay:ready | None | The embedded frame is running |
hubpay:step | step, paid, remaining | The payer reached a checkout step |
hubpay:success | paid, remaining | The payer completed the checkout journey |
hubpay:error | Optional message | The checkout reached a terminal error state |
hubpay:cancel | None | The 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
| Parameter | Value | Effect |
|---|---|---|
embedded | true | Enables embedded mode inside an iframe |
origin | Host page origin | Enables browser events and restricts them to the integrating page |
Optional parameters
| Parameter | Value | Effect |
|---|---|---|
primary | Hex colour | Overrides the primary action colour |
accent | Hex colour | Overrides highlights such as focus and countdown marks |
background | Hex colour | Paints the checkout surface; the frame is transparent when omitted |
theme | dark | Selects the embedded dark theme |
nav | host | Lets the parent page control Back navigation |
footer | hidden | Hides the embedded compliance footer when your integration owns that content |
See Payment page branding for colour behaviour and accessibility adjustments.