Sandbox mode — Use https://wallet.e-mazad.store/api/v1 as your base URL
Embedded WalletKey Integration

Checkout Popup

The Checkout Popup is a pre-built, Mazad-hosted payment UI that opens as an overlay on your website. Users confirm payment from their embedded wallet without leaving your page.

Payment flow

1

Your server creates a checkout session

POST /embedded/checkout/sessions with amount, currency, and user ID. You receive a session_token.

2

Your frontend opens the popup

Call MazadCheckout.open({ sessionToken }) in the browser. A modal overlay appears.

3

User reviews and confirms

The popup shows the amount, merchant name, and balance. User taps "Pay Now" or enters their PIN.

4

Mazad processes the payment

Funds are debited from the user wallet and held in escrow (or settled immediately, depending on your config).

5

Popup closes, callback fires

The onSuccess / onError callback fires in your frontend. A webhook is sent to your server.

1. Install the JS SDK

Add the Mazad Checkout script to your HTML. This exposes the global MazadCheckout object.

<!-- Add before closing </body> tag -->
<script src="https://cdn.mazad.com/checkout/v1/mazad-checkout.min.js"></script>

2. Create a checkout session

Create a session on your server. This returns a short-lived token that your frontend uses to open the popup.

POST/embedded/checkout/sessions

Create a new checkout session. The session token expires after 30 minutes if not used.

Request Body

NameTypeRequiredDescription
user_idstringrequiredThe mazad_user_id or external_id of the payer.
amountintegerrequiredPayment amount in smallest currency unit (e.g., 25000 = 25 IQD).
currencystringrequiredISO 4217 currency code. Must match a currency the user wallet supports.
descriptionstringoptionalShown to the user in the popup. Max 256 characters.
referencestringoptionalYour order/invoice ID. Returned in webhooks for reconciliation.
capture_modestringoptional"automatic" (default) settles immediately. "manual" places a hold requiring a later capture call.
redirect_urlstringoptionalURL to redirect after payment in mobile browsers where popup is not supported.
metadataobjectoptionalArbitrary key-value pairs passed through to webhooks. Max 20 keys.
expires_inintegeroptionalSession TTL in seconds. Min 300 (5 min), max 1800 (30 min). Default 1800.
curl -X POST https://wallet.e-mazad.store/api/v1/embedded/checkout/sessions \
  -H "Authorization: Bearer sk_sandbox_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "usr_12345",
    "amount": 25000,
    "currency": "IQD",
    "description": "Order #1234 - Premium Widget",
    "reference": "order_1234",
    "capture_mode": "automatic",
    "metadata": {
      "order_id": "1234",
      "sku": "widget-premium"
    }
  }'

Session response

{
  "success": true,
  "data": {
    "session_id": "cs_9f8e7d6c5b4a",
    "session_token": "cs_live_tok_a1b2c3d4e5f6g7h8i9j0",
    "amount": 25000,
    "currency": "IQD",
    "status": "pending",
    "expires_at": "2026-03-20T15:00:00Z",
    "payment_id": null,
    "created_at": "2026-03-20T14:30:00Z"
  }
}

3. Open the popup

In your frontend, call MazadCheckout.open() with the session token returned from your server.

// After receiving session_token from your backend
MazadCheckout.open({
  sessionToken: 'cs_live_tok_a1b2c3d4e5f6g7h8i9j0',

  // Optional: customize appearance
  theme: 'light',       // 'light' | 'dark' | 'auto'
  locale: 'ar',         // 'ar' | 'en' | 'ku'

  // Callbacks
  onSuccess: function(result) {
    console.log('Payment succeeded!', result.payment_id);
    // result.payment_id   - "pay_..."
    // result.amount       - 25000
    // result.currency     - "IQD"
    // result.reference    - "order_1234"

    // Redirect to success page or update UI
    window.location.href = '/order/1234/success';
  },

  onError: function(error) {
    console.error('Payment failed:', error.code, error.message);
    // error.code     - "insufficient_funds" | "session_expired" | ...
    // error.message  - Human-readable error

    showErrorToast(error.message);
  },

  onClose: function() {
    // User closed the popup without completing payment
    console.log('Popup closed by user');
  },
});

Popup screens

The checkout popup guides the user through a simple two-step flow. Here is what each screen looks like:

Screen 1: Review Payment
+----------------------------------+
|          Mazad Checkout           |
|                                  |
|   [Your Brand Logo]              |
|                                  |
|   Pay to: Acme Store             |
|   Amount: 25,000 IQD             |
|   Description: Order #1234       |
|                                  |
|   Wallet Balance: 150,000 IQD    |
|                                  |
|   +----------------------------+ |
|   |        Pay Now             | |
|   +----------------------------+ |
|                                  |
|   Secured by Mazad Wallet        |
+----------------------------------+
Screen 2: Confirm with PIN
+----------------------------------+
|          Confirm Payment          |
|                                  |
|   Amount: 25,000 IQD             |
|                                  |
|   Enter your 4-digit PIN:        |
|                                  |
|       [ * ] [ * ] [   ] [   ]    |
|                                  |
|   +---  ---  ---  ---  ---  ---+ |
|   | 1 || 2 || 3 || 4 || 5 || 6| |
|   +---  ---  ---  ---  ---  ---+ |
|   | 7 || 8 || 9 ||   || 0 || <| |
|   +---  ---  ---  ---  ---  ---+ |
|                                  |
|   Forgot PIN?                    |
+----------------------------------+
Screen 3: Success
+----------------------------------+
|                                  |
|            [Checkmark]           |
|                                  |
|       Payment Successful!        |
|                                  |
|       25,000 IQD                 |
|       to Acme Store              |
|                                  |
|   Ref: pay_x1y2z3               |
|                                  |
|   +----------------------------+ |
|   |          Done              | |
|   +----------------------------+ |
|                                  |
+----------------------------------+
Screen 4: Insufficient Funds
+----------------------------------+
|                                  |
|              [X]                 |
|                                  |
|       Insufficient Funds         |
|                                  |
|   Your balance is 10,000 IQD     |
|   but 25,000 IQD is required.    |
|                                  |
|   +----------------------------+ |
|   |        Top Up Wallet       | |
|   +----------------------------+ |
|   +----------------------------+ |
|   |          Cancel            | |
|   +----------------------------+ |
|                                  |
+----------------------------------+

Branding

Customize the popup appearance from your Mazad merchant dashboard. The following options are available:

SettingDescription
LogoYour brand logo displayed at the top of the popup. Recommended: 200x60px PNG with transparent background.
Brand colorPrimary button color. Must meet WCAG AA contrast ratio against white text.
Merchant nameDisplayed as "Pay to: {name}" in the review screen.
Support URLLink shown in error screens so users can contact your support team.

Security model

Session tokens are single-use

Each session token can only be used once to open the popup. After the popup closes (success, error, or dismissal), the token is invalidated.

Popup runs on Mazad domain

The popup iframe loads from checkout.mazad.com. Your page never has access to the user PIN or wallet credentials.

Amount is server-defined

The payment amount is locked when you create the session on your server. The frontend cannot modify it. This prevents client-side tampering.

Always verify server-side

Do not trust the onSuccess callback alone. Always verify the payment status via the webhook or by polling GET /embedded/payments/{id} from your server.

Never trust the frontend

The onSuccess callback is a UX convenience for showing the user a success message. Always confirm the payment status from your backend via webhook or API polling before fulfilling the order.