Max SystemsMAXFIdeveloper hub
APIPayouts

Payouts API

Create payouts to a recipient’s bank card, read them and cancel them. The method field selects the payout method; today there is one method: card. A card payout returns payout_url: the recipient opens it and enters the card on a MAXFI page. Step by step: Card payouts.

MAXFI enables live card payouts for your account; until then POST /v2/payouts with a live key returns 403 card_payouts_not_enabled. Test keys work for every account and never reach a bank.

Keys and permissions

Use the same secret keys as for payments: Authorization: Bearer sk_live_… or sk_test_…. Restricted keys need payouts:read for GET requests and payouts:write for POST requests; payouts:write includes read. A key bound to a channel sees only the payouts of its channel. A test key sees only test payouts, a live key only live ones.

Make retries safe
There are two ways, and you can use both. Send a reference: a repeat with the same reference, amount and currency returns the existing payout instead of creating a second one; the same reference with a different amount or currency gets 409 reference_already_used. Or send an Idempotency-Key header with POST /v2/payouts and POST /v2/payouts/{id}/cancel: a successful response is stored for 24 hours and returned for a repeat with the same key, with the idempotent-replay: true header.

Create a payout

POST/v2/payouts
Authentication: sk_live_ / sk_test_. Secret API key. Use it only on your server.

Creates a payout and returns it with 201. A card payout starts in status pending with a payout_url for the recipient. In live mode the amount is held on your available balance (see Money and limits). The body is strict: a field that is not in the table below is rejected with 400 VALIDATION_ERROR, so card numbers cannot be sent.

FieldTypeDescription
method (required)string"card" — the only payout method today.
amount (required)integerAmount in minor units: 1500 = 15.00. A positive integer.
currency (required)string(3)Three-letter currency code. Card payouts accept only AZN; another currency gets 400 unsupported_currency.
referencestring(64)Your payout ID: 1–64 characters — letters, digits and _ . : -. A repeat with the same reference, amount and currency returns the existing payout.
descriptionstring(255)Your note, up to 255 characters. Not shown to the recipient.
metadataobjectYour key–value data: up to 20 keys and up to 4000 characters of JSON. Returned in the payout and in webhook events.
expires_inintegerLink lifetime in seconds. Values outside 900–604800 (15 minutes to 7 days) are moved to the nearest bound. If omitted, your account setting applies (24 hours by default).

Response: 201 with the payout object.

List payouts

GET/v2/payouts
Authentication: sk_live_ / sk_test_. Secret API key. Use it only on your server.

Returns your payouts, newest first, as {"object": "list", "data": [...], "has_more": true | false}. has_more is true when there are more payouts after this page.

ParameterTypeDescription
limitintegerPage size, 1–100. Default 20.
offsetintegerNumber of payouts to skip. Default 0.
statusstringOnly payouts with this status: pending, processing, succeeded, failed, canceled, expired or reversed. Another value gets 400 invalid_status.
curl "https://maxfi-api.exezine.az/v2/payouts?status=pending&limit=20" \
  -H "Authorization: Bearer sk_test_…"
← 200 OK
{
  "object": "list",
  "data": [
    {
      "id": "po_3f9c2a7b1d4e5f60718293ab",
      "object": "payout",
      "method": "card",
      "status": "pending",
      "amount": 1500,
      "currency": "AZN",
      "description": "Payout for order 1042",
      "reference": "order-1042",
      "metadata": { "order_id": "1042" },
      "payout_url": "https://maxfi-api.exezine.az/payout/<token>",
      "expires_at": "2026-11-14T12:00:00.000Z",
      "card": null,
      "recipient": null,
      "failure_code": null,
      "failure_message": null,
      "livemode": false,
      "created_at": "2026-11-13T12:00:00.000Z",
      "completed_at": null
    }
  ],
  "has_more": false
}

Get a payout

GET/v2/payouts/{id}
Authentication: sk_live_ / sk_test_. Secret API key. Use it only on your server.

Returns the payout object. A payout of another account, of the other mode or, for a channel-bound key, of another channel returns 404 payout_not_found.

Path parameter

ParameterDescription
{id}Payout ID: po_ and 24 hexadecimal characters.
curl https://maxfi-api.exezine.az/v2/payouts/po_3f9c2a7b1d4e5f60718293ab \
  -H "Authorization: Bearer sk_test_…"

Cancel a payout

POST/v2/payouts/{id}/cancel
Authentication: sk_live_ / sk_test_. Secret API key. Use it only on your server.

Cancels a payout that is still waiting for the recipient (pending) and returns it with status canceled and failure_code: "canceled". In live mode the held amount is released. A payout in any other status returns 409 payout_not_cancelable. MAXFI sends payout.canceled.

Path parameter

ParameterDescription
{id}Payout ID: po_ and 24 hexadecimal characters.
curl -X POST https://maxfi-api.exezine.az/v2/payouts/po_3f9c2a7b1d4e5f60718293ab/cancel \
  -H "Authorization: Bearer sk_test_…" \
  -H "Idempotency-Key: cancel-order-1042"

The payout object

Every endpoint above returns it. Webhook events carry the same object without payout_url.

FieldTypeDescription
idstringpo_ and 24 hexadecimal characters.
objectstringAlways "payout".
methodstring"card".
statusstringpending, processing, succeeded, failed, canceled, expired or reversed — see Statuses.
amountintegerAmount in minor units.
currencystring"AZN".
descriptionstring | nullYour note, or null.
referencestring | nullYour payout ID, or null.
metadataobjectYour metadata; {} if you sent none.
payout_urlstring | nullLink for the recipient. Filled while the status is pending, otherwise null. Whoever opens it can direct the payout to their own card: send it only to the recipient.
expires_atdatetimeWhen the link expires.
cardobject | null{ "bin": "424242", "last4": "4242" } — the first 6 and last 4 digits of the card once the recipient has entered it; before that null.
recipientobject | null{ "name": "…" } — the name on the card once the recipient has entered it; before that null.
failure_codestring | nullReason code when the status is failed, canceled or expired — see Failure codes; otherwise null.
failure_messagestring | nullShort explanation of failure_code in English, or null.
livemodebooleanfalse for test payouts.
created_atdatetimeWhen the payout was created (UTC).
completed_atdatetime | nullWhen the payout reached a final status, or null.
status: succeeded
{
  "id": "po_3f9c2a7b1d4e5f60718293ab",
  "object": "payout",
  "method": "card",
  "status": "succeeded",
  "amount": 1500,
  "currency": "AZN",
  "description": "Payout for order 1042",
  "reference": "order-1042",
  "metadata": { "order_id": "1042" },
  "payout_url": null,
  "expires_at": "2026-11-14T12:00:00.000Z",
  "card": { "bin": "424242", "last4": "4242" },
  "recipient": { "name": "Test Recipient" },
  "failure_code": null,
  "failure_message": null,
  "livemode": false,
  "created_at": "2026-11-13T12:00:00.000Z",
  "completed_at": "2026-11-13T12:03:41.198Z"
}

Errors

Errors have the same shape as in the rest of the API: {"error": {"code": "…", "message": "…", "request_id": "…"}}.

HTTPCodeReason
400VALIDATION_ERRORThe body or the query does not match the description above: a required field is missing, a value has the wrong type or range, or the body has an unknown field.
400invalid_referencereference has characters other than letters, digits and _ . : -.
400unsupported_currencyThe currency is not AZN.
400invalid_metadatametadata has more than 20 keys or more than 4000 characters.
400amount_too_largeThe amount exceeds the limit for one payout set for your account.
400daily_count_exceededLive mode: your account has reached its daily number of payouts.
400daily_amount_exceededLive mode: this payout would exceed the daily total for your account.
400invalid_statusGET /v2/payouts: status is not a payout status.
401UNAUTHORIZEDMissing or invalid API key.
402insufficient_balanceLive mode: your available balance does not cover the payout. Nothing was held; retry later, with the same reference if you like.
403FORBIDDENA live key before live mode is enabled for your account, or a restricted key without payouts:read / payouts:write.
403card_payouts_not_enabledLive card payouts are not enabled for your account.
404payout_not_foundNo payout with this ID in your account and mode.
409reference_already_usedA payout with this reference already exists with a different amount or currency.
409payout_not_cancelableThe payout is no longer pending.
409IDEMPOTENCY_IN_PROGRESSA request with the same Idempotency-Key is still being processed.
429RATE_LIMIT_EXCEEDEDMore than 100 requests in 60 seconds from your IP address.
503payouts_unavailablePayouts are temporarily unavailable. Nothing was held; retry later.

Webhooks

MAXFI sends payout.processing, payout.succeeded, payout.failed, payout.canceled, payout.expired and payout.reversed to your webhook URL — see Webhooks.

Payouts API · MAXFI Developer Hub