Skip to content

Payouts ​

Single payouts attempt submission during the request. API vendors do not need per-transaction operator approval.

POST /api/v1/payouts ​

Requires payouts:write. First read /account and /methods. Reserve the customer's balance in your own system before sending the request.

Voucher request ​

json
{
  "reference": "WD-VOUCHER-000123",
  "amount": "100.00",
  "currency": "ZAR",
  "method": "voucher_1voucher",
  "recipient": {
    "first_name": "Alex",
    "surname": "Example",
    "phone": "27821234567",
    "id_type": "Passport",
    "id_number": "EXAMPLE123",
    "country_of_issue": "ZW",
    "nationality": "ZW"
  },
  "metadata": { "withdrawal_id": "123" }
}

Cash request ​

json
{
  "reference": "WD-CASH-000124",
  "amount": "100.00",
  "currency": "ZAR",
  "method": "standard_bank_instant_money",
  "recipient": {
    "first_name": "Alex",
    "surname": "Example",
    "phone": "27821234567",
    "id_type": "Passport",
    "id_number": "EXAMPLE123",
    "country_of_issue": "ZW",
    "nationality": "ZW"
  }
}

Bank transfer request ​

json
{
  "reference": "WD-BANK-000125",
  "amount": "100.00",
  "currency": "ZAR",
  "method": "rtc_eft",
  "recipient": {
    "first_name": "Alex",
    "surname": "Example",
    "phone": "27821234567",
    "id_type": "Passport",
    "id_number": "EXAMPLE123",
    "country_of_issue": "ZW",
    "nationality": "ZW",
    "bank_account": {
      "bank_name": "Standard Bank",
      "account_name": "Alex Example",
      "account_number": "0000000000",
      "branch_code": "051001"
    }
  }
}

Use real recipient details in your integration. The bank account above is a placeholder, not a destination for testing live transfers.

Request rules ​

  • reference is your idempotency key, unique per vendor across individual and batch items. It must match ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,99}$. The Idempotency-Key HTTP header is not used. Keep the same body and reference for a retry; changed payloads return 409 REFERENCE_CONFLICT.
  • A replay uses the existing record and reservation. It can submit an item that has never been attempted, but never repeats a provider submission. It returns the current outcome, not necessarily the original HTTP response.
  • amount is a string with exactly two decimal places, no sign or leading zeros except 0.xx, and at most eight digits before the decimal point. Currency must be ZAR. The effective method minimum, maximum, increment and vendor daily cap also apply. Daily caps count face value, using the gateway's configured calendar date.
  • Cash methods require multiples of 10.00. RTC EFT and vouchers accept cents. Do not round a customer's requested amount without their agreement.
  • Names are at most 80 characters. first_name and surname are required; middle_name is optional and nullable.
  • recipient.id_type is RSAID or Passport. id_number must be alphanumeric and at most 30 characters. RSAID additionally requires 13 digits and a valid checksum. Countries must be recognised uppercase ISO alpha-2 codes.
  • recipient.phone is exactly 27 followed by nine digits, without + or spaces.
  • email is optional and nullable, with at most 150 characters. date_of_birth is optional and nullable, formatted YYYY-MM-DD, before today. Its value is stored but never sent to the payment provider.
  • bank_account is required for RTC EFT. For other methods it may be omitted or null. When present, all four fields are required: bank and account names up to 100 characters, account number 4 to 40 digits, branch code six digits. Use strings to preserve leading zeros. No bank ID field is accepted.
  • metadata is an optional flat object with at most 50 non-numeric keys. Values may be strings, numbers, booleans or null. Each value's string form must fit 2,000 bytes. Nested objects and arrays are rejected. Metadata is stored and echoed, never forwarded to the provider.
  • The generated merchant_reference is a separate FLUXR_PO_... identifier used with the provider. provider_reference is the provider's identifier; for vouchers it is a Flash gateway transaction UUID. Use your own reference for API lookups. This API does not guarantee bank-statement narration.

Successful response ​

Example 200 for a paid voucher with a token that lacks delivery access:

json
{
  "success": true,
  "data": {
    "id": "01990000-0000-7000-8000-000000000001",
    "reference": "WD-VOUCHER-000123",
    "status": "paid",
    "status_reason": null,
    "method": "voucher_1voucher",
    "amount": "100.00",
    "fee": "0.00",
    "currency": "ZAR",
    "merchant_reference": "FLUXR_PO_01990000000070008000000000000001",
    "provider_reference": "01990000-0000-7000-8000-000000000002",
    "delivery": null,
    "metadata": { "withdrawal_id": "123" },
    "created_at": "2026-09-19T10:00:00+00:00",
    "paid_at": "2026-09-19T10:00:02+00:00",
    "reversal_reconciliation": null
  }
}

200 does not always mean paid. Cash and bank payouts can return pending, with paid_at: null; a replay of a reversed payout can return reversed. Definitive rejection returns 422 with an error envelope. An uncertain outcome returns 409 PENDING_CONFIRMATION, without a payout object. Retrieve the payout using the same reference. RTC settlement timing is not guaranteed.

delivery is populated only for paid payouts when the token also has payouts:delivery. Otherwise it is null. The separate delivery endpoint still requires that scope; it is not a way to bypass access restrictions.

reversal_reconciliation is null until finance posts a verified return to the append-only vendor ledger. When present it contains ledger_reference, returned_minor in cents, currency (ZAR), verified_by and verified_at. This is the actual returned amount, which can exclude fees or some principal. Raw reversed status alone is never evidence that money was returned. Internal statement notes remain private; the ledger reference identifies the audit record.

GET /api/v1/payouts/{reference} ​

Requires payouts:read. Read the current payout using your original vendor reference. URL-encode reserved characters in path references. This lookup reads stored state. Background workers check the provider; this request does not trigger a provider lookup or another payment.

For pending or PENDING_CONFIRMATION, keep the hold and poll this endpoint. Never send a replacement payment while the outcome is uncertain. See statuses and errors.

PayoutRequest fields ​

reference is the vendor idempotency key; the Idempotency-Key header is not used. Replay the same body and reference. RTC EFT requires recipient.bank_account. API creation requires automatic dispatch. A 200 response can be pending; only paid confirms payment.

FieldTypeRequiredDetails
referencestringYesPattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,99}$
amountstringYesPattern: ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$; Must meet effective method limits and increment, and the vendor daily cap.
currencystringYesZAR
methodstringYesstandard_bank_instant_money, nedbank_cardless, rtc_eft, voucher_1voucher, voucher_ott, voucher_blu, voucher_easyload
recipientRecipientYes
metadataMetadataOptional

Recipient fields ​

FieldTypeRequiredDetails
first_namestringYesMaximum characters: 80
middle_namestring or nullOptionalMaximum characters: 80
surnamestringYesMaximum characters: 80
phonestringYesPattern: ^27[0-9]{9}$
id_typestringYesRSAID, Passport
id_numberstringYesMaximum characters: 30; Pattern: ^[A-Za-z0-9]+$; RSAID also requires 13 digits and a valid checksum.
country_of_issuestringYesPattern: ^[A-Z]{2}$; Recognised uppercase ISO alpha-2 country code.
nationalitystringYesPattern: ^[A-Z]{2}$; Recognised uppercase ISO alpha-2 country code.
emailstring or nullOptionalMaximum characters: 150; Format: email
date_of_birthstring or nullOptionalFormat: date; YYYY-MM-DD before today. Stored for records; its value is never sent to the provider.
bank_accountobject or nullOptionalRequired and non-null for rtc_eft; otherwise optional. All four bank fields are required when supplied.

BankAccount fields ​

FieldTypeRequiredDetails
bank_namestringYesMaximum characters: 100
account_numberstringYesPattern: ^[0-9]{4,40}$
account_namestringYesMaximum characters: 100
branch_codestringYesPattern: ^[0-9]{6}$

Metadata fields ​

Optional flat object, at most 50 non-numeric keys. Values are scalar or null, with at most 2,000 bytes when converted to strings. Never forwarded to providers.

Payout fields ​

FieldTypeRequiredDetails
idstringYes
referencestringYes
statusstringYespending, paid, failed, reversed, needs_review, cancelled
methodstringYesstandard_bank_instant_money, nedbank_cardless, rtc_eft, voucher_1voucher, voucher_ott, voucher_blu, voucher_easyload
amountstringYesPattern: ^(0|[1-9][0-9]*)\.[0-9]{2}$
feestringYesPattern: ^(0|[1-9][0-9]*)\.[0-9]{2}$
merchant_referencestringYes
provider_referencestring or nullYes
status_reasonstring or nullYes
deliveryobject or nullYes
metadataMetadataYes
created_atstringYesFormat: date-time
paid_atstring or nullYesFormat: date-time
reversal_reconciliationobject or nullYes
currencystringYesZAR