CleonPay

Payouts

Send money to an individual: winnings, seller balances, contractor pay.

A payout is not a refund. It goes to someone who may never have paid you, and it is a separate product with its own rails and rules.

Rails

MethodGoes toCurrenciesSpeedCan bounce
CPCard payout
card_payout
card Any Instant No
SEPA Instant
sepa_credit_transfer
bank account EUR Seconds (SCT Inst) Yes
Faster Payments
faster_payments
bank account GBP Seconds to two hours Yes
NPPAustralia (NPP)
au_npp
bank account AUD Seconds (NPP) Yes

1. Create a recipient

POST /v1/payout-recipients
{
  "type": "card",
  "first_name": "Ana",
  "last_name": "Silva",
  "date_of_birth": "1990-01-01",
  "country": "PT",
  "reference": "winner-001",
  "parent_payment_reference": "57-9-5091179"
}

A card recipient is created from a token issued by the provider, from a previous payment they made (the bank still holds the card, we hold a reference), or from the card number itself with its expiry, since some payout rails take the number directly. Card details are encrypted at rest and exist in memory only while the payout is being sent.

Required fields by rail

RailRequired recipient fields
Faster Paymentsfirst_name, last_name, sort_code (6 digits), account_number (8 digits)
SEPAfirst_name, last_name, iban, and the address: address_line1, city, postal_code, country
Card payoutfirst_name, last_name, date_of_birth, the card (card_number + expiry_month/expiry_year), and the address: address_line1, city, postal_code, country
Australia (NPP)first_name, last_name, bsb (6 digits), account_number, contact_phone, and the address: address_line1, city, postal_code, country (AU), country_subdivision (state, e.g. NSW)

SEPA and card payouts are refused with address_required (and card without a birth date with date_of_birth_required) if those are missing. Details are encrypted at rest; only the last four digits are kept readable.

2. Send the payout

POST /v1/payouts
{
  "recipient_id": "6d4ff39f-72fb-44c4-9e13-9c724683d40a",
  "method": "card_payout",
  "amount": 2500,
  "currency": "EUR",
  "reference": "PAYOUT-2026-0001"
}

States

created  →  submitted  →  sent  →  completed
                            │
                            ├──→  failed     (never left)
                            └──→  returned   (left, then came back)
returned is not failed. Failed means the money never left. Returned means it reached the recipient's bank and bounced, days later on SEPA, and your balance moved in between. Handle them differently.

Failure reasons

A failed or returned payout carries a failure object with a stable machine code and a human message. Branch on code and show the message. Treat any code you do not recognise as a plain failure — we may add more over time.

"failure": {
  "code": "insufficient_funds",
  "message": "The card has insufficient funds for this payout."
}
CodeMeaning
payout_declinedDeclined by the card issuer
insufficient_fundsThe card has insufficient funds
invalid_card_numberThe card number is invalid
invalid_detailsThe payout details are invalid
invalid_addressThe recipient address is invalid
unsupported_cardThe card does not support payouts
payout_not_permittedThe payout is not permitted for this card
restricted_cardThe card is restricted
security_declineDeclined for security reasons
authentication_requiredCardholder authentication was required
card_inactiveThe card is closed or not yet active
do_not_honorThe issuer declined (do not honor)
card_expiredThe card has expired or the expiry is incorrect
card_lost_or_stolenThe card was reported lost or stolen
temporarily_unavailableCould not complete right now — retry shortly
processing_errorA temporary processing error — retry

The amount is credited back to your balance whenever a payout fails. A returned payout (money that left and then bounced, on SEPA or Faster Payments) carries the bank's return reason on its returned object instead.

Prefunded balance

Payouts spend a balance you hold with us, one per rail and currency. A payout draws its matching account down by the amount plus any fee, and one an account cannot cover is refused with insufficient_balance: we never send money that was not funded. Read what each account holds from GET /v1/balance.

GET /v1/balance
GET /v1/payouts
GET /v1/payouts/{id}
GET /v1/payout-methods