Inline checkout

Inline checkout embeds Mamo's payment form directly on your page inside an <iframe>, so the customer pays without being redirected to a hosted Mamo page. You create an inline payment link, then mount its payment URL into a container element using Mamo's checkout script.

📘

When to use inline vs. hosted

Use inline checkout when you want the card form to appear on your own page. If you don't need the form embedded, create a standard (standalone) link and redirect the customer to its payment_url instead — that path is simpler and needs no script.

1. Create an inline payment link

Call POST /links with link_type: "inline". The response's payment_url is the URL you hand to the checkout script.

curl -X POST https://business.mamopay.com/manage_api/v1/links \
  -H "Authorization: Bearer <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Order #1234",
    "amount": 150.00,
    "amount_currency": "AED",
    "link_type": "inline",
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "[email protected]",
    "return_url": "https://yourstore.com/checkout/complete",
    "failure_return_url": "https://yourstore.com/checkout/failed",
    "external_id": "1234"
  }'

For sandbox, use the base URL https://sandbox.dev.business.mamopay.com/manage_api/v1/links with your sandbox API key.

The response includes a payment_url of the form:

https://business.mamopay.com/inline-widget/pay/<slug>

(In sandbox it is served from https://sandbox.dev.business.mamopay.com/inline-widget/pay/<slug>.) This differs from a hosted link, whose payment_url points at /pay/<slug>. Keep this URL for step 2.

⚠️

Set link_type, not is_widget

To create an inline link you must send link_type: "inline". Sending is_widget: true produces a modal link, not an inline one.

Customer details are collected by you, not the iframe

The inline iframe renders the payment form only — it does not render a customer-details step (name / email collection). Collect those details on your own page and pass them at link creation via first_name, last_name, and email (they are stored as the link's prefilled customer and used for the charge). All three are optional at the API level and are validated only for format when present.

2. Embed the checkout script

You can embed the widget two ways.

Auto-init with a container element

Add the script, then a <div id="mamo-checkout"> whose data-src holds the payment_url from step 1. On window.onload the script looks for an element with id mamo-checkout, and if it exists, constructs new MamoPay() and calls addIframeToWebsite("mamo-checkout", <data-src value>) for you.

<head>
  <script src="https://assets.mamopay.com/stable/checkout-inline-2.0.0.min.js"></script>
</head>

<body>
  <div id="mamo-checkout" data-src="https://business.mamopay.com/inline-widget/pay/<slug>"></div>
</body>

Manual init

To mount into a different element, or at a time you control, construct MamoPay yourself and call addIframeToWebsite with the container's id and the payment_url.

<head>
  <script src="https://assets.mamopay.com/stable/checkout-inline-2.0.0.min.js"></script>
</head>

<body>
  <div id="mamo-checkout-element"></div>

  <script>
    const mamoPay = new MamoPay();
    mamoPay.addIframeToWebsite("mamo-checkout-element", paymentLink);
  </script>
</body>

The JavaScript API, as served by the script above:

CallDescription
new MamoPay()Constructs the helper. Takes no arguments.
addIframeToWebsite(elementId, paymentUrl)Injects an <iframe> into the element with id elementId. If no element with that id exists it logs an error to the console and returns without doing anything. Pass the payment_url returned by POST /links.

The injected iframe has id iframe-mamo-checkout, is set to width: 100%; height: 100%, and is given allow="payment" and crossorigin="anonymous".

The iframe src and the consumer parameter

addIframeToWebsite builds the iframe src by appending your current page URL as a consumer query parameter:

iframe.src = `${paymentLinkUrl}?consumer=${encodeURIComponent(window.location.href)}`

So the iframe loads, for example, https://business.mamopay.com/inline-widget/pay/<slug>?consumer=https%3A%2F%2Fyourstore.com%2Fcheckout. The consumer value is the encoded URL of the parent page embedding the widget.

📘

Script version

checkout-inline-2.0.0.min.js is the version referenced by the Mamo dashboard's Developer page at the time of writing. Pin to the version you have tested and confirm the latest stable filename with Mamo before upgrading.

3. Handle the result

There is no JavaScript success/failure callback. The script does not expose an onSuccess / onComplete hook. What it does do is register a single window.addEventListener("message", ...) handler on your page (after the iframe loads) and act on a fixed set of messages posted from the iframe.

Before handling any message, the script checks that event.origin equals Mamo's payment domain (the scheme + host of the payment_url you passed in). Messages from any other origin are ignored. This origin check gates message handling only — it is not a check on your embedding page's hostname and does not prevent the iframe from rendering. The iframe is always appended and loaded.

The messages it handles:

MessageEffect
"closeIframe"Hides the iframe (display: none).
"checkout-complete"Hides the iframe. This is the completion signal — the script does not redirect your page on completion.
"connectionEstablished"Handshake; logged to the console.
{ type: "confirmation_required", payload }Hides the iframe and runs window.location.replace(payload) — a top-window redirect used for 3-D Secure authentication.
⚠️

checkout-complete does not redirect to return_url

On a completed payment the script only hides the iframe. The only navigation the script performs is the 3-D Secure confirmation_required redirect above. It does not navigate the top window to return_url or failure_return_url on success or failure.

Because there is no success callback and no success redirect in the script, the authoritative success signal for your backend is the webhook (and/or checking the charge directly):

  • Webhooks. Mamo sends server-to-server webhooks for the charge — payment.succeeded / payment.failed. Treat the webhook as the source of truth for fulfilment. Match it back to your order using the external_id you set on the link.
  • Charge lookup. You can also query the charge via the API to confirm its status.

What the iframe renders

The iframe shows the card (and, where enabled, Apple Pay / Google Pay) entry form and the total amount (on the pay button / wallet sheet). It does not render an itemized breakdown — no fee, VAT, subtotal, or line items. If you want to show an order summary or fee breakdown, draw it yourself on your page, outside the iframe.

Content Security Policy and allowed domains

If your site sends a Content Security Policy, allow Mamo's domains so the script loads and the iframe can be framed:

DirectiveAllow
script-srchttps://assets.mamopay.com
frame-src / child-srchttps://business.mamopay.com (production), https://sandbox.dev.business.mamopay.com (sandbox)

The inline widget page intentionally does not send X-Frame-Options, so it can be embedded on your domain.


Did this page help you?