Appearance
How payments work
Read this page before you go live. It covers the rules that every payin and payout follows.
Statuses
A payment starts when Payd accepts your request and ends in success or failed.
| Status | Meaning | What to do |
|---|---|---|
pending | Payd accepted the request and is about to send it. | Wait. |
processing | The network has the request. A customer may still be looking at the prompt. | Wait for the webhook, or check the status. |
success | The money moved. | Fulfil the order or mark the payout as paid. |
failed | The payment did not happen. The customer cancelled, the network declined, or the payout could not be delivered. | Show the customer what to do next. A failed payout is refunded to your balance. |
success and failed are final. A payment never moves out of them.
Card payments have one more step. A card payment reaches success when the customer pays, and Payd holds the money for a short period in case of a chargeback. When Payd releases it to your balance, you get a webhook with status settled. See cards.
References
Every payment has two references.
| Reference | Who sets it | Where you see it |
|---|---|---|
Payd reference, such as 9BD103350408eR | Payd | gateway_response.merchant_reference in the response, reference in webhooks, transaction_ref in status |
Your reference, such as order-8842 | You, in payment_config.reference | external_reference in webhooks |
Payd references end in eR for collections and eW for payouts. Use the Payd reference to check status. Store both, side by side, so you can match a webhook to your order.
Payd does not check that your reference is unique. It is yours to keep unique.
Amounts and currencies
- Send
amountin the currency of the person paying or being paid: KES for M-Pesa in Kenya, UGX for Uganda, XOF for Senegal, and so on. - Send whole numbers for mobile money. Networks do not take cents.
- Each network has a minimum and maximum. Payment options by country lists them, and a quote shows the fee for a given amount.
- Payd keeps your account balance in US dollars and converts each payment at the rate in force when it runs. A quote shows that rate.
For Côte d'Ivoire, Senegal, Benin and Togo (XOF) and Cameroon (XAF), several countries share one currency. Always send country so Payd knows where the money is going.
Wallets
Your Payd account has two balances, which the balances endpoint shows:
wallet_type | Balance |
|---|---|
fiat (default) | Your main balance. |
crypto | Your USD stablecoin balance. |
Payins credit, and payouts debit, the balance you name in wallet_type. Leave it out to use fiat.
Reading responses
- Field names are
snake_case. Payd also acceptslowerCamelCasein requests. - Responses include every field, so empty values come back as
"",0orfalse. - Large whole numbers, such as page counts, come back as strings:
"count": "42". Parse them as numbers. - Times are RFC 3339 strings in UTC, such as
2026-10-16T11:42:03Z. - Responses can carry more fields than these docs list. Ignore any field the docs do not describe: it may change without notice.
- Payd ignores fields it does not know in your request. A misspelt field name is dropped without an error, so check names against the docs.
Retries and duplicates
Send an idempotency_key with every payin and payout. It is a string you choose, up to 100 characters, such as your order id or a UUID. It goes at the top level of the request body, next to amount:
json
{
"idempotency_key": "order-8842-attempt-1",
"amount": 1500,
"currency": "KES"
}If Payd has already seen that key on your account:
- With the same request, Payd sends back the first response and does not charge or pay again. Resending after a timeout is safe.
- With a different request, Payd answers
409duplicate_conflict:this idempotency_key was already used for a different payment. Use a new key for a new payment. - If the first payment failed, Payd answers
409duplicate_conflictwith a message that it failed and its reference. Use a new key to try again. - If the first request is still running, Payd answers
409duplicate_conflictwith a message that it is still being processed and its reference. Check its status before you try again.
"The same request" means the same kind of payment (payin or payout), amount, currency, account number and wallet. Keys belong to your account. Never reuse one for another payment.
Without a key, Payd does not merge repeated requests. If you send the same payin twice, the customer gets two prompts. If you send the same payout twice, Payd pays twice. So without a key, never resend without checking first:
- If you got a response with a
merchant_reference, the request went through. Do not send it again. Check its status. - If the request timed out or you got a
5xx, the payment may still exist. Search your payment requests for the customer's phone number or account number from the last few minutes. - Send a new request only when you are sure the first one does not exist, and give it a new reference of your own.
Payd itself never retries a payin or payout on your behalf.
Timeouts
Payd answers payin and payout requests within 30 seconds. Set your HTTP client timeout to at least 35 seconds. Most other endpoints answer within 15 seconds.
Request ids
Every response has an X-Request-Id header, and error bodies repeat it as request_id. Log it. When you contact support about a request, send the request id with the time.
You can send your own X-Request-Id header, and Payd uses it for that request.
Who is paying
Collections by mobile money outside Kenya and by bank transfer carry the paying customer's details: customer.document_type and document_number for their ID, dob, email and address. Nigerian collections also need a BVN or NIN. M-Pesa in Kenya needs only the name and phone number. See mobile money and bank transfers.
Payouts need only the recipient's name and account. Payd uses your own account's identity details for the rest.
Before your first payout
Payouts move money out of your balance, so Payd checks three things first:
- Balance. The balance must cover the amount and the fee. Otherwise you get
400insufficient_balance. - Withdrawal PIN. The person who owns the API key must have set a withdrawal PIN in the Payd Money App. API payouts do not ask for the PIN, but they fail until one is set.
- Identity checks. Payouts to some countries need the account holder's identity details to be complete in the Payd Money App. Payd tells you in the error message when this is missing.

