FX & Currency
When a payment involves two different currencies (e.g., user wallet is in USD but merchant charges IQD), Mazad handles the conversion automatically. This page explains how FX works, how to preview rates, and how to interpret the fx_details object.
How FX conversion works
Checkout session is created
You specify amount and currency (e.g., 25,000 IQD). This is the settlement currency.
Popup opens
If the user wallet is in a different currency (e.g., USD), Mazad fetches a live rate and shows the converted amount.
Rate is locked
When the user confirms, the rate is locked for that transaction. The quoted amount is what gets debited.
Settlement
The merchant receives exactly the original amount in the original currency. FX margin is applied to the user side.
The fx_details object
When a payment involves currency conversion, the payment response includes an fx_details object with full conversion details.
{
"payment_id": "pay_x1y2z3",
"amount": 25000,
"currency": "IQD",
"status": "completed",
"fx_details": {
"source_currency": "USD",
"source_amount": 1705,
"target_currency": "IQD",
"target_amount": 25000,
"rate": 1466.275,
"inverse_rate": 0.000682,
"margin_percent": 1.5,
"quote_id": "fxq_a1b2c3d4",
"quoted_at": "2026-03-20T14:30:00Z",
"expires_at": "2026-03-20T14:32:00Z",
"locked": true
}
}fx_details fields
| Name | Type | Required | Description |
|---|---|---|---|
| source_currency | string | required | The currency debited from the user wallet. |
| source_amount | integer | required | Amount debited from user in smallest unit of source currency. |
| target_currency | string | required | The settlement currency (what the merchant receives). |
| target_amount | integer | required | Amount credited to merchant in smallest unit of target currency. |
| rate | number | required | The applied exchange rate (target per 1 unit of source). |
| inverse_rate | number | required | Inverse of rate (source per 1 unit of target). |
| margin_percent | number | required | FX margin applied as a percentage. Typically 1-2%. |
| quote_id | string | required | Unique ID for this FX quote. Use for dispute resolution. |
| quoted_at | string | required | When the rate was fetched (ISO 8601). |
| expires_at | string | required | When the quoted rate expires if not locked. |
| locked | boolean | required | True if the rate has been locked (user confirmed payment). |
Preview exchange rates
Use this endpoint to display indicative exchange rates in your UI before the user starts a checkout.
/embedded/fx/ratesGet current exchange rates for all supported currency pairs. Rates are indicative and may change by the time a transaction is confirmed.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| base | string | optional | Base currency code (e.g., USD). If omitted, returns all pairs. |
| target | string | optional | Target currency code (e.g., IQD). If omitted, returns all targets for the base. |
| amount | integer | optional | If provided, returns the converted amount alongside the rate. |
curl -X GET "https://wallet.e-mazad.store/api/v1/embedded/fx/rates?base=USD&target=IQD&amount=1000" \
-H "Authorization: Bearer sk_sandbox_abc123"Response
{
"success": true,
"data": {
"rates": [
{
"base": "USD",
"target": "IQD",
"rate": 1466.275,
"inverse_rate": 0.000682,
"margin_percent": 1.5,
"converted_amount": 1466275,
"quoted_at": "2026-03-20T14:30:00Z",
"ttl_seconds": 120
}
]
}
}Quote TTL
Exchange rates from the /fx/rates endpoint are indicative and have a time-to-live (TTL).
Indicative quotes: 120 seconds
Rates returned by GET /embedded/fx/rates are valid for 120 seconds. After that, you should fetch a fresh rate.
Checkout quotes: locked on confirmation
When a user opens the checkout popup, a fresh rate is fetched. The rate is locked (guaranteed) the moment the user taps "Pay Now". The locked rate does not expire.
Stale popup rates
If the popup stays open for more than 2 minutes without confirmation, the rate refreshes automatically. The user sees a brief "Updating rate..." indicator.
Same-currency payments skip FX
fx_details field will be null in the payment response.