Skip to content

Payouts

Send money from your balance to a mobile-money number or bank account, and check who holds an account first.

Endpoint What it does
POST /v1/name-enquiries Look up who holds an account
POST /v1/payouts Create a payout
GET /v1/payouts/{id} Retrieve a payout

Try any of them in the API tester.

POST /v1/name-enquiries

Asks the bank or mobile-money network for the name on an account, before you pay out to it. The cheapest protection against a mistyped number: a payout to the wrong account cannot be recalled.

Send expected_name to have the answer compared for you; matches then says whether the holder is that person or business, ignoring case, punctuation, word order and middle initials.

Server-side only: a publishable key is refused, because the answer is a person’s name. A test key asks the sandbox, which echoes expected_name (or a fixed name); a number ending 0000 returns a different holder and one ending 9999 fails with partner_unavailable, so both branches can be tested.

Not every bank or network can be asked; those that cannot return 422.

Your pricing plan may set a fee per enquiry, shown on each response as fee_minor. Only an enquiry that returned a name is charged, from your available balance; if it cannot cover the fee the request is refused with 402 before anything is asked.

Authentication: a secret key (server-side only) with the scope verification.create.

Field Type Required Allowed values and limits What it is
account_number string yes at least 5 characters; at most 30 characters; e.g. 0244123456 The mobile-money number or bank account number.
bank string no at most 30 characters Required for bank unless bank_id is sent. Codes are at /v1/reference/banks.
bank_id string (uuid) no Alternative to bank; send one, not both.
channel string yes One of: mobile_money, bank What kind of account to ask about.
expected_name string no at most 200 characters; e.g. Ama Mensah Optional. The name you expect. When sent, the response says whether the holder matches it (case, punctuation, word order and middle initials are ignored).
momo_network string no at most 30 characters; e.g. mtn Required for mobile_money unless momo_network_id is sent. Codes are at /v1/reference/momo-networks.
momo_network_id string (uuid) no Alternative to momo_network; send one, not both.
Terminal window
curl -X POST https://sandbox.paysigna.com/v1/name-enquiries \
-H "Authorization: Bearer sk_test_…" \
-H "Content-Type: application/json" \
-d '{
"account_number": "0244123456",
"channel": "mobile_money",
"expected_name": "Ama Mensah",
"momo_network": "mtn"
}'
Field Type What it is
account_name string The holder’s name as the bank or network holds it, usually upper case.
account_number string As sent.
channel string
fee_currency string
fee_minor integer What this enquiry cost, in minor units of fee_currency. 0 when your plan makes enquiries free. Only an enquiry that returned a name is charged.
matches boolean Present only when expected_name was sent: whether the holder is that person or business.
object string
  • 400: the request is malformed
  • 401: the key is missing, wrong or revoked
  • 403: the key lacks the scope, or your account may not do this
  • 422: a field is invalid; errors names it
  • 429: too many requests; wait for Retry-After
  • 500: Internal Server Error
  • 503: the payment partner is unreachable; safe to retry

Every error is a JSON problem with a stable code. See Errors.


POST /v1/payouts

Sends money to a recipient over mobile money or a bank account.

YOUR BALANCE IS DEBITED WHEN THE PAYOUT IS CREATED, not when it completes. A payout that returns pending has already taken the funds out of your available balance.

Requires an Idempotency-Key header, and it matters more here than anywhere else in this API: a payout resent without one sends the money twice. A retry with the same key returns the original response.

If a request times out, READ the payout. Do not resend it. A timeout does not mean the money did not move, and the funds stay reserved until the partner tells us what happened.

The fee is always borne by you. amount is what the recipient receives; debited is what leaves your balance.

Authentication: a secret key (server-side only) with the scope payout.create.

Field Type Required Allowed values and limits What it is
Idempotency-Key string yes Unique per operation. Resend the same value to retry safely — this matters more here than anywhere else in the API, because a payout retried without it sends the money twice.
Field Type Required Allowed values and limits What it is
amount integer yes min 1; e.g. 1250 What the RECIPIENT receives, in minor units — 1250 is GHS 12.50. Your balance is debited by this plus the fee.
bank string no at most 30 characters The bank’s code. Required for bank unless bank_id is sent instead. Codes are listed at /v1/reference/banks?payout_only=true.
bank_branch_code string no at most 20 characters Required by some GhIPSS transfers.
bank_id string (uuid) no The bank’s id from /v1/reference/banks. An alternative to bank; send one, not both.
callback_url string (uri) no HTTPS only.
channel string yes One of: mobile_money, bank Where the money goes: mobile_money (a mobile-money wallet; send momo_network) or bank (a bank account; send bank). Payouts to a card are not supported.
currency string yes exactly 3 characters; e.g. GHS The currency of amount, as an ISO 4217 code such as GHS. Your balance in this currency is debited.
description string no at most 500 characters May appear on the recipient’s statement, depending on the rail.
metadata object no Returned unchanged on every read and webhook.
momo_network string no at most 30 characters; e.g. mtn The network’s code, such as mtn, telecel or airteltigo. Required for mobile_money unless momo_network_id is sent instead. Codes are listed at /v1/reference/momo-networks.
momo_network_id string (uuid) no The network’s id from /v1/reference/momo-networks. An alternative to momo_network; send one, not both.
recipient object yes
recipient.identifier string yes at most 100 characters; e.g. 0244123456 Mobile-money number or bank account number.
recipient.name string no at most 150 characters; e.g. Ama Mensah Strongly recommended. Some banks reject a transfer with no beneficiary name, and it is what appears on the recipient’s statement.
reference string no at most 100 characters Your own identifier for this payout.
Terminal window
curl -X POST https://sandbox.paysigna.com/v1/payouts \
-H "Authorization: Bearer sk_test_…" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": 1250,
"channel": "mobile_money",
"currency": "GHS",
"momo_network": "mtn",
"recipient": {
"identifier": "0244123456",
"name": "Ama Mensah"
}
}'
Field Type What it is
amount integer What the recipient receives, in minor units.
channel string Where the money was sent: mobile_money or bank.
completed_at string (date-time) When the payout reached a final state. Absent while it is in flight.
created_at string (date-time) When the payout was created.
currency string ISO 4217 code of every amount on this payout.
debited integer What was taken from your balance: the amount plus the fee.
failure_code string A machine-readable reason, present when the payout failed.
failure_message string Present when the payout failed. The funds have been returned to your balance.
fee object
fee.platform integer PaySigna’s payout fee, in minor units.
fee.tax integer Tax charged on the fee, in minor units.
id string The payout’s id. Read it at /v1/payouts/{id}.
metadata object The metadata you sent, unchanged.
object string
recipient object
recipient.masked string A partial identifier. The full value is never returned.
recipient.name string The recipient name you sent.
reference string PaySigna’s reference. Quote it to support.
status string pending or processing means in flight — your balance is already debited. Wait for the webhook or read the payout; do not resend it. One of: initiated, pending, processing, succeeded, failed, cancelled, expired
your_reference string The reference you sent when creating the payout.
  • 400: the request is malformed
  • 401: the key is missing, wrong or revoked
  • 402: your balance cannot cover it
  • 403: the key lacks the scope, or your account may not do this
  • 409: it conflicts with the current state, or the idempotency key was used for a different request
  • 422: a field is invalid; errors names it
  • 429: too many requests; wait for Retry-After
  • 500: Internal Server Error
  • 502: the payment partner refused it
  • 503: the payment partner is unreachable; safe to retry
  • 504: the partner timed out; read the resource before retrying

Every error is a JSON problem with a stable code. See Errors.


GET /v1/payouts/{id}

Reads a payout’s current state. This is the authority after a timeout: if a create request did not return, read the payout rather than resending it.

Authentication: a secret key (server-side only) with the scope payout.read.

Field Type Required Allowed values and limits What it is
{id} string (uuid) yes The payout’s id, as returned when it was created.
Field Type What it is
amount integer What the recipient receives, in minor units.
channel string Where the money was sent: mobile_money or bank.
completed_at string (date-time) When the payout reached a final state. Absent while it is in flight.
created_at string (date-time) When the payout was created.
currency string ISO 4217 code of every amount on this payout.
debited integer What was taken from your balance: the amount plus the fee.
failure_code string A machine-readable reason, present when the payout failed.
failure_message string Present when the payout failed. The funds have been returned to your balance.
fee object
fee.platform integer PaySigna’s payout fee, in minor units.
fee.tax integer Tax charged on the fee, in minor units.
id string The payout’s id. Read it at /v1/payouts/{id}.
metadata object The metadata you sent, unchanged.
object string
recipient object
recipient.masked string A partial identifier. The full value is never returned.
recipient.name string The recipient name you sent.
reference string PaySigna’s reference. Quote it to support.
status string pending or processing means in flight — your balance is already debited. Wait for the webhook or read the payout; do not resend it. One of: initiated, pending, processing, succeeded, failed, cancelled, expired
your_reference string The reference you sent when creating the payout.
  • 401: the key is missing, wrong or revoked
  • 403: the key lacks the scope, or your account may not do this
  • 404: no such resource on this account
  • 422: a field is invalid; errors names it
  • 429: too many requests; wait for Retry-After
  • 500: Internal Server Error
  • 503: the payment partner is unreachable; safe to retry

Every error is a JSON problem with a stable code. See Errors.