Embedded Bank Payments

Embedded payments keep the bank selector inside your checkout while Trustist handles the Pay by Bank flow. The SDK creates the payment, loads the bank list, and starts the bank authorization after selection.

Flow Summary

  1. Your page renders a container for the bank selector.
  2. The SDK calls your server to create a payment and gets payLink.
  3. The bank selector is rendered in an iframe or inline mode.
  4. When the payer selects a bank, the SDK calls your server to start the payment.
  5. Your server returns the authUrl, and the SDK redirects the payer.

Client Example

<div id="bank-selector"></div>
<script src="https://sdk-sandbox.trustistecommerce.com/js/sdk.js?client-id=YOUR_CLIENT_ID" async></script>
<script>
window.trustistReadyCallback = function () {
    const currency = "GBP";

    const embeddedPayment = trustist.ecommerce.EmbeddedBankPayment({
        createPayment: () => {
            return fetch("/api/payments", {
                method: "post",
                headers: {
                    "Accept": "application/json",
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({
                    amount: 99.99,
                    currency: currency,
                    reference: "ORDER-12345",
                    returnUrl: window.location.origin + "/checkout/complete"
                })
            })
            .then((response) => response.json())
            .then((payment) => ({
                paymentId: payment.id,
                payIdString: payment.payIdString,
                payLink: payment.payLink,
                payerServicesUrl: payment.payerServicesUrl
            }));
        },
        startPayment: (request) => {
            return fetch("/api/payments/" + request.paymentId + "/start", {
                method: "post",
                headers: {
                    "Accept": "application/json",
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({
                    bankId: request.bankId,
                    countryCode: request.countryCode,
                    payIdString: request.payIdString
                })
            })
            .then((response) => response.json());
        },
        bankSelector: {
            container: "#bank-selector",
            mode: "iframe",
            countryCode: "GB",
            showCountrySelector: true,
            minHeight: "560px"
        },
        qr: {
            enabled: true
        },
        onStatus: (message) => console.log(message),
        // Live payment observations are available in iframe bank-selector mode.
        onPaymentStatus: (state) => console.log("Payment status", state),
        onPaymentComplete: (state) => {
            if (state.isSuccessful) console.log("Payment approved", state.paymentId);
        },
        onError: (err) => console.error(err)
    });
    embeddedPayment.render();
    // Call embeddedPayment.destroy() when removing this checkout from the page.
};
</script>

onPaymentStatus(state) reports observed statuses, including failed attempts that may be retried. Its payload contains paymentId, payIdString, status, attempt, isRemote, isTerminal, and isSuccessful. A failed attempt remains visible through this callback and does not trigger onPaymentComplete, so the retry remains observable. onPaymentComplete runs for terminal outcomes such as COMPLETED and CANCELLED; check isSuccessful, which is true only for a successful payment. These live hooks are supported with the iframe bank selector; onStatus(message) remains available for human-readable progress. The SDK supplies the calling page's origin as the iframe message target and checks messages against the expected iframe and origin. Call destroy() on the flow when removing it to remove its iframe and message listener. Callbacks run while the checkout page remains loaded, such as when a QR payment completes on another device. A top-level redirect to the bank unloads the checkout, so use the existing return URL flow to handle that result.

Bank Selector Options

Option Description
container CSS selector for the element where the selector will render.
mode iframe or inline rendering mode.
countryCode Two-letter country code to scope the bank list.
currency Optional compatibility input. In iframe mode, the selector can infer bank filtering from the payment behind payIdString.
showCountrySelector Show or hide the country selector when supported.
allowedBankIds Limit the bank list to specific bank IDs.
minHeight Minimum height for the iframe selector.
Recommended pattern: create the payment with the correct currency and let the iframe selector infer the appropriate bank filtering from that payment.

Defaults: in iframe mode, the selector can infer bank filtering from the payment currency and continue to use countryCode and showCountrySelector for bank-list presentation.

If you are not using the SDK, existing integrations can append the same parameters directly to the payLink and use the /embedded/bank-selector endpoint yourself. For payment flows, you normally do not need to append currency or paymentRails; for AIS-only flows, countryCode is normally enough. Direct iframe integrations must provide their exact parent origin as targetOrigin and validate both event.source and event.origin before handling messages. The SDK supplies and checks these values automatically.

https://pay.trustist.com/embedded/bank-selector?payIdString={payIdString}&countryCode=GB&showCountrySelector=false&showQr=false&targetOrigin=https%3A%2F%2Fmerchant.example

Inline mode and specialist bank-directory integrations can continue to use advanced filters directly when needed. Inline controls share one bank-selector script load, so multiple controls can initialise together. Call destroy() before removing an inline checkout: it removes that selector and cancels its pending bank-directory reads. A failed script download is reported through onError; a new control can try loading it again.

Server Responsibilities

  • Create a payment and return paymentId, payIdString, and payLink.
  • Start the payment when the payer selects a bank and return authUrl.
  • Verify final status server-side before fulfilling an order; browser callbacks are presentation updates only.

Retry is disabled by default for TE API payments. To allow retries, set workflow.allowRetryOnFailure when you create the payment on your server.

Next Steps