Payment Gateway
Payments
Retrieve individual payment details or list payments with filters. Use the polling pattern with exponential backoff for real-time status checks.
Get a payment
GET
/gateway/payments/{id}Retrieve the full details of a payment including status, amounts, FX details, and timestamps. Use this to poll for payment completion.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | The payment ID (pay_...) returned when the checkout session was completed. |
curl -X GET https://wallet.e-mazad.store/api/v1/gateway/payments/pay_x1y2z3 \
-H "X-Api-Key: mk_your_key_id" -H "X-Api-Timestamp: $TIMESTAMP" -H "X-Api-Signature: $SIGNATURE"Response
{
"success": true,
"data": {
"id": "pay_x1y2z3",
"session_id": "cs_9f8e7d6c5b4a",
"status": "completed",
"amount": 25000,
"currency": "IQD",
"captured_amount": 25000,
"refunded_amount": 0,
"user_id": "mzd_usr_9f8e7d6c5b4a",
"external_user_id": "usr_12345",
"description": "Order #1234 - Premium Widget",
"reference": "order_1234",
"capture_mode": "automatic",
"fx_details": null,
"metadata": {
"order_id": "1234",
"sku": "widget-premium"
},
"authorized_at": "2026-03-20T14:31:00Z",
"captured_at": "2026-03-20T14:31:00Z",
"created_at": "2026-03-20T14:30:00Z",
"updated_at": "2026-03-20T14:31:00Z"
}
}Status values
| Status | Terminal? | Description |
|---|---|---|
| created | No | Payment created. Checkout URL has been sent to the customer. Awaiting payment. |
| reserved | No | Customer paid. Funds are held in escrow. Call /capture or /void to proceed. |
| completed | Yes* | Funds captured and settled to merchant wallet. *Can still be refunded. |
| cancelled | Yes | Voided before capture. Funds returned to customer. No settlement. |
| refunded | Yes | Fully refunded after capture. Funds returned to customer. |
| expired | Yes | Checkout expired (default: 30 min) before customer completed payment. |
List payments
GET
/gateway/paymentsList payments with optional filters. Returns paginated results sorted by creation date (newest first).
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| status | string | optional | Filter by status: created, reserved, completed, cancelled, refunded, expired. |
| user_id | string | optional | Filter by mazad_user_id or external_id. |
| reference | string | optional | Filter by your reference ID (exact match). |
| currency | string | optional | Filter by currency code (e.g., IQD, USD). |
| from | string | optional | Start date in ISO 8601 (e.g., 2026-03-01T00:00:00Z). |
| to | string | optional | End date in ISO 8601. |
| page | integer | optional | Page number. Defaults to 1. |
| per_page | integer | optional | Results per page. Max 100. Defaults to 20. |
curl -X GET "https://wallet.e-mazad.store/api/v1/gateway/payments?status=completed¤cy=IQD&per_page=10" \
-H "X-Api-Key: mk_your_key_id" -H "X-Api-Timestamp: $TIMESTAMP" -H "X-Api-Signature: $SIGNATURE"List response
{
"success": true,
"data": {
"payments": [
{
"id": "pay_x1y2z3",
"status": "completed",
"amount": 25000,
"currency": "IQD",
"reference": "order_1234",
"user_id": "mzd_usr_9f8e7d6c5b4a",
"created_at": "2026-03-20T14:30:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 10,
"total": 47,
"total_pages": 5
}
}
}Polling with exponential backoff
If you cannot use webhooks, poll the payment status with exponential backoff. Start at 1 second, double each attempt, cap at 30 seconds, and stop after 10 attempts.
async function pollPayment(paymentId, maxAttempts = 10) {
let delay = 1000; // Start at 1 second
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
const response = await fetch(
`https://wallet.e-mazad.store/api/v1/gateway/payments/${paymentId}`,
{
headers: { 'Authorization': 'Bearer sk_sandbox_abc123' },
}
);
const { data } = await response.json();
const terminal = ['completed', 'voided', 'refunded', 'failed', 'expired'];
if (terminal.includes(data.status)) {
return data; // Payment reached final state
}
console.log(`Attempt ${attempt}: status=${data.status}, retrying in ${delay}ms`);
await new Promise(resolve => setTimeout(resolve, delay));
delay = Math.min(delay * 2, 30000); // Double, cap at 30s
}
throw new Error('Payment did not reach terminal state');
}
// Usage
const payment = await pollPayment('pay_x1y2z3');
console.log(`Final status: ${payment.status}`);Prefer webhooks
Webhooks are more efficient than polling. Register a webhook URL in your dashboard and listen for
payment.completed, payment.failed, and other events.