Max SystemsMAXFIdeveloper hub
DocsCard payouts

Card payouts

A payout sends money from your MAXFI balance to a person’s bank card. One API serves all payout methods — /v2/payouts — and the method field selects the method. Today there is one method: "card". Payouts use the same secret keys as payments (sk_live_…, sk_test_…) and the same webhook URL and signature.

Live payouts are enabled per account
MAXFI switches on live card payouts for your account. Until then, creating a payout with a live key returns 403 card_payouts_not_enabled. Test mode (sk_test_…) works for every account. To enable live payouts, contact MAXFI.

How it works

  1. Your server creates a payout: POST /v2/payouts with "method": "card", an amount and a currency. The response has "status": "pending" and a payout_url.
  2. You send payout_url to the recipient, for example by email or in your app.
  3. The recipient opens the link and enters the card number and the name on the card on a MAXFI page. The page shows the amount and the name of your business. The card number never passes through your systems.
  4. MAXFI sends the transfer to the bank (payout.processing) and then reports the result: payout.succeeded or payout.failed.

If the recipient does not enter a card before expires_at, the payout becomes expired. The link is valid for 24 hours unless your account has a different setting; expires_in changes it for one payout (in seconds, from 15 minutes to 7 days). While a payout is pending, you can cancel it.

1. Create a payout

Send method, amount in minor units (1500 = 15.00) and currency — card payouts accept only AZN. Optional fields: reference (your payout ID), description, metadata and expires_in. All fields and errors are in the API reference.

POST /v2/payouts
curl https://maxfi-api.exezine.az/v2/payouts \
  -H "Authorization: Bearer $MAXFI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout-order-1042" \
  -d '{
    "method": "card",
    "amount": 1500,
    "currency": "AZN",
    "reference": "order-1042",
    "description": "Payout for order 1042",
    "metadata": { "order_id": "1042" }
  }'

The response is 201 with the payout. Send payout_url to the recipient: the field is filled while the payout is pending and is null afterwards.

← 201 Created
{
  "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
}

2. Follow and cancel

Webhooks tell you when the status changes. You can also read a payout with GET /v2/payouts/{id} or list payouts with GET /v2/payouts. To cancel a payout before the recipient enters a card, call POST /v2/payouts/{id}/cancel; after that the recipient can no longer enter a card.

# Read one payout
curl https://maxfi-api.exezine.az/v2/payouts/po_3f9c2a7b1d4e5f60718293ab \
  -H "Authorization: Bearer $MAXFI_SECRET_KEY"

# Payouts that are still waiting for the recipient, newest first
curl "https://maxfi-api.exezine.az/v2/payouts?status=pending&limit=20" \
  -H "Authorization: Bearer $MAXFI_SECRET_KEY"

# Cancel a payout while it is pending
curl -X POST https://maxfi-api.exezine.az/v2/payouts/po_3f9c2a7b1d4e5f60718293ab/cancel \
  -H "Authorization: Bearer $MAXFI_SECRET_KEY"

Money and limits

  • In live mode, creating a payout holds the amount on your available balance. The hold is charged when the payout succeeds and released when it fails, is canceled or expires.
  • If your available balance does not cover the payout, the API answers 402 insufficient_balance and holds nothing. You can retry later with the same reference.
  • MAXFI sets limits for your account: the maximum amount of one payout (400 amount_too_large), and the number and total amount of payouts per day (400 daily_count_exceeded, 400 daily_amount_exceeded). Daily limits apply in live mode only.
  • In live mode, MAXFI screens every recipient before the transfer. A payout declined by this check fails with payout_declined; MAXFI does not disclose the reason.
  • The bank can return a transfer after it succeeded: the payout then becomes reversed. The returned amount is not added back to your balance automatically — contact MAXFI support.

Statuses

StatusMeaningWebhook event
pendingWaiting for the recipient to enter a card. payout_url is filled only in this status.—
processingThe recipient entered a card and MAXFI sent the transfer to the bank. The result is not known yet.payout.processing
succeededThe transfer succeeded: the money was sent to the recipient’s card.payout.succeeded
failedThe transfer did not go through. See failure_code.payout.failed
canceledYou canceled the payout before the recipient entered a card.payout.canceled
expiredThe link expired before the recipient entered a card.payout.expired
reversedThe bank returned the transfer after it had succeeded.payout.reversed

Failure codes

failure_code and failure_message are filled when the status is failed, canceled or expired. failure_message is a short explanation in English.

CodeMeaning
card_declinedThe card issuer declined the transfer.
expired_cardThe card has expired.
insufficient_balanceYour available balance did not cover the payout (live mode).
payout_declinedMAXFI declined the payout after checking the recipient. No details are given.
processing_errorThe payout could not be processed.
link_expiredThe recipient did not enter a card before the link expired (status expired).
canceledYou canceled the payout (status canceled).
test_card_requiredTest mode accepts only test cards.

Webhooks

  • MAXFI sends payout.processing, payout.succeeded, payout.failed, payout.canceled, payout.expired and payout.reversed to the same webhook URL as payment events and signs them the same way. data holds the payout object without payout_url.
  • Select the payout events in the merchant portal under Developer Hub → Webhooks: events that are not selected are not sent.
  • Each event type is queued at most once per payout. A delivery can still be repeated, for example after a timeout, so skip event IDs you have already processed. See Webhooks.

Test mode

With a test key (sk_test_…) payouts never reach a bank and do not touch your balance, and they carry "livemode": false. Open payout_url and enter one of these cards with any name made of letters, for example “Test Recipient”.

CardResult
4242 4242 4242 4242Success.
5555 5555 5555 4444Success.
4000 0000 0000 0002Declined: card_declined.
4000 0000 0000 0069Expired card: expired_card.
4000 0000 0000 0119Stays processing, then succeeds — at least 20 seconds later, usually within two minutes.
4000 0000 0000 0259The connection is lost: the payout stays processing, then fails with card_declined — at least 20 seconds later, usually within two minutes.
  • Any other card is rejected in test mode: the page shows an error and the payout stays pending.
  • Daily limits do not apply in test mode; the limit for one payout does.

Security

  • payout_url works like a key. Whoever opens it can direct the payout to their own card. Send it only to the intended recipient, over a channel you trust. Webhook events do not include it.
  • The API does not accept card numbers: POST /v2/payouts rejects unknown fields with 400 VALIDATION_ERROR. After the recipient enters a card you get only its first 6 and last 4 digits (card.bin, card.last4) and the name on the card (recipient.name).
  • Make retries safe. A repeat with the same reference, amount and currency returns the existing payout instead of creating a second one; different parameters get 409 reference_already_used. POST /v2/payouts and POST /v2/payouts/{id}/cancel also accept the Idempotency-Key header — see the API conventions.
Card payouts — send money to a recipient’s card · MAXFI Developer Hub