Create a payment (pay-in or pay-out)
curl -X POST "https://api.payhero.africa/api/global/payments" \ -u "API_USERNAME:API_PASSWORD" \ -H "Content-Type: application/json" \ -d '{ "request_type": "payment", "transaction_channel": "momo", "provider": "yellowcard", "amount": 5500, "currency": "KES", "country": "KE", "reason": "Order payment for invoice INV-2025-001", "source": "api", "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "+254712345678", "dob": "1990-01-01T00:00:00Z", "country": "KE", "address": { "line_1": "Westlands Road", "country": "KE" } }, "vendor_config": { "vendor_id": 63 }, "provider_config": { "network_id": "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "provider_id": "c2b2eeda-d4ca-49fd-ba21-0781ffa7714b", "network_name": "M PESA", "network_code": "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "account_type": "momo" }, "payment_config": { "reference": "test_top_", "account_number": "+254712345678", "remark": "order payment", "payment_category": "bill payment", "callback_url": "https://payhero-dev.beeceptor.com", "redirect_url": "https://payhero-dev.beeceptor.com" }}'<?php$ch = curl_init("https://api.payhero.africa/api/global/payments");$options = [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_USERPWD => "API_USERNAME:API_PASSWORD", CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_POSTFIELDS => json_encode([ "request_type" => "payment", "transaction_channel" => "momo", "provider" => "yellowcard", "amount" => 5500, "currency" => "KES", "country" => "KE", "reason" => "Order payment for invoice INV-2025-001", "source" => "api", "customer" => [ "first_name" => "John", "last_name" => "Doe", "email" => "john.doe@example.com", "phone" => "+254712345678", "dob" => "1990-01-01T00:00:00Z", "country" => "KE", "address" => [ "line_1" => "Westlands Road", "country" => "KE", ], ], "vendor_config" => [ "vendor_id" => 63, ], "provider_config" => [ "network_id" => "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "provider_id" => "c2b2eeda-d4ca-49fd-ba21-0781ffa7714b", "network_name" => "M PESA", "network_code" => "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "account_type" => "momo", ], "payment_config" => [ "reference" => "test_top_", "account_number" => "+254712345678", "remark" => "order payment", "payment_category" => "bill payment", "callback_url" => "https://payhero-dev.beeceptor.com", "redirect_url" => "https://payhero-dev.beeceptor.com", ], ]),];curl_setopt_array($ch, $options);$response = curl_exec($ch);curl_close($ch);echo $response;import requests
response = requests.post( "https://api.payhero.africa/api/global/payments", auth=("API_USERNAME", "API_PASSWORD"), json={ "request_type": "payment", "transaction_channel": "momo", "provider": "yellowcard", "amount": 5500, "currency": "KES", "country": "KE", "reason": "Order payment for invoice INV-2025-001", "source": "api", "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "+254712345678", "dob": "1990-01-01T00:00:00Z", "country": "KE", "address": { "line_1": "Westlands Road", "country": "KE", }, }, "vendor_config": { "vendor_id": 63, }, "provider_config": { "network_id": "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "provider_id": "c2b2eeda-d4ca-49fd-ba21-0781ffa7714b", "network_name": "M PESA", "network_code": "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "account_type": "momo", }, "payment_config": { "reference": "test_top_", "account_number": "+254712345678", "remark": "order payment", "payment_category": "bill payment", "callback_url": "https://payhero-dev.beeceptor.com", "redirect_url": "https://payhero-dev.beeceptor.com", }, },)print(response.json())const auth = Buffer.from("API_USERNAME:API_PASSWORD").toString("base64");
const response = await fetch("https://api.payhero.africa/api/global/payments", { method: "POST", headers: { Authorization: `Basic ${auth}`, "Content-Type": "application/json", }, body: JSON.stringify({ "request_type": "payment", "transaction_channel": "momo", "provider": "yellowcard", "amount": 5500, "currency": "KES", "country": "KE", "reason": "Order payment for invoice INV-2025-001", "source": "api", "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "+254712345678", "dob": "1990-01-01T00:00:00Z", "country": "KE", "address": { "line_1": "Westlands Road", "country": "KE" } }, "vendor_config": { "vendor_id": 63 }, "provider_config": { "network_id": "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "provider_id": "c2b2eeda-d4ca-49fd-ba21-0781ffa7714b", "network_name": "M PESA", "network_code": "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "account_type": "momo" }, "payment_config": { "reference": "test_top_", "account_number": "+254712345678", "remark": "order payment", "payment_category": "bill payment", "callback_url": "https://payhero-dev.beeceptor.com", "redirect_url": "https://payhero-dev.beeceptor.com" } }),});
const data = await response.json();console.log(data);Initiates a collection (request_type: payment) or a disbursement
(request_type: withdrawal). Works across all supported countries — set
currency, country, provider, and the relevant provider_config.
Who is the customer? It is the owner of the funds being moved, not you as the
platform. For a collection it is the client making the deposit; for a withdrawal it is the
owner of the wallet being debited — normally the initiating merchant — while the
destination is set in payment_config.account_number.
For global payments provider_config and payment_config are required in full.
vendor_config.channel_id is not required: it only applies to Kenya-based collections
that settle to an external channel (bank, paybill, till).
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
payment for pay-in (collection), withdrawal for pay-out (disbursement).
Rail to use.
Payment provider (see Discovery API).
ISO 4217 currency code.
ISO 3166-1 alpha-2 country code.
The owner (custodian) of the funds being moved — not you as the platform.
- Collection (
request_type: payment) — the client making the deposit, i.e. the payer being charged. - Withdrawal (
request_type: withdrawal) — the owner of the wallet being debited, which is normally the initiating merchant, not the person receiving the money. The destination is identified bypayment_config.account_number.
object
Customer phone number; usually the same as the account number.
Date of birth. Required for bank rails; for mobile top-ups use your KYC’s DOB. Not required for mobile top-ups.
Identity document type (e.g. national_id, NIN, passport).
object
ISO 3166-1 alpha-2 country code.
object
Your vendor ID.
Optional — not required for global payments. This references a payment channel ID and is only used for Kenya-based collections that settle to an external channel such as a bank account, paybill or till. Omit it for everything else.
Provider/network routing details, taken from the Discovery API
(POST /api/global/transaction-providers). All fields are required for global payments,
except channel_id.
object
Network ID returned by the Discovery API.
Provider ID returned by the Discovery API.
Human-readable network name.
Network code returned by the Discovery API.
Destination account type, e.g. momo or bank.
Optional. Provider channel ID; you can safely ignore this field.
Payment metadata. All fields are required for global payments.
object
Your own reference for the transaction.
The account being charged (collection) or paid (withdrawal).
Free-text remark shown on the transaction.
Category of the payment.
URL that receives the asynchronous transaction result.
URL the payer is returned to after completing the payment.
object
Examples
Pay-in — Kenya (KES, YellowCard MoMo). `customer` is the payer being charged.
{ "request_type": "payment", "transaction_channel": "momo", "provider": "yellowcard", "amount": 5500, "currency": "KES", "country": "KE", "reason": "Order payment for invoice INV-2025-001", "source": "api", "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "+254712345678", "dob": "1990-01-01T00:00:00Z", "country": "KE", "address": { "line_1": "Westlands Road", "country": "KE" } }, "vendor_config": { "vendor_id": 63 }, "provider_config": { "network_id": "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "provider_id": "c2b2eeda-d4ca-49fd-ba21-0781ffa7714b", "network_name": "M PESA", "network_code": "7ea6df5c-6bba-46b2-a7e6-f511959e7edb", "account_type": "momo" }, "payment_config": { "reference": "test_top_", "account_number": "+254712345678", "remark": "order payment", "payment_category": "bill payment", "callback_url": "https://payhero-dev.beeceptor.com", "redirect_url": "https://payhero-dev.beeceptor.com" }}Pay-out — Kenya (KES, Sasapay MoMo). `customer` is the owner of the wallet being debited.
{ "request_type": "withdrawal", "transaction_channel": "momo", "provider": "sasapay", "amount": 10, "currency": "KES", "country": "KE", "reason": "Withdrawal to account +254758955781", "source": "api", "customer": { "first_name": "Mary", "last_name": "Wanjiku", "email": "mary@acme.co.ke", "phone": "+254700111222", "dob": "1990-01-01T00:00:00Z", "country": "KE", "address": { "line_1": "Westlands Road", "country": "KE" } }, "vendor_config": { "vendor_id": 231 }, "provider_config": { "network_id": "63902", "provider_id": "63902", "network_name": "M PESA", "network_code": "63902", "account_type": "momo" }, "payment_config": { "reference": "test_withdrawal", "account_number": "+254758955781", "remark": "bill payments", "payment_category": "bill payment", "callback_url": "https://payhero.free.beeceptor.com", "redirect_url": "https://payhero.free.beeceptor.com" }, "payment_split": { "amount_to_save": 100 }}Pay-out — Tanzania (TZS, YellowCard). Recipient KYC fields are required for this corridor.
{ "request_type": "withdrawal", "transaction_channel": "momo", "provider": "yellowcard", "amount": 220000, "currency": "TZS", "country": "TZ", "reason": "Withdrawal to account +255712345678", "source": "api", "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "+255712345678", "dob": "1990-01-01T00:00:00Z", "country": "TZ", "id_type": "national_id", "id_number": "12345678", "address": { "line_1": "Westlands Road", "country": "TZ" } }, "vendor_config": { "vendor_id": 4046 }, "provider_config": { "network_id": "3a0b8d21-4a1f-4c2e-9d5b-6f1c2a7e40d3", "provider_id": "8f21c4de-90ab-4f77-b3c1-2d5e9a6b1c04", "network_name": "M PESA", "network_code": "3a0b8d21-4a1f-4c2e-9d5b-6f1c2a7e40d3", "account_type": "momo" }, "payment_config": { "reference": "tz_withdrawal_001", "account_number": "+255712345678", "remark": "bill payments", "payment_category": "bill payment", "callback_url": "https://payhero-dev.free.beeceptor.com", "redirect_url": "https://payhero-dev.free.beeceptor.com" }}Pay-out — Zambia (ZMW, YellowCard)
{ "request_type": "withdrawal", "transaction_channel": "momo", "provider": "yellowcard", "amount": 100, "currency": "ZMW", "country": "ZM", "reason": "Transfer payout", "source": "api", "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "+260712345678", "dob": "1990-01-01T00:00:00Z", "country": "ZM", "id_type": "NIN", "id_number": "12345678", "address": { "line_1": "Lusaka", "country": "ZM" } }, "vendor_config": { "vendor_id": 4046 }, "provider_config": { "network_id": "69affaa2-fbec-4e28-abd0-7444232721be", "provider_id": "b71d3f80-5c2a-4de6-8a19-0c6f4b2e7d55", "network_name": "AIRTEL MONEY", "network_code": "69affaa2-fbec-4e28-abd0-7444232721be", "account_type": "momo" }, "payment_config": { "reference": "zm_withdrawal_001", "account_number": "+260712345678", "remark": "bill payments", "payment_category": "bill payment", "callback_url": "https://payhero-dev.free.beeceptor.com", "redirect_url": "https://payhero-dev.free.beeceptor.com" }}Responses
Section titled “Responses”Payment request accepted and queued for processing.
object
Raw provider response details.
object
Examples
Pay-in accepted
{ "status_code": "200", "merchant_reference": "9FD194041588.iI", "transaction_type": "payin", "success": true, "message": "request sent", "checkout_request_id": "a8e1c979-3592-5abd-b1cd-dc1dbd34e708", "gateway": "yellowcard", "conversation_id": "9FD194041588.iI", "provider_response": { "amount": 42.11, "convertedAmount": 5500, "country": "KE", "currency": "KES", "rate": 130.61, "status": "process" }}Pay-out accepted
{ "status_code": "200", "merchant_reference": "UFD002744827.eO", "transaction_type": "payout", "success": true, "message": "request sent", "checkout_request_id": "a4131a61-c866-5eaa-96ab-d26fb1f1450e", "gateway": "yellowcard", "conversation_id": "UFD002744827.eO"}The request was rejected (validation or business-rule failure).
object
Examples
{ "error_code": "invalid_argument", "error_message": "the transaction amount is insufficient as it wont cater for cost: (4.62)", "status_code": 400}{ "error_code": "invalid_argument", "error_message": "The passed channel is not active", "status_code": 400}Missing or invalid Basic auth credentials.
object
Example
{ "error_code": "invalid_argument", "error_message": "the transaction amount is insufficient as it wont cater for cost: (4.62)", "status_code": 400}
