Skip to content

Payouts

A payout sends money from the merchant’s payout balance to a mobile wallet or a bank account. A key prepares payouts and reads them; only a person approves or rejects one, in the merchant portal. In the sandbox every participant, destination and fee is synthetic, and no payout moves real money.

Three key scopes open the /v1 payout routes: payouts:read reads payouts, batches and their files, payouts:write makes name enquiries, payouts and batches and tops up the sandbox balance, and balance:read reads the payout balance. A key never approves or rejects a payout.

Only an Owner’s or an Admin’s delegation gives a key one of these scopes. The sandbox’s bootstrap key and keys issued by Futa’s staff hold none, and keys:manage alone never gives one: POST /v1/keys asking for a payout scope with such a key answers 403 SCOPE_ESCALATION.

GET /v1/balance with balance:read reads the balance in both currencies, never summed and never converted: available and reserved in integer minor units, each currency’s low-balance alert_threshold and below_alert, funded (false before any top-up reached it) and the merchant’s one funding_reference, PF-…. Collections and settlements never feed it. A payout or a batch reserves its money from available when it is submitted, and returns it there when it fails, is rejected or expires.

{
"schema_version": 1,
"merchant_id": "sandbox-merchant",
"funding_reference": "PF-3XW8-K2NB",
"balances": [
{
"currency": "CDF",
"available": 0,
"reserved": 0,
"alert_threshold": null,
"alert_version": 0,
"below_alert": false,
"funded": false
},
{
"currency": "USD",
"available": 100000,
"reserved": 18000,
"alert_threshold": 20000,
"alert_version": 1,
"below_alert": false,
"funded": true
}
],
"as_of": "2026-10-28T09:15:00Z",
"sandbox": true
}

In the sandbox, POST /v1/sandbox/payout-top-ups with payouts:write, a test key and an Idempotency-Key funds the balance with synthetic money: the sponsor simulator writes a credit notice carrying the merchant’s funding reference, and the balance shows the money once that notice is posted, never before, so read GET /v1/balance again. No real funding account, transfer or withdrawal exists in the sandbox.

{
"amount": 100000,
"currency": "USD"
}
{
"schema_version": 1,
"synthetic": true,
"notice_id": "SIM-SN-000000000001",
"funding_reference": "PF-3XW8-K2NB",
"amount": 100000,
"currency": "USD",
"credited_at": "2026-10-28T09:14:02.481233Z"
}

The same key and body fund once. 503 TOP_UP_UNAVAILABLE leaves the outcome unknown: send the same request again under the same key. A sandbox that gives the merchant API no simulator key answers every top-up so, and asks nothing.

The low-balance alert threshold is set in the merchant portal. Its alert shows there, and its « Solde de versement bas » notification is stored: nothing is sent by email or SMS yet.

Every payout names a name enquiry made for it within 24 hours. POST /v1/name-enquiries with payouts:write and an Idempotency-Key asks the participant who holds the destination, with the name you expect, or null:

{
"kind": "WALLET",
"participant": "simulator",
"destination": "+243810000001",
"expected_name": "SYNTHETIC HOLDER"
}

The answer gives status: FOUND, UNKNOWN_ACCOUNT, or UNAVAILABLE with the reason NOT_CONTRACTED. A name found is shown only masked, its first word whole and each other word as its first letter, with a verdict against the name expected: MATCH, DIFFERENT, UNAVAILABLE, or null when none was expected. A name that differs from the one expected, or that the participant could not give, is never shown, not even masked. The destination is never repeated. A check is kept 24 hours, until expires_at, and an enquiry within them answers that same check, with cached true.

{
"schema_version": 1,
"synthetic": true,
"id": "00000000-0000-4000-8000-000000000011",
"kind": "WALLET",
"participant": "simulator",
"destination_masked": "+243•••••0001",
"status": "FOUND",
"holder_name_masked": "SYNTHETIC H***",
"reason": null,
"expected_name_given": true,
"verdict": "MATCH",
"checked_at": "2026-10-28T09:20:11.204117Z",
"expires_at": "2026-10-29T09:20:11.204117Z",
"cached": false
}

Name enquiries have a budget, SYNTHETIC, over a rolling hour: at most 5 for one destination, 60 by one person or key and 300 for the merchant. An exact retry under its key counts once, and a batch’s lines, which the batch’s validation name-checks, count against none of them. Past a bound, 429 NAME_ENQUIRY_RATE_LIMITED answers with Retry-After, the seconds until every bound reached has room again.

POST /v1/payouts with payouts:write and an Idempotency-Key prepares the payout and submits it:

{
"kind": "WALLET",
"participant": "simulator",
"destination": "+243810000001",
"amount": 18000,
"currency": "USD",
"message": "Prime trimestrielle",
"merchant_reference": "PAIE-2026-10-017",
"name_enquiry_id": "00000000-0000-4000-8000-000000000011",
"acknowledge_unavailable_name": false
}
  • Amounts are integer minor units of their currency, from 1: cents in USD and centimes in CDF, where an amount is always whole francs, so a multiple of 100. 18050 is 180.50 dollars in USD; 1500000 is 15,000 francs in CDF, and 15000 only 150 francs.
  • Destinations are a wallet number, +243 and nine digits, for kind WALLET, or a bank account reference, SIM-BANK- and four digits in the sandbox, for kind BANK.
  • message is the payout’s motif, at most 100 characters, or null; merchant_reference is yours, 1 to 64 characters of letters, digits, _, ., / and -, or null.
  • acknowledge_unavailable_name is true only when the enquiry could not give the holder’s name: without it, such a payout answers 409 NAME_ACKNOWLEDGEMENT_REQUIRED, and with it after an enquiry that gave a name, 400 INVALID_REQUEST.

The payout’s amount and fee are reserved from the available balance as it is recorded, or it is refused with 409 INSUFFICIENT_PAYOUT_BALANCE and the shortfall, in minor units of its currency:

{
"error": {
"code": "INSUFFICIENT_PAYOUT_BALANCE",
"message_en": "The available payout balance does not cover this amount and its fees: the shortfall is stated. Nothing was reserved.",
"message_fr": "Le solde de versement disponible ne couvre pas ce montant et ses frais : il manque le montant indiqué. Rien n'a été réservé.",
"shortfall": {
"amount": 4500,
"currency": "USD"
}
}
}

Every payout route’s own refusal is this body, shortfall null but for that code; the key, scope, size, media type and quota refusals are the Error body, and a 400 INVALID_REQUEST may be either: the Error body when the request is refused before the payout route reads it, this body when the route or the switch refuses it. The other refusals of a payout are 404 NAME_ENQUIRY_NOT_FOUND, 409 NAME_ENQUIRY_STALE (the enquiry is more than 24 hours old), 409 PAYOUT_DESTINATION_UNKNOWN (the participant does not know the account), 409 PAYOUT_ROUTE_UNAVAILABLE (the participant takes no payouts at the moment), 409 MERCHANT_LIMIT_EXCEEDED (the per-payout limit, or the per-day limit, a day running from midnight to midnight in Kinshasa time, Africa/Kinshasa; both SYNTHETIC in the sandbox), 409 PAYOUTS_HELD (Futa holds the merchant’s payouts) and 409 IDEMPOTENCY_CONFLICT. The errors page lists them all by status.

Above the merchant’s approval threshold for its currency, a payout waits for a second person, PENDING_APPROVAL, its money reserved, for seven days at most; nothing is sent before it is approved. The threshold starts at zero, a zero nobody set, so every payout waits. Only the Owner sets a threshold: lowering it applies at once, while raising or removing it, the first threshold above zero included, is a proposal another Owner or Admin approves, with no exception for a merchant with a single Owner, and the proposal lapses after seven days (SYNTHETIC).

Approving and rejecting are done by a person, in the merchant portal, never through the API: an Owner or an Admin who neither prepared the payout nor is a holder of the key that prepared it, with a recent sign-in and a reason. A key’s holders are the people who created or rotated it, and, for a key made with another key, the holders of that key in turn. When key_holders.known is false, a holder of that key is not a known person and nobody can approve the payout; a rejection or the expiry still returns its money. A key that more than 50 people have held prepares no payout and no batch: its preparing commands are refused 400 INVALID_REQUEST.

This is the two-person rule, not a fault: a payout above the threshold always needs a second person, and one at or below it needs none. A merchant with a single Owner and no Admin, whose Owner prepares the payouts or holds the key that prepares them, can have none of those approved, nor raise the threshold alone, and each one expires after seven days, its money returned. Invite an Admin: one of the two then issues the key or prepares the payout and the other approves it, and the Admin approves the Owner’s threshold proposal. A Finance member can also prepare payouts in the portal for the Owner to approve.

A payout sent more than 24 hours after its name enquiry, as one approved later may be, has its name checked again first, as a batch’s line has: a different verdict stops it FAILED with NAME_CHANGED, nothing sent and its money returned, and while the participant gives no answer, or can no longer give the name, it stays QUEUED and the check is asked again: at each step, then, after three checks in a row without an answer, at most once a minute. Fifteen minutes after the first check without an answer, the payout is escalated to operations, its money still reserved until an answer comes or operations act (these three numbers are SYNTHETIC).

201 answers the payout as recorded, QUEUED or PENDING_APPROVAL. Read it with GET /v1/payouts/{id} and payouts:read, which is authoritative; GET /v1/payouts lists payouts newest first, 100 a page.

State Meaning
PENDING_APPROVAL Waiting for a second person in the portal, its money reserved.
QUEUED Recorded without waiting for approval, or approved: to be sent.
PROCESSING Sent to the participant, not yet final.
PAID The destination is credited; paid_at says when.
FAILED It failed, with its reason: the participant refused it (UNKNOWN_ACCOUNT, ACCOUNT_SUSPENDED, CREDIT_REFUSED), or Futa’s name check before sending found the name changed (NAME_CHANGED) and nothing was sent. Its money is available again.
UNCERTAIN The participant’s answer is not known yet: its money stays reserved, and it is never sent again under another key.
REJECTED Rejected by the approver. Its money is available again.
EXPIRED Not approved within seven days. Its money is available again.
{
"schema_version": 1,
"id": "00000000-0000-4000-8000-000000000021",
"reference": "PO-7G2K-9Q4M",
"merchant_id": "sandbox-merchant",
"kind": "WALLET",
"participant": "simulator",
"destination_masked": "+243•••••0001",
"name": {
"enquiry_id": "00000000-0000-4000-8000-000000000011",
"status": "FOUND",
"holder_name_masked": "SYNTHETIC H***",
"verdict": "MATCH",
"checked_at": "2026-10-28T09:20:11.204117Z",
"acknowledged_unavailable": false
},
"amount": 18000,
"fee": 0,
"total": 18000,
"reserved": 18000,
"currency": "USD",
"fee_policy": "synthetic-zero-fee-v1",
"message": "Prime trimestrielle",
"merchant_reference": "PAIE-2026-10-017",
"state": "PENDING_APPROVAL",
"reason": null,
"prepared_by": "key:00000000-0000-4000-8000-000000000004",
"key_holders": {
"known": true,
"holders": ["user:00000000-0000-4000-8000-000000000003"]
},
"threshold_version": 0,
"approval": {
"expires_at": "2026-11-04T09:21:30.112094Z",
"approved_by": null,
"rejected_by": null,
"decided_at": null,
"reason": null
},
"escalated": false,
"version": 1,
"created_at": "2026-10-28T09:21:30.112094Z",
"updated_at": "2026-10-28T09:21:30.112094Z",
"paid_at": null,
"sandbox": true
}

A batch pays many destinations in one currency. Through the API a key prepares it; a person approves it in the portal.

  1. Create it. POST /v1/payout-batches with payouts:write and an Idempotency-Key names its currency and how many lines will arrive, at most 100,000. It answers the batch, UPLOADED, with its PB-… reference. A merchant keeps at most 20 open batches, SYNTHETIC: past them, 409 PAYOUT_BATCH_TOO_LARGE. GET /v1/payout-batches/{id} reads a batch, and GET /v1/payout-batches lists them newest first, 100 a page.

    {
    "currency": "USD",
    "expected_lines": 3
    }
  2. Send its lines in chunks. POST /v1/payout-batches/{id}/lines takes at most 1,000 lines and 512 KiB a call, each line numbered within the batch, in its currency, its amount exact integer minor units. The chunk’s number, from 1 to the number of lines announced, keys it: the same chunk sent again changes nothing, whatever its key, and a chunk refused may be sent again with corrected lines under its number. These are the three lines of the file example below:

    {
    "chunk": 1,
    "lines": [
    {
    "number": 1,
    "kind": "WALLET",
    "participant": "simulator",
    "destination": "+243810000001",
    "expected_name": "SYNTHETIC HOLDER",
    "amount": 18000,
    "currency": "USD",
    "message": "Prime trimestrielle",
    "merchant_reference": "LIGNE-1"
    },
    {
    "number": 2,
    "kind": "WALLET",
    "participant": "simulator",
    "destination": "+243810000002",
    "expected_name": null,
    "amount": 25050,
    "currency": "USD",
    "message": "Salaire, octobre",
    "merchant_reference": "LIGNE-2"
    },
    {
    "number": 3,
    "kind": "WALLET",
    "participant": "simulator",
    "destination": "+243810000003",
    "expected_name": null,
    "amount": 1200,
    "currency": "USD",
    "message": null,
    "merchant_reference": null
    }
    ]
    }
  3. Follow its validation. Once every announced line has arrived, the batch is VALIDATING, then VALIDATED: each line is checked, its name included, and is VALID, REVIEW (to review) or EXCLUDED. A line whose issues are all among NAME_DIFFERENT, NAME_UNAVAILABLE, DUPLICATE_PAYOUT, DUPLICATE_REFERENCE and ROUTE_PAUSED is to review, waiting for the preparer’s decision; any other issue, INVALID_DESTINATION, ROUTE_UNAVAILABLE, INVALID_AMOUNT, MERCHANT_LIMIT_EXCEEDED, UNKNOWN_ACCOUNT, INVALID_EXPECTED_NAME, INVALID_MESSAGE or INVALID_REFERENCE, excludes the line until it is corrected. GET /v1/payout-batches/{id}/validation gives its progress, counts, what its valid lines would reserve and its issue lines, and GET /v1/payout-batches/{id}/lines its lines, masked, 1,000 a page, optionally of one state. GET /v1/payout-batches/{id}/report gives the validation report as a file from VALIDATED on, or once a batch never validated has LAPSED.

  4. Decide the lines to review. While the batch is VALIDATED, POST /v1/payout-batches/{id}/lines/{line}/decision takes ACCEPT, KEEP, REMOVE or CORRECT at the batch’s version. ACCEPT and KEEP apply only to a line to review, and are treated alike: either makes the line VALID, and the decision is recorded as sent. A ROUTE_PAUSED line, whose participant’s route was paused when it was checked, takes neither (409 PAYOUT_ROUTE_UNAVAILABLE): correct it once the route reopens, or remove it. A correction carries the line’s new values under its own number and is checked again.

    {
    "expected_version": 4,
    "decision": "REMOVE",
    "correction": null
    }
  5. Submit it. POST /v1/payout-batches/{id}/submit at the batch’s version sends it for approval. The total of its valid lines, amounts and fees, is reserved from the available balance, or it is refused with 409 INSUFFICIENT_PAYOUT_BALANCE and the shortfall; the batch is then PENDING_APPROVAL.

    {
    "expected_version": 5
    }
  6. A person approves or rejects it, in the portal. Every batch waits for a second person, whatever its total, for seven days at most, and nothing is sent before its approval. Four eyes hold: an Owner or an Admin approves or rejects it, with a recent sign-in and a reason, and never anyone who prepared it (whoever created it, sent a chunk, decided a line or submitted it) nor a holder of a key among them. A batch keeps at most 100 preparers and 50 key holders: a command that would add one more is refused 409 PAYOUT_BATCH_INVALID. Approved, it is APPROVED, PROCESSING, then COMPLETED once every line is final; otherwise REJECTED or EXPIRED, its money available again. A batch never submitted that stays seven days unchanged is LAPSED, SYNTHETIC, and never held money.

  7. Read its result. GET /v1/payout-batches/{id}/result gives the result file once the batch is COMPLETED, REJECTED, EXPIRED or LAPSED. The report and the result are written asynchronously: 202 with Retry-After while the file is being written, then the file; 409 RESULT_NOT_READY before the batch reaches the state it describes.

  8. Retry its failed lines. POST /v1/payout-batches/{id}/retry at the batch’s version (« Relancer ») makes a new batch, retry_of the first, of the lines the participant definitively refused, each linked to its original line and carrying its reference. The retry reserves nothing: its lines are checked again, then submitted, reserved and approved again as a new submission. An uncertain line is never retried; with no failed line left to retry, 409 PAYOUT_LINE_NOT_RETRYABLE.

futa-payout-batch-v1 is Futa’s own CSV template, labelled « modèle Futa » wherever it is offered: it is not a bank’s format, a regulator’s format or any standard’s. A person uploads it in the merchant portal, which also offers the template; the upload is a portal action, and a key sends the same lines as JSON through POST /v1/payout-batches/{id}/lines. The template is frozen as version 1: any change is a new template.

  • Encoding. UTF-8, with or without a byte-order mark.
  • Separator. A comma; a file separated by semicolons has no valid header.
  • Records. One per line, ending with a line feed or a carriage return and a line feed; the last line may end without one.
  • Quotes. A cell may be enclosed in double quotes, which lets it hold a comma; a double quote inside it is written twice.
  • Header. Exactly type,participant,numero,nom_attendu,montant,devise,motif,reference, in this order and in lower case.
  • Bounds. At least 1 line and at most 100,000; at most 16 MiB (16,777,216 bytes), the byte-order mark included.
  • One currency. Every line is in the file’s currency.
  • Cells as written. No cell is trimmed or reinterpreted.
  • Formulas. A cell holding a control character, or whose first character other than whitespace is =, +, - or @, is refused (UNSAFE_CELL): a negative amount is one.
Column Holds Becomes in the line
type wallet or bank, in lower case kind: WALLET or BANK
participant The participant’s code: simulator or synthetic-bank in the sandbox participant
numero A wallet number as its digits, without the plus sign (243810000001); a bank account reference (SIM-BANK-0001) destination: +243810000001, or the reference as written
nom_attendu Optional: the holder’s name you expect expected_name, or null when empty
montant The amount in the currency’s unit with a decimal point: at most two decimals in USD (180, 180.5, 180.50), none in CDF (15000) amount in minor units: 180.50 USD is 18050, 15000 CDF is 1500000
devise USD or CDF, in upper case currency
motif Optional: the payout’s message message, or null when empty
reference Optional: your own reference merchant_reference, or null when empty

A spreadsheet saves a long number such as 243810000001 as 2.4381E+11 unless its column is formatted as text: format numero as text before saving. A wallet number in its national form, 0810000001, is flagged on its line (INVALID_DESTINATION).

type,participant,numero,nom_attendu,montant,devise,motif,reference
wallet,simulator,243810000001,SYNTHETIC HOLDER,180.00,USD,Prime trimestrielle,LIGNE-1
wallet,simulator,243810000002,,250.5,USD,"Salaire, octobre",LIGNE-2
wallet,simulator,243810000003,,12,USD,,

A file that breaks the template is refused whole before any line is sent: 422 PAYOUT_FILE_INVALID with its first 100 problems, each with its line and column when it has them, and more_problems when there are more. A file over 16 MiB is refused 413 REQUEST_TOO_LARGE before it is read whole. Values the template reads, such as an unknown participant, an amount of zero or a different name, are judged on their line by the validation, never refusing the whole file. While the batch a file made is open, the same file sent again by the same person answers that batch, whatever key it comes under. Once the batch has ended, the same file sent under a new Idempotency-Key makes a new batch, validated and approved again; under the key it was first sent with, it still answers the batch it made until that key’s 720 hours are past, and is then refused 409 IDEMPOTENCY_CONFLICT.

The validation report and the result Futa writes are UTF-8 files with a byte-order mark, lines ending with a carriage return and a line feed, every cell quoted, and a cell that a spreadsheet would read as a formula written after an apostrophe. Destinations are masked and a holder’s name appears only masked, when it matched or none was expected.

  • The report, one row per line the validation flagged or the preparer decided: ligne,etat,problemes,decision,numero_masque,nom_masque,montant,devise.
  • The result, one row per line once the batch is finished: ligne,reference_futa,type,participant,numero_masque,montant,devise,motif,reference,etat,raison,ligne_relancee, where reference_futa is the line’s PB-…/NNNNNN and ligne_relancee names the original line of a retry’s line.
  • A lapsed batch has its report and its result written too, each listing only the lines it checked before it lapsed.

Every payout command takes an Idempotency-Key of 8 to 128 letters, digits, _ and -, scoped to the merchant and the key that sends it:

  • For 720 hours the same key with the same body answers the command’s first outcome, whatever happened since; the same key with another body answers 409 IDEMPOTENCY_CONFLICT.
  • After 720 hours a command sent again under its key is refused 409 IDEMPOTENCY_CONFLICT and never sent: the key is kept for ten years, so it never makes a second payout.
  • A lost reply, a timeout, 503 SWITCH_UNAVAILABLE or 503 TOP_UP_UNAVAILABLE, leaves the outcome unknown: send the same request again under the same key with the same body.
  • An uncertain outcome is never sent again under a new key: read the payout or the batch instead.

A chunk of lines is known by its batch and its number rather than by its key, a top-up funds once under its key, and keys starting with payout-batch- or payout-file-, which Futa makes for its own commands, are refused 400 INVALID_REQUEST. A decision, a submission and a retry each cover one line or batch at the version sent: reusing their key for another answers 409 IDEMPOTENCY_CONFLICT.

Payouts and batches send these events to the merchant’s webhook endpoint, signed as every event:

Event Sent by default When
payout.pending_approval No A payout waits for a second person.
payout.completed Yes A payout is paid (PAID).
payout.failed Yes A payout failed, with its reason.
payout.rejected No A payout was rejected by the approver.
payout.expired No A payout was not approved within seven days.
payout_batch.validated No A batch’s lines are checked, ready for decisions.
payout_batch.completed Yes Every line of a batch is final.

A payout event follows payout-event.schema.json and a batch event payout-batch-event.schema.json; payout-event.vectors.json and payout-batch-event.vectors.json hold recorded events. QUEUED, PROCESSING and UNCERTAIN send no event, and a batch’s lines send none of their own. An event carries key_holders.known alone: who holds which key stays behind authenticated reads. Deduplicate on the event’s id, apply a payout’s event only when its data.version is above the last applied for that payout, and read GET /v1/payouts/{id} or GET /v1/payout-batches/{id} when in doubt: an event is a notice, not the record.

{
"id": "00000000-0000-4000-8000-000000000031",
"type": "payout.completed",
"schema_version": 1,
"occurred_at": "2026-10-28T10:02:41.512903Z",
"data": {
"schema_version": 1,
"id": "00000000-0000-4000-8000-000000000021",
"reference": "PO-7G2K-9Q4M",
"merchant_id": "sandbox-merchant",
"kind": "WALLET",
"participant": "simulator",
"destination_masked": "+243•••••0001",
"name": {
"enquiry_id": "00000000-0000-4000-8000-000000000011",
"status": "FOUND",
"holder_name_masked": "SYNTHETIC H***",
"verdict": "MATCH",
"checked_at": "2026-10-28T09:20:11.204117Z",
"acknowledged_unavailable": false
},
"amount": 18000,
"fee": 0,
"total": 18000,
"reserved": 0,
"currency": "USD",
"fee_policy": "synthetic-zero-fee-v1",
"message": "Prime trimestrielle",
"merchant_reference": "PAIE-2026-10-017",
"state": "PAID",
"reason": null,
"prepared_by": "key:00000000-0000-4000-8000-000000000004",
"key_holders": {
"known": true
},
"threshold_version": 0,
"approval": {
"expires_at": "2026-11-04T09:21:30.112094Z",
"approved_by": "user:00000000-0000-4000-8000-000000000001",
"rejected_by": null,
"decided_at": "2026-10-28T10:01:12.004211Z",
"reason": "Prime validée"
},
"escalated": false,
"version": 4,
"created_at": "2026-10-28T09:21:30.112094Z",
"updated_at": "2026-10-28T10:02:41.512903Z",
"paid_at": "2026-10-28T10:02:41.512903Z",
"sandbox": true
}
}

A new endpoint is sent payout.completed, payout.failed and payout_batch.completed by default, beside the payment and refund events the webhooks guide lists; choose the others through its configuration. An endpoint registered before payout events were delivered keeps the events it had: add the payout events to it to receive them.

Payouts in the sandbox reach only the simulator’s synthetic participants: simulator, the test wallet (« Portefeuille simulé »), and synthetic-bank, the synthetic bank (« Banque simulée »). Six wallet numbers and six bank references choose how the participant answers a credit and a name enquiry; the bank reference with the same last digit answers as its wallet number.

Destination Credit Name enquiry
+243810000001, SIM-BANK-0001 Credited at once FOUND, SYNTHETIC H***
+243810000002, SIM-BANK-0002 Refused: UNKNOWN_ACCOUNT UNKNOWN_ACCOUNT
+243810000003, SIM-BANK-0003 Refused: ACCOUNT_SUSPENDED FOUND, another name: SYNTHETIC O*** H***, or DIFFERENT against SYNTHETIC HOLDER
+243810000004, SIM-BANK-0004 No answer until the simulator’s test control settles it, which no merchant key can do: the payout stays UNCERTAIN FOUND, SYNTHETIC H***
+243810000005, SIM-BANK-0005 Accepted, then credited 2 seconds later FOUND, SYNTHETIC H***
+243810000006, SIM-BANK-0006 Unavailable at the first send, credited when sent again under the same credit UNAVAILABLE, NOT_CONTRACTED: acknowledge it

A refused credit fails its payout with that reason. Any other well-formed destination is an account the simulator does not hold: its name enquiry answers UNKNOWN_ACCOUNT and its credit is refused so. A single payout is never prepared on an enquiry that found no account. The two names are synthetic and say so.

Every fee is the synthetic zero, fee_policy synthetic-zero-fee-v1, and every limit and threshold is SYNTHETIC: the merchant’s per-payout and per-day limits, the approval threshold starting at zero, the seven days of an approval and of a batch’s lapse, the 20 open batches and the name-enquiry budget. None of them is a production value.

  • XLSX. A workbook is refused with its reason (XLSX_NOT_ACCEPTED), and there is no « Modèle XLSX »: send CSV.
  • Saved templates. « Enregistrer comme modèle » and « Utiliser un modèle enregistré » are not built.
  • SMS to the recipient. A payout’s message is stored and carried to the participant; no SMS is sent.
  • Low-balance alerts by email or SMS. The alert shows in the merchant portal and its notification is stored; nothing is sent.