Skip to content
Early access: payments on this site are in test mode, so no real money moves yet.
DarajaPay Payments API · early access

Accept M-PESA in your website, app or shop

One API to send M-PESA prompts, hear the moment money lands, and track every shilling. Start in test mode today; go live after a quick business check.

  • Test keys right after you apply
  • Plain JSON, any language
  • Signed webhooks
# Ask the customer to pay KES 2,450
curl https://api.darajapay.co.ke/v1/payments \
  -H "Authorization: Bearer sk_test_••••••••" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042" \
  -d '{
    "amount": 2450,
    "phone": "254712345512",
    "reference": "ORDER-1042",
    "callback_url": "https://yoursite.co.ke/webhook"
  }'
Webhook to your server when they pay
{
  "event": "payment.completed",
  "data": {
    "id": "pay_8Kq2Xr91",
    "object": "payment",
    "mode": "test",
    "amount": 2450,
    "status": "completed",
    "mpesa_receipt": "TST4K2…",
    "reference": "ORDER-1042"
  }
}

What you can build

From a one-person Instagram shop to a big online store. Use the API, or no code at all.

M-PESA prompt checkout

Your customer types their number and gets the M-PESA prompt (STK push). They type their PIN on their own phone.

Instant webhooks

We call your server the second a payment succeeds or fails. Signed so you know it's us, and retried if your server doesn't answer.

Every payment on record

Look up any payment by its id or list your latest ones through the API. A dashboard comes next.

Later

Payment links

No website? Make a link, send it on WhatsApp or Instagram, and get paid. No code.

Later

Hosted checkout page

Send customers to a DarajaPay page with your name and logo. We handle the payment and send them back.

Later

Payouts

Send money to suppliers, staff or customers' M-PESA (B2C).

Escrow payments for marketplaces

Later

Hold a payment until the buyer confirms delivery, then release it to the seller, using the same protected flow as Buy & Sell Safe through the API. The money would be held by our licensed partner, never in a DarajaPay wallet.

See how the protected flow works →

PlannedWooCommerce plugin · Android and iOS kits · Node.js, PHP and Python libraries

Two ways to get paid

Start with your own Till or Paybill. Collecting through DarajaPay comes later.

Your own Till or Paybill

First

Customers pay straight into your M-PESA Till or Paybill. DarajaPay never holds your money: we send the prompts, track every payment and tell your system.

  • Money reaches you at once
  • Needs a Till or Paybill with M-PESA API access; we help you set it up

Collect through DarajaPay

Later

No Till yet? We would collect for you and send your money to your bank or M-PESA every day.

  • Opens once a licensed partner is in place
  • Daily payout to your bank or M-PESA

From test to live in four steps

  1. 1ApplyFill in the form below and confirm your phone with an SMS code. Your test keys appear straight away.
  2. 2Build in test modeSimulated M-PESA prompts and webhooks, so you can finish your checkout without moving real money.
  3. 3We check your businessA person reviews your documents and website. We may call you.
  4. 4Go liveWe SMS you when you're approved and help you connect your Till or Paybill. Then you swap in your live key.
Quick start

The API on one page

Plain HTTPS and JSON. Send your secret key as a Bearer token. Base address: https://api.darajapay.co.ke/v1

1. Ask for a payment

POST /v1/payments with amount (whole shillings), phone (07… or 2547…), reference (your order number, up to 40 characters) and, if you like, description and callback_url. The customer gets an M-PESA prompt and the reply has status: "prompt_sent".

Send an Idempotency-Key header so a retry never charges twice.

Ask for a payment (cURL)
# Ask the customer to pay KES 2,450
curl https://api.darajapay.co.ke/v1/payments \
  -H "Authorization: Bearer sk_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042" \
  -d '{
    "amount": 2450,
    "phone": "254712345512",
    "reference": "ORDER-1042",
    "callback_url": "https://yoursite.co.ke/webhook"
  }'
Check a payment
curl https://api.darajapay.co.ke/v1/payments/pay_8Kq2Xr91 \
  -H "Authorization: Bearer sk_test_YOUR_KEY"

# Your latest payments (limit 1 to 100)
curl "https://api.darajapay.co.ke/v1/payments?limit=10" \
  -H "Authorization: Bearer sk_test_YOUR_KEY"

2. Hear when they pay

We POST to your callback_url with the event payment.completed, payment.failed or payment.cancelled. If your server doesn't answer with a 2xx, we try again after 10 seconds and after a minute.

Every webhook carries a DarajaPay-Signature header: t=<time>,v1=<HMAC-SHA256> of <time>.<raw body>, signed with your webhook secret. Check it before you trust the event.

Webhook body
{
  "event": "payment.completed",
  "data": {
    "id": "pay_8Kq2Xr91",
    "object": "payment",
    "mode": "test",
    "amount": 2450,
    "status": "completed",
    "mpesa_receipt": "TST4K2…",
    "reference": "ORDER-1042"
  }
}
Verify the signature
// Node.js: check the DarajaPay-Signature header
import { createHmac, timingSafeEqual } from "node:crypto";

function fromDarajaPay(rawBody, header, secret) {
  const sig = Object.fromEntries(
    header.split(",").map((p) => p.split("=")),
  );
  const mine = createHmac("sha256", secret)
    .update(sig.t + "." + rawBody)
    .digest("hex");
  const age = Date.now() / 1000 - Number(sig.t);
  return (
    Math.abs(age) < 300 &&
    mine.length === (sig.v1 || "").length &&
    timingSafeEqual(Buffer.from(mine), Buffer.from(sig.v1))
  );
}

3. Test without real money

Test keys (sk_test_…) never send a real prompt. Use any Kenyan number: one ending 000 is cancelled, one ending 111 fails, anything else completes about 3 seconds later with a fake receipt like TST4K2….

Errors come back as { error: { code, message } } with a plain-English message. Live keys aren't issued yet: they come after approval, once your Till or Paybill is connected.

Apply for API access

Takes about 5 minutes. Have these ready:

  • Certificate of registration or incorporation
  • Business KRA PIN certificate
  • ID of a director or the owner
  • Your Till or Paybill number
Why we askWe check every business before it can take real money, to keep scammers out and protect your customers. Your documents are only seen by our review team.

Your application

About you
We send a code here to confirm it's you.
Your business
How you'll get paid
Documents come next. After you confirm your phone you can add your registration certificate, KRA PIN certificate and a director's ID. Test keys don't need them.

We SMS a code to your phone. Once confirmed, your test keys are ready and your application goes to our review team.

Developer questions

Do I need my own Till or Paybill?
For now, yes. Money goes straight into it and we never hold it. If you don't have one with M-PESA API access yet, we'll show you how to get it.
How long does approval take?
We review applications in the order they arrive, once all documents are in. You can build in test mode while you wait.
Which languages and platforms work?
Any that can make an HTTPS request: PHP, Node.js, Python, Java, Laravel, WordPress and more. Ready-made plugins and libraries are planned.
What does it cost?
Test mode is free. We'll agree live pricing with you before you take real payments.
Can I talk to someone technical?

Yes. Ask Daraja first for quick answers about the API.