Create an account, generate an API key and send STK pushes from your own code. Every shilling is tracked to your account, visible on your dashboard, and withdrawable to any mobile money number.
Create free accountRead the API docs
$ curl -X POST https://harakapaye.co.ke/api/v1/stk/push \ -H "Authorization: Bearer sk_live_••••••••" \ -d '{"phone":"0712345678","amount":1500,"reference":"ORDER-1042"}' 201 {"success":true,"data":{"status":"pending","amount":1500}} … customer enters their mobile money PIN webhook payment.success KES 1,500 QGH7X2K9LP wallet balance KES 1,425 (after 5% fee)
From the customer’s phone to your wallet, with a record at every step.
One endpoint starts a payment. Use your secret key as a bearer token, pass the phone number and amount, and you are done. Your own order reference makes the call safe to retry.
curl -X POST https://harakapaye.co.ke/api/v1/stk/push \
-H "Authorization: Bearer $GATEWAY_SECRET_KEY" \
-H "X-Public-Key: $GATEWAY_PUBLIC_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "0712345678",
"amount": 1500,
"reference": "ORDER-1042",
"description": "Order 1042"
}'<?php
$ch = curl_init(getenv('GATEWAY_API_URL') . '/stk/push');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('GATEWAY_SECRET_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'phone' => '0712345678',
'amount' => 1500,
'reference' => 'ORDER-1042', // your own order id
'description' => 'Order 1042',
]),
]);
$res = json_decode(curl_exec($ch), true);
if ($res['success']) {
$gatewayRef = $res['data']['reference']; // store this next to your order
} else {
error_log('STK push failed: ' . $res['error']);
}const res = await fetch(`${process.env.GATEWAY_API_URL}/stk/push`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.GATEWAY_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
phone: '0712345678',
amount: 1500,
reference: 'ORDER-1042', // your own order id
description: 'Order 1042',
}),
});
const body = await res.json();
if (body.success) {
console.log('Payment requested:', body.data.reference);
} else {
console.error('STK push failed:', body.error);
}import os, requests
res = requests.post(
os.environ["GATEWAY_API_URL"] + "/stk/push",
headers={"Authorization": "Bearer " + os.environ["GATEWAY_SECRET_KEY"]},
json={
"phone": "0712345678",
"amount": 1500,
"reference": "ORDER-1042", # your own order id
"description": "Order 1042",
},
timeout=30,
)
body = res.json()
if body["success"]:
print("Payment requested:", body["data"]["reference"])
else:
print("STK push failed:", body["error"])Collect, reconcile and withdraw without stitching tools together.
Customers approve on their own phone. Business-number and till collections supported.
Each payment is credited to the account that owns the key, with fees shown separately.
Results are posted to your server with an HMAC signature, retried if your server is down, and can be resent on demand.
A public key, secret key and signing secret per key. Restrict by IP, label per site, revoke instantly.
Balance, collections, success rate and a 14-day chart. Filter and export every payment as CSV.
Send your balance to any mobile money number. Track each request from pending to paid.
No developer needed. Push a payment request to any customer from your browser.
Every field, status, error and code sample explained, with a go-live checklist.
Your dashboard shows what you have collected, what the fees were, and what is ready to withdraw. Each payment carries your own order reference and the receipt code, so reconciliation takes minutes, not days.
Let customers pay for an order without leaving your checkout page.
Bill monthly plans and top-ups, and unlock access when the webhook arrives.
Sell tickets by phone number and confirm instantly with the receipt code.
Collect fees and contributions and reconcile each payer by reference.
You pay only when you get paid.
per successful payment. Failed, cancelled and expired payments are free.
Start collectingper withdrawal to any mobile money number. Minimum withdrawal KES 100.
per payment. Special rates and limits can be arranged for high-volume merchants.
Money software should be boring and strict. These protections are on by default.
Your site sends us the customer’s phone number and an amount. The customer instantly gets a payment prompt on their phone, enters their PIN, and the payment is confirmed. They never leave your site.
Your wallet is credited the moment the network confirms the payment. You see it on your dashboard straight away and, if you set a webhook, we notify your server in the same moment.
Request a withdrawal to any mobile money number from your dashboard and confirm with your password. The amount is held immediately. The gateway team reviews it, sends the money and records the receipt on your withdrawal. If it is rejected, the money returns to your wallet.
You pay 5% on each successful collection and KES 10 per withdrawal. Failed, cancelled and expired payments cost nothing.
The payment ends with a clear status (cancelled, failed or expired), you get a webhook with the reason, and nothing is charged. Your site can simply ask the customer to try again.
Yes. The “Request a payment” form on your dashboard sends an STK push to any number. It is handy for invoices, phone orders and testing.
Secret keys are stored as one-way hashes and shown only once. You can lock a key to your server’s IP addresses, create separate keys for each site, and revoke any key instantly.
Verification (KYC) becomes mandatory once your successful deposits exceed KES 1,000, or when the team asks you to verify. You upload the front and back of your ID plus a selfie holding it, an administrator approves it, and withdrawals unlock. An account suspended for missing KYC is reactivated as soon as the ID is approved.
Yes. Signed-in merchants can start a conversation with the support team from the Support page. Replies appear in the same thread.
Any supported mobile money number, written as 07XXXXXXXX, 01XXXXXXXX or 2547XXXXXXXX.
Create an account and an API key, then ask the administrator to enable test mode, or use the dashboard form. The documentation has a step-by-step testing guide.
Create an account, generate your keys and send a test STK push in under five minutes.