DeriPayDeriPayDocs
DeriPayDeriPayDocs
Merchant dashboardBuild with DeriPay

Getting started

QuickstartAuthenticationEnvironments

Integration guides

Limits and input formatsIdempotency and retriesPayment lifecycleWebhooksTest your integration

API reference

Create a collectionCreate a payoutRetrieve a paymentRead balances
Errors and troubleshooting

Merchant API · v1

Endpoints

Create a payout

POST /disbursements: send M-Pesa from your merchant payout balance.

Endpoint

POST /api/v1/disbursements

Required scope: disbursements:write. Include X-API-Key, Content-Type: application/json, and Idempotency-Key.

Request body

FieldTypeRequiredDescription
amount_minorintegerYesKES cents, divisible by 100. Between 100 and 25000000, subject to merchant limits.
currencystringYesKES
methodstringNob2c; also used when omitted
phonestringYesRecipient's Kenyan M-Pesa mobile number
referencestringNoBusiness reference, up to 80 UTF-8 bytes after trimming
quoted_fee_minorintegerNoExpected total withdrawal fee in cents, including the KES 10 service fee

Approved recipient restrictions and daily limits apply. Unknown and duplicate JSON fields are rejected.

Example request

curl --fail-with-body "$DERIPAY_API_BASE_URL/disbursements" \
  -H "X-API-Key: $DERIPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout-2026-000123" \
  --data '{"amount_minor":10000,"currency":"KES","method":"b2c","phone":"254712345678","reference":"PAYOUT-000123"}'

Response

A new payout returns 202 Accepted with {"data": payment, "replayed": false}. An idempotent replay returns 200 OK with replayed: true.

The payment object has kind: "disbursement", method: "b2c", its ID, current status, amount, calculated fees, phone, reference, shortcode, and timestamps. See the payment object.

Check payout funds

Read GET /balance before showing payout availability. The request must be covered by both merchant funds and merchant-owned payout liquidity, including applicable fees. A balance response is a snapshot, not a reservation.

MERCHANT_INSUFFICIENT_FUNDS returns HTTP 409. Do not blindly retry it. Recheck the balance and resolve funding first.

Fees

Admission reserves amount_minor + fee_minor + provider_fee_minor. The recipient receives amount_minor; the total withdrawal fee is an additional merchant charge. Every total below includes a KES 10 service fee.

Withdrawal amount (KES)Base fee (KES)Service fee (KES)Total fee (KES)
1–10001010
101–50071017
501–1,000131023
1,001–1,500231033
1,501–2,500331043
2,501–3,500531063
3,501–5,000571067
5,001–7,500781088
7,501–10,0009010100
10,001–15,00010010110
15,001–20,00010510115
20,001–35,00010810118
35,001–50,00012510135
50,001–75,00015010160
75,001–100,00017510185
100,001–125,00020010210
125,001–150,00022510235
150,001–175,00025010260
175,001–200,00027510285
200,001–225,00030010310
225,001–250,00032510335

provider_fee_minor records the actual configured M-Pesa B2C business cost. fee_minor records Deripay's retained portion: total withdrawal fee minus that provider cost. The base fee in the table is part of the customer tariff, not an additional provider charge. Do not add any other fee to the table total.

For example, a KES 500 payout (amount_minor: 50000) has a KES 17 total fee: fee_minor: 1200 and provider_fee_minor: 500. It reserves 51700 cents and accepts quoted_fee_minor: 1700. A mismatched quote returns 409 MERCHANT_CONFLICT.

Idempotent retries must retain the original quote and body, even if the fee table has since changed.

Handle pending outcomes

On 202, save the payment ID and wait for confirmation. Poll with disbursements:read or receive a signed terminal webhook.

Do not replace uncertain payouts

If the status is unknown or the create request times out, do not submit a new payment with a different idempotency key. The original may still complete.

There is no public cancellation endpoint for accepted payouts. Revoking an API key does not cancel them.

Create a collection

POST /collections: request an M-Pesa STK push.

Retrieve a payment

GET /collections/:id or /disbursements/:id: read the current payment status.

On this page

EndpointRequest bodyExample requestResponseCheck payout fundsFeesHandle pending outcomes