HarakaPaye
Built around instant STK push payments

Take mobile money payments on any website with one API call.

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

terminal
$ 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)
Payment receivedKES 1,500 · QGH7X2K9LP
5%per successful collection
Instantwallet credit on confirmation
KES 100minimum withdrawal
KES 250,000maximum per payment

How money moves

From the customer’s phone to your wallet, with a record at every step.

  1. Customer paysYour site calls the API and the customer gets an STK prompt on their phone.
  2. Funds settle in our collection accountThe network confirms and we credit the payment to your wallet, minus the fee.
  3. You request a withdrawalChoose any mobile money number and an amount from your available balance.
  4. We approve and send itThe gateway team reviews and pays out. The receipt shows in your history.

Integrate in minutes

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.

  • Plain JSON over HTTPS, works from any language
  • Idempotent: reuse a reference and nobody is charged twice
  • Poll for status or receive a signed webhook
  • Clear errors with the reason in plain words

Follow the quickstart

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"])

Everything you need to get paid

Collect, reconcile and withdraw without stitching tools together.

STK push collections

Customers approve on their own phone. Business-number and till collections supported.

Merchant wallet

Each payment is credited to the account that owns the key, with fees shown separately.

Signed webhooks

Results are posted to your server with an HMAC signature, retried if your server is down, and can be resent on demand.

Keys you control

A public key, secret key and signing secret per key. Restrict by IP, label per site, revoke instantly.

Live dashboard

Balance, collections, success rate and a 14-day chart. Filter and export every payment as CSV.

Withdraw anywhere

Send your balance to any mobile money number. Track each request from pending to paid.

Request from the dashboard

No developer needed. Push a payment request to any customer from your browser.

Real documentation

Every field, status, error and code sample explained, with a go-live checklist.

Dashboard · sample data
Available balanceKES 48,250
TodayKES 6,400
Success rate96%
KP3F9A1C0B7D0712 ••• 3451,500success
KP81C2D77E100722 ••• 981350success
KP0A9B3E5C220733 ••• 1182,000pending

See every shilling

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.

  • Search by order reference, phone or receipt code
  • Webhook delivery status on every payment
  • One-click CSV export

Built for every kind of checkout

Online shops

Let customers pay for an order without leaving your checkout page.

Subscriptions and SaaS

Bill monthly plans and top-ups, and unlock access when the webhook arrives.

Events and ticketing

Sell tickets by phone number and confirm instantly with the receipt code.

Schools, clubs and donations

Collect fees and contributions and reconcile each payer by reference.

Simple pricing

You pay only when you get paid.

Collections5%

per successful payment. Failed, cancelled and expired payments are free.

Start collecting
WithdrawalsKES 10

per withdrawal to any mobile money number. Minimum withdrawal KES 100.

LimitsKES 1 – 250,000

per payment. Special rates and limits can be arranged for high-volume merchants.

Security you can explain to your boss

Money software should be boring and strict. These protections are on by default.

Questions, answered

How does a customer pay?

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.

When does my balance update?

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.

How do withdrawals work?

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.

What do I pay?

You pay 5% on each successful collection and KES 10 per withdrawal. Failed, cancelled and expired payments cost nothing.

What happens if the customer cancels or enters the wrong PIN?

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.

Can I use it without writing code?

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.

Is my API key safe?

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.

Do I need to verify my identity?

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.

Can I talk to someone?

Yes. Signed-in merchants can start a conversation with the support team from the Support page. Replies appear in the same thread.

Which phones are supported?

Any supported mobile money number, written as 07XXXXXXXX, 01XXXXXXXX or 2547XXXXXXXX.

How can I test before going live?

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.

Ready to take your first mobile money payment?

Create an account, generate your keys and send a test STK push in under five minutes.

Create free accountRead the docs