M-Pesa & Payments

M-Pesa Daraja Integration:
Complete Guide for Kenyan businesses.

A practical, no-fluff guide to what Daraja is, what it costs to integrate in Kenya, and how to ship it without burning two weeks on Safaricom KYC.

M-Pesa Daraja is Safaricom's official developer API for integrating M-Pesa payments into websites, apps, and business systems. It lets a Kenyan business accept payments (C2B), pay out money (B2C), query transaction status, and reconcile Till and Paybill activity automatically — without staff hunting through SMS confirmations.

This guide is for two readers: business owners trying to scope an M-Pesa integration before they hire someone, and developers shipping their first Daraja build. It covers what Daraja actually is, how STK Push works, what integration realistically costs in Kenya, the difference between sandbox and production, the most common errors that derail go-live, and two case studies from builds we've shipped.

What is the M-Pesa Daraja API?

M-Pesa Daraja is Safaricom's developer API. It exposes M-Pesa's core money-movement features — pay in, pay out, check status, reconcile — as HTTP endpoints any modern application can call.

Before Daraja, businesses that wanted M-Pesa on their site had two options: pay an aggregator like Pesapal a per-transaction fee, or have a human reconcile SMS receipts every evening. Daraja removed the middle layer. A WooCommerce store can now prompt a customer for their PIN, confirm payment, mark the order paid, and trigger a delivery — all in 8 seconds, no aggregator markup.

Daraja is free to use as an API. Safaricom does not charge a per-call fee. You pay only the normal M-Pesa transaction tariff that you would have paid anyway when the customer hit Pay Bill or Buy Goods on their phone.

How Daraja works: C2B, B2C, STK Push

Daraja groups its features into directional flows. The two that matter to most Kenyan businesses are C2B (customer pays you) and B2C (you pay someone else). STK Push is the smoothest variant of C2B for online checkout.

The names are jargon, but the underlying idea is straightforward:

  • C2B (Customer to Business) — money flowing in. A customer pays your Paybill or Till. Daraja confirms the payment to your server, which marks the invoice or order paid.
  • B2C (Business to Customer) — money flowing out. You pay out salaries, refunds, supplier disbursements, or commission directly from your shortcode to a phone number. No bank transfer needed.
  • B2B — money moving between two Paybills or Tills. Useful when you have a holding shortcode and a working shortcode.
  • Transaction Status / Account Balance / Reversal — utility calls for reconciliation and support.

STK Push (officially "Lipa na M-Pesa Online") is the friendliest C2B variant: instead of asking the customer to navigate to Lipa na M-Pesa → Pay Bill → type the business number → type the account number → type the amount, your server tells Safaricom "prompt this phone number to pay this amount to this shortcode." The customer's phone rings with a PIN prompt. They type it. Done.

STK Push, explained simply

STK Push sends a payment prompt directly to the customer's phone — they enter their M-Pesa PIN, Safaricom moves the money, and your server gets a callback with the result. It is the standard for online checkout in Kenya.

The flow has five steps, and every Daraja bug we've seen happens at one of them:

  1. You request an access token. Your server hits Safaricom's OAuth endpoint with your consumer key and secret and gets a token good for one hour.
  2. You build the STK Push request. You send the customer's phone (formatted 2547XXXXXXXX), the amount in KES, your shortcode, a timestamp, a passkey-derived password, and a callback URL.
  3. Safaricom prompts the phone. The customer sees a Lipa na M-Pesa prompt, enters their PIN, and confirms.
  4. Safaricom posts the result to your callback URL. Success or failure, with the MpesaReceiptNumber if successful.
  5. Your server reconciles. Mark the order paid, send the receipt, update inventory, kick off fulfilment.
Hidden gotcha: step 4 is the one that breaks most integrations. If your callback URL is behind a local dev tunnel, on plain HTTP, or unreachable for any reason, Safaricom retries a few times then gives up — and your DB never finds out the customer paid. Build the callback handler before you build the request, and always reconcile with a "transaction status" call as a fallback.

How much does Daraja integration cost in Kenya?

Daraja integration in Kenya typically costs KES 25,000–60,000 for a basic STK Push checkout on an existing site, KES 60,000–150,000 for a full Paybill + C2B + B2C + reconciliation system, and KES 150,000+ for multi-till or multi-shortcode builds with custom reporting. Safaricom does not charge a fee to use Daraja itself.

The variables that move the price:

  • How many flows you need. STK Push alone is the cheapest. Add B2C payouts, refunds, or multi-shortcode and the price climbs because each flow needs its own callback, retry logic, and reconciliation.
  • What you're integrating into. A WooCommerce or Shopify plugin glue is faster than wiring Daraja into a 5-year-old PHP system with no abstraction layer.
  • Reconciliation depth. "Mark the order paid" is one day. "Auto-match every till payment to an invoice, surface unmatched ones, and send daily reconciliation reports to the finance team" is two weeks.
  • Whether KYC and Paybill issuance are already done. Safaricom approval takes 2–4 weeks on its own. If your business doesn't yet have a Paybill, factor that timeline in — not the developer's.

At Owldid, our standard STK-Push-on-an-existing-site Daraja build is KES 35,000–45,000, ships in 5–8 working days, and includes sandbox testing, live callback infrastructure, and a 30-day post-go-live warranty. See full pricing →

Sandbox vs production

Sandbox is Safaricom's test environment with fake shortcodes and test phone numbers. Production uses your real Paybill or Till and real customer phones. You build and test against sandbox first, then swap credentials to go live.

The split exists because no developer should be testing payment edge cases by moving real money around. In sandbox you get:

  • A test consumer key and secret (issued the moment you create a Daraja app on the developer portal).
  • A test shortcode (174379 for STK Push) and passkey.
  • Safaricom-provided test phone numbers that always succeed, and ones that always fail — perfect for testing both happy path and error handling.

Going to production requires three things, in order: (1) an active Paybill or Till registered to the business, (2) a Safaricom-approved Daraja production app linked to that shortcode, and (3) production callback URLs whitelisted by Safaricom's portal. The third one is where solo developers usually hit a wall — Safaricom requires public HTTPS endpoints, not localhost.

The 7 most common Daraja errors (and how to avoid them)

Most Daraja go-live failures are not Daraja's fault — they're credential, format, or callback mistakes. Here are the seven we see most often, with fixes.

  1. Invalid access token. Tokens expire after 3600 seconds. Cache them, but refresh on 401. Don't request a new token per call — Safaricom will throttle you.
  2. Wrong shortcode / passkey combination. Sandbox passkey will not work in production. Confirm which environment you're hitting before debugging anything else.
  3. Phone number format. Daraja wants 2547XXXXXXXX (12 digits, no plus). +2547…, 07…, and 2547 XXX XXXX all fail silently or with vague errors. Normalize before sending.
  4. Callback URL unreachable. HTTPS required. No self-signed certs. No localhost. No ports other than 443. If you're using ngrok in dev, that's fine; in production it must be a real domain.
  5. Mismatched amount. Daraja rejects decimals on STK Push. KES 100 not 100.00. Round before submission.
  6. Timestamp drift. The password in the STK Push request is a base64-encoded SHA256 of shortcode + passkey + timestamp. If your server clock drifts more than ~5 minutes, requests reject. NTP your server.
  7. No reconciliation fallback. Even when everything works, ~1–2% of callbacks don't land due to network or carrier issues. Always run a "transaction status" sweep on pending orders 60–120 seconds after the request. This single safety net turns reliable into bulletproof.

Step-by-step: setting up Daraja from scratch

The full path from "I want M-Pesa on my site" to "live in production" has eight steps. Most of the calendar time is Safaricom's KYC queue, not development.

  1. Register for a Lipa na M-Pesa Paybill or Till via Safaricom (M-Pesa for Business). Requires business registration documents. 1–3 weeks.
  2. Create a Safaricom Developer account at developer.safaricom.co.ke. Free, immediate.
  3. Create a Daraja app in the sandbox environment. You'll get a consumer key and consumer secret.
  4. Build and test against sandbox. STK Push, C2B confirmation, B2C, transaction status — wire everything you need. Test with the Safaricom-provided test numbers.
  5. Set up production-grade callback infrastructure. Public HTTPS, signed certificate, persistent logging, idempotent handlers (Safaricom can deliver the same callback twice).
  6. Submit a Go-Live request on the Daraja portal. You'll attach your shortcode, your validation/confirmation URLs, and proof that the shortcode is yours. Approval is 3–10 business days.
  7. Swap sandbox credentials for production credentials. One config change, one redeploy.
  8. Run a real-money smoke test with your own phone for KES 1, watching every step in your logs. Then go live.

Two builds that shipped on Daraja

If you want to know whether Daraja works in production for Kenyan businesses — yes. Here are two we've shipped.

Nakuru Hardware POS — Till + STK Push reconciliation

A two-branch hardware retailer was reconciling till payments manually every evening, 90 minutes per branch. We built a custom POS with M-Pesa till integration: every customer payment ties automatically to a sale, surplus or shortfall is flagged in real time, and the end-of-day reconciliation now takes 10 minutes. Daraja was the spine of the reconciliation engine.

Read the full case study →

Stitches & Style — WooCommerce + STK Push

A Nairobi boutique brand had built its entire e-commerce on a Canva PDF and Instagram DMs. We launched a WooCommerce store with M-Pesa Daraja STK Push at checkout, size filters, automated WhatsApp order notifications, and an Instagram feed embed. Online sales grew 280% in the first 60 days; order errors dropped to near zero.

Read the full case study →

Frequently asked questions

Is M-Pesa Daraja free to use?
Yes. Safaricom does not charge for API access. You only pay the normal M-Pesa transaction charges you would have paid anyway.
Do I need a Paybill or a Till?
You need one or the other — Paybill (typically for invoicing, fees, rent, donations) or Till (typically for retail). Daraja attaches to whichever you have. Apply through Safaricom's M-Pesa for Business platform.
How long does the full go-live process take?
If your business already has a Paybill, 5–10 working days end-to-end including Safaricom approval. If not, factor in 2–4 weeks for the Paybill KYC itself.
Can Daraja be added to an existing WooCommerce, Shopify, or custom site?
Yes. Daraja is a server-side integration plus a public callback URL. The front-end of your site does not have to change — only the checkout endpoint.
What happens if a payment fails halfway?
Safaricom returns a failure code on the callback. A well-built integration marks the order as "payment failed", emails or WhatsApps the customer, and offers a retry. The reconciliation sweep we mentioned above catches any callbacks that never arrive.
Can Owldid integrate Daraja for our business?
Yes — Daraja is one of our most-shipped builds. Pricing starts at KES 35,000 for a clean STK Push integration on an existing site and scales with reconciliation complexity. Get in touch →

Need M-Pesa Daraja shipped without the two-week debugging spiral?

We've shipped Daraja for retail, e-commerce, schools, and clinics. We'll handle the Safaricom paperwork, the sandbox build, the production credentials, and the reconciliation. You get a working checkout in 5–8 working days.

Start a project → WhatsApp +254 113 333 522