API reference
Base URL: https://maxfi-api.exezine.az. Authenticate with your secret key in Authorization: Bearer sk_test_… (or sk_live_…); the X-API-Key header with the same key also works. Requests and responses are JSON. A request body can be up to 1 MB.
Keys starting with sk_test_ work in test mode: no money moves, and responses carry "livemode": false. sk_live_ keys work after MAXFI enables live mode for your account; before that they get 403. Restricted keys (rk_live_, rk_test_) can call only the endpoints their permissions allow. A test key sees only test payments and checkout sessions, a live key only live ones. The test_mode field cannot switch the mode: a value that contradicts the key returns 400 TEST_MODE_MISMATCH. In test mode, steps that a bank or wallet would show open a MAXFI test page where you choose the result; the payment gets that result and you receive the webhook, as in live mode — see Quickstart.
Rate limit: 100 requests per 60 seconds per client IP address. Above it the API answers 429 RATE_LIMIT_EXCEEDED.
| Method | Path | Description |
|---|---|---|
| POST | /v2/payments/checkout | Create a session on the MAXFI payment page and redirect the customer to it. |
| GET | /v2/payments/checkout/{id} | Get a checkout session and its status. |
| POST | /v2/payments | Create a payment from your server with the payment method data. If you send card details yourself, your systems are in PCI DSS scope. |
| GET | /v2/payments/{id} | Get a payment by its ID (pay_… or cs_…). |
| GET | /v2/payments | List your payments with filters and pagination. |
| POST | /v2/payments/{id}/capture | Capture an authorised payment, fully or partially. |
| POST | /v2/payments/{id}/void | Cancel an authorisation that has not been captured. |
| POST | /v2/payments/{id}/refund | Refund a payment, fully or in parts. |
| POST | /v2/payouts | Create a payout to a recipient’s card. The response has a link for the recipient, who enters the card on a MAXFI page. |
| GET | /v2/payouts | List your payouts, newest first. |
| GET | /v2/payouts/{id} | Get a payout by its ID (po_…). |
| POST | /v2/payouts/{id}/cancel | Cancel a payout that is still waiting for the recipient. |
| GET | /v1/balance | Balances per currency: available, pending and reserve. |
| GET | /v1/balance/transactions | Your succeeded and refunded payments, newest first: test ones for a test key, live ones for a live key. |
| GET | /v2/health | Service status. No authentication. |
Channels are described on Channels, the browser widget on Widget SDK, payouts on Card payouts, events on Webhooks. Every endpoint and field is listed in the OpenAPI spec.
Conventions
- Amounts — Integers in minor units:
4900= 49.00. No decimals. - Currencies — ISO 4217 codes:
AZN,USD,EUR,RUB. - Timestamps — Strings with a time zone. Payments (
created_atandupdated_atinGET /v2/paymentsandGET /v2/payments/{id}) use ISO 8601 in UTC withZ(2026-11-13T07:30:00.000Z);GET /v1/balance/transactionsuses an offset (2026-11-13 11:30:00.123+04). Read the zone instead of assuming UTC. - Idempotency — Send an
Idempotency-Keyheader (up to 255 characters) withPOST /v2/payments,POST /v2/payments/checkout,POST /v2/payments/{id}/capture,POST /v2/payments/{id}/void,POST /v2/payments/{id}/refund,POST /v2/payoutsandPOST /v2/payouts/{id}/cancel. A repeat with the same key and the same request (method, path and body; the order of fields does not matter) within 24 hours returns the stored response with its status code and theidempotent-replay: trueheader. Only responses with a 2xx status are stored: after an error the same key can be used again. The same key with a different request gets409 IDEMPOTENCY_KEY_REUSED; a repeat while the first request is still running gets409 IDEMPOTENCY_IN_PROGRESS; a key longer than 255 characters gets400 IDEMPOTENCY_KEY_TOO_LONG. Use a new key for each new operation. Other endpoints ignore the header.POST /v2/paymentsand refunds also accept anidempotency_keyfield in the body: a repeat of the same request returns the stored response with its status code and theidempotent-replay: trueheader, and a different request gets409 IDEMPOTENCY_KEY_REUSED. Unlike the header, the body field does not reject a parallel repeat, so prefer the header. - IDs —
cs_…— checkout session; payments made on the payment page use it as their ID.pay_…— payment created withPOST /v2/payments.po_…— payout.evt_…— webhook event. - Errors — Error responses look like
{"error": {"code": "…", "message": "…", "request_id": "…"}}; every one of them carriesrequest_id. Quote it when you contact support.
