Skip to content
NovaroPayDocs
PSP-Version 2026-10-25.acacia
Theme
Merchant portal(opens in a new tab)

Payouts

A payout sends money from your available balance to a bank account you name, as Stripe’s payouts do. In Argentina that is a CVU, a CBU or an alias.

  1. You create a payout with POST /payouts. Its amount and the payout fee of your agreement are held from your available balance at once, and the payout is pending. You get the webhook event payout.created.
  2. We send it from one of our accounts. While it is being sent it is processing.
  3. It ends paid once the recipient’s bank took it, or failed; then you get payout.paid or payout.failed. A failed payout’s amount and fee are back in your available balance, and failure_code says why.

Rarely we cannot tell at once whether a transfer went through: the payout is then requires_review, you get payout.requires_review, and our team checks it with the bank. It ends paid or failed, and nothing is sent twice.

A payout belongs to the merchant account whose key made it: another account’s key does not see it, and an Idempotency-Key is the account’s.

Live mode is not open yet. A live key’s POST /payouts is 409 payouts_not_available, and nothing is held: make test payouts with your test key meanwhile. Live payouts open with an announcement in the Changelog.

Status
pending Created: the amount and fee are held. Not sent yet; you may cancel it.
processing Being sent.
paid The recipient’s bank took it. The fee is taken.
failed Not sent, or refused by the bank: failure_code says why. The amount and fee are back in your available balance.
requires_review Our team is checking whether it went through. It ends paid or failed.
canceled You canceled it while it was pending. The amount and fee are back in your available balance.

New statuses may be added: treat one you do not know as not paid.

Create a payout
curl https://api.63-180-91-99.sslip.io/payouts \
-H "Authorization: Bearer sk_test_ar_…" \
-H "Idempotency-Key: 3f2b8c1e-7d4a-4b9e-9a6c-2e1d5f4c3b2a" \
-H "Content-Type: application/json" \
-d '{
"amount": 2500000,
"currency": "ARS",
"destination": { "type": "cvu", "cvu": "0000003100000000000017" },
"recipient": { "tax_id": { "type": "ar_cuit", "value": "20-12345678-6" } },
"description": "Withdrawal 4821",
"metadata": { "user_id": "u_4821" }
}'
  • amount is what the recipient’s account receives, in the currency’s smallest unit (centavos). The payout fee is held beside it: more than you have available is 400 balance_insufficient, and nothing is made.

  • destination is the account: its type and that field alone.

    • cvu: 22 digits, starting 000, with their check digits.
    • cbu: 22 digits with their check digits.
    • alias: 6 to 20 letters, digits, dots and dashes, read in lower case.

    A destination that is not one of its type is 400 parameter_invalid with param: destination; a type your market’s payouts do not take, param: destination.type.

  • recipient.tax_id is optional: the account’s holder, as a payment’s customer.tax_id (ar_cuit, ar_cuil or ar_dni). When you send it, the account’s holder is checked against it before anything is sent, and a payout to another holder fails with recipient_tax_id_mismatch.

  • Send an Idempotency-Key. The same key again answers the same payout, Idempotent-Replayed: true, and holds nothing more; the key with other parameters is 400 idempotency_error.

The answer is 201 with the payout:

{
"id": "po_ar_01JB4R7X9K2M5N8P3Q6S9T1V4W",
"object": "payout",
"status": "pending",
"market": "AR",
"amount": 2500000,
"currency": "ARS",
"fee": 25000,
"destination": { "type": "cvu", "alias": null, "last4": "0017" },
"recipient": { "tax_id": { "type": "ar_cuit", "value": "20-•••••678-6" } },
"failure_code": null,
"description": "Withdrawal 4821",
"metadata": { "user_id": "u_4821" },
"created": 1761213600,
"ended_at": null,
"livemode": false,
"version": 1
}

A payout answers its destination back by the account number’s last four digits, or the alias, and the recipient’s tax id masked.

POST /payouts/{id}/cancel cancels a payout that is still pending: its amount and fee are back in your available balance, and you get payout.canceled. One that is being sent or has ended is 409 payout_not_cancelable. Canceling a canceled payout answers it as it is.

failure_code
recipient_account_not_found No account has that CVU, CBU or alias.
recipient_tax_id_mismatch The account’s holder is not the recipient.tax_id you sent.
transfer_rejected The bank refused the transfer.

More codes may be added.

A test key makes test payouts from your test balance, as live ones are made, and none is ever sent anywhere. Instead, the last two digits of the amount (in minor units: centavos) decide what happens to it, the way magic UTRs do a test payment’s. Each change is the one a live payout gets on that path: its status, its balance lines and its webhook events.

Amount ends in What happens
01 (e.g. 2500001) processing, then paid at once.
02 processing, then failed at once: recipient_account_not_found.
03 processing, then failed at once: recipient_tax_id_mismatch.
04 processing, then failed at once: transfer_rejected.
05 processing, then requires_review at once, then paid 5 seconds after it was made.
06 Stays pending until you cancel it.
Anything else processing at once, then paid 5 seconds after it was made.

“At once” means within a second or two: read the payout again, or wait for its events. A failed test payout’s amount and fee are back in your test balance, as a live one’s are. A test payout that cannot be sent in the test environment stays pending, or, once on its way, fails with transfer_rejected. Live mode has no magic amounts.

Endpoints

  • GET /payoutsListPayouts
  • POST /payoutsCreatePayout
  • GET /payouts/{id}GetPayout
  • POST /payouts/{id}/cancelCancelPayout

Loading the reference…