Embedded Payment Integration

Seamless payment experience directly on your website

Introduction

Embedded Payment lets customers pay with Card, mada, Apple Pay, or STC Pay directly on your website — no redirect to an external page. The widget collects and processes the payment itself (including any 3D Secure challenge), then hands control back to your page once it's done.

👍 Your settlement account is automatic — never send a SupplierCode. Your Royat Pay API token already identifies which settlement account you are. Every session you create with it is automatically attributed to your account server-side; there is nothing to configure, select, or pass in the request for this. (The only exception is a marketplace-style integration that settles a single checkout across several of your own sub-accounts — that is a distinct, opt-in feature unrelated to normal integration, and does not apply unless Royat Pay support has set it up with you specifically.)
🚧 Deprecated flow — do not use for new integrations: An older embedded flow built on /api/payment/initiate-session + /api/payment/execute (with a SessionId) used to be documented here. It is kept working for existing integrations, but it does not reliably attribute completed payments to your settlement account — the split only applies at ExecutePayment time, and that call never carries your account when a SessionId is used. Use create-session below instead; it attaches your account at creation time and this is verified to work correctly.

How it Works

1. Call the Create Session endpoint

Call POST /api/payment/create-session with the invoice details. Your settlement account is resolved automatically from your Bearer token — do not send a supplier/account field.

Request

{
    "InvoiceValue": 35,
    "CurrencyIso": "SAR",
    "CustomerName": "Mohammed Alhumaid",
    "CustomerMobile": "512345678",
    "CustomerReference": "ORD-2026-00073",
    "CallbackUrl": "https://yoursite.com/checkout/callback/ORD-2026-00073",
    "ErrorUrl": "https://yoursite.com/checkout/failed/ORD-2026-00073"
}
📘 CustomerReference: Always send your own order number here. You will match it back against the session in step 6 — this is what stops a paid session for one order being replayed to mark a different (possibly more expensive) order as paid.

Response

{
    "IsSuccess": true,
    "Message": null,
    "ValidationErrors": null,
    "Data": {
        "SessionId": "dfc6a3c3-df09-44cb-9c6a-0a6375752da6"
    }
}

2. Include the payment widget script

Load MyFatoorah's session widget directly on your checkout page:

<script src="https://sa.myfatoorah.com/sessions/v1/session.js"></script>

3. Define a container element

Add a div with a unique id — the widget renders the payment form inside it.

<div id="embedded-payment"></div>

4. Configure and initialize the widget

Use the SessionId from step 1. The widget shows its own "Pay" button inside the container — you do not need (and should not build) a separate submit button or call any submit API. This widget's config is intentionally minimal — exactly four fields:

var mf = window.myfatoorah || window.myFatoorah || window.MyFatoorah;
mf.init({
    sessionId: "dfc6a3c3-df09-44cb-9c6a-0a6375752da6", // From create-session
    containerId: "embedded-payment",
    shouldHandlePaymentUrl: true, // let the widget handle any 3DS challenge itself
    callback: onPaymentComplete,
});
❗ Do not add paymentOptions, countryCode, currencyCode, amount, supportedNetworks, or language to this config. This is the single most common integration mistake: those keys belong to an older, deprecated widget (see the note above) and this script does not recognize them. Passing them doesn't get silently ignored — it can make the widget fail to render or reject the session outright with "SessionId is not valid or expired!", even for a session that was created correctly. The widget reads the invoice amount, currency, and country from the session itself, and shows every payment method enabled on your account automatically — including Apple Pay and mada — with no method list to configure.
🚧 Apple Pay Prerequisites: To enable Apple Pay you must register and verify your domain first — see the Apple Pay Domain Registration page.

5. Handle the completion callback

The widget calls your callback function once the customer finishes paying (card entry, 3DS, or the Apple Pay / STC Pay sheet). At this point the charge has already been processed by MyFatoorah — send the SessionId to your own backend to verify and complete the order.

var sessionId = "dfc6a3c3-df09-44cb-9c6a-0a6375752da6"; // same value passed to mf.init above

function onPaymentComplete(response) {
    if (response && response.isSuccess === false) {
        // Payment failed or was cancelled — show an error, let the customer retry.
        return;
    }
    // Tell your backend the session is ready to be verified.
    fetch('/checkout/pay/ORD-2026-00073', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ session_id: sessionId }),
    })
    .then(r => r.json())
    .then(result => {
        if (result.success) window.location.href = result.redirect;
    });
}

6. Verify server-side with Session Details

From your backend, call GET /api/payment/session-details?SessionId=... and confirm, fail-closed, before marking anything paid:

  • The invoice status is Paid.
  • The customer reference matches the order you expect (from step 1's CustomerReference).
  • The paid amount matches the order's expected total.

Only then mark your order as paid. See the full request/response shape on the Session Details page.

👍 Why verify instead of trusting the callback: The callback runs in the customer's browser and can be replayed or spoofed. Session Details is the source of truth — it is your server talking directly to MyFatoorah's API with your token.

API Endpoints

The following endpoints are used for embedded integration:

Endpoint Method Description
/api/payment/create-session POST Create an embedded payment session (your settlement account is attached automatically)
/api/payment/session-details GET Verify a session's invoice status, reference, and amount server-side

Support

For more information and support, please contact the Royat Pay team.