Chapa
Payouts

Create B2B Payout

Move balance to another Chapa merchant.

Send balance to another Chapa merchant without a bank transfer.

POST /v2/payouts/b2b
Host: api.chapa.global
Authorization: Bearer <PRIVATE_KEY>
Content-Type: application/json
Idempotency-Key: <UNIQUE_OPERATION_KEY>

Required fields are merchant_id (recipient) and amount (integer cents, minimum 100). Optional fields are currency, merchant_reference (maximum 20 characters), and meta.

Replace YOUR_RECIPIENT_MERCHANT_ID in the example with the actual recipient merchant ID.

Example Request

For cURL, set PRIVATE_KEY in your shell. Set IDEMPOTENCY_KEY for this operation and reuse it on retries. Replace the placeholders in the JavaScript example before running it.

JSON
{
  "merchant_id": "YOUR_RECIPIENT_MERCHANT_ID",
  "amount": 10000,
  "currency": "ETB",
  "merchant_reference": "ref-1791192600",
  "meta": {
    "batch": "OCT-01"
  }
}
cURL
curl -X POST 'https://api.chapa.global/v2/payouts/b2b' \
  -H "Authorization: Bearer $PRIVATE_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "merchant_id": "YOUR_RECIPIENT_MERCHANT_ID",
  "amount": 10000,
  "currency": "ETB",
  "merchant_reference": "ref-1791192600",
  "meta": {
    "batch": "OCT-01"
  }
}'
JavaScript
const response = await fetch("https://api.chapa.global/v2/payouts/b2b", {
  method: "POST",
  headers: {
  "Authorization": "Bearer <PRIVATE_KEY>",
  "Idempotency-Key": "<IDEMPOTENCY_KEY>",
  "Content-Type": "application/json"
},
  body: JSON.stringify({
  "merchant_id": "YOUR_RECIPIENT_MERCHANT_ID",
  "amount": 10000,
  "currency": "ETB",
  "merchant_reference": "ref-1791192600",
  "meta": {
    "batch": "OCT-01"
  }
})
});
const data = await response.json();

console.log(data);
Example Response
200 Success
{
  "status": "success",
  "message": "B2B payout completed successfully",
  "data": {
    "chapa_reference": "CP_T_17902410739",
    "status": "SUCCESS",
    "created_at": "2026-10-05T09:30:00Z",
    "updated_at": "2026-10-05T09:30:00Z"
  }
}
400 Error
{
  "status": "error",
  "message": "MerchantID is required",
  "error": {
    "code": "MISSING_REQUIRED_FIELD",
    "details": null
  }
}
401 Error
{
  "status": "error",
  "message": "Invalid API key or User does not exist",
  "error": {
    "code": "UNAUTHORIZED",
    "details": null
  }
}
403 Error
{
  "status": "error",
  "message": "API key environment does not match business environment.",
  "error": {
    "code": "INVALID_VALUE",
    "details": null
  }
}
409 Error
{
  "status": "error",
  "message": "Payout reference has been used before",
  "error": {
    "code": "INVALID_STATE",
    "details": null
  }
}

The example response reports data.status: "SUCCESS". Store the Chapa reference and verify the payout when reconciling.