Paystack works in Kenya as a licensed payment aggregator. It accepts M-Pesa, Airtel Money, Visa/Mastercard, Apple Pay, Pesalink, and bank transfers through a single API. You send one Charge API request with provider set to "mpesa" and Paystack triggers the STK push on the customer's phone. Funds settle to your bank account or M-Pesa wallet.
Paystack launched in Kenya as a licensed payment service provider. For developers, that means one API integration gives you access to the payment methods Kenyan customers actually use.
Here is what you can accept through Paystack in Kenya today:
From your code, you do not build six separate integrations. You build one. Paystack's Transaction Initialize or Charge API accepts a channel parameter. You specify which methods to offer, and Paystack's checkout or your custom form handles the rest.
One detail that trips people up: M-Pesa through Paystack is not the same as direct M-Pesa through Daraja. The money flows through Paystack as the aggregator. The customer sees a Paystack-related paybill or shortcode on their phone, not your own paybill number. For most applications, this does not matter. For some, it does. That brings us to the question every Kenyan developer eventually asks.
If you are building a product in Kenya that accepts payments, you will face this decision early: should you integrate M-Pesa directly through Safaricom's Daraja API, or use a payment gateway like Paystack?
This is not a theoretical question. It affects your costs, your development timeline, your reconciliation workflow, and your customer's checkout experience.
Choose direct Daraja when:
Choose Paystack when:
The hybrid approach: Some teams run both. They use Paystack for the checkout (cards, Pesalink, small M-Pesa amounts) and direct Daraja for high-volume M-Pesa use cases like bulk disbursements. This adds complexity, but it is a legitimate pattern. We cover it in detail in Running Paystack and Daraja Side by Side.
There is no universally correct answer. The right choice depends on your product, your team, and your transaction profile. The articles in this cluster cover both paths so you can make an informed decision for your specific situation.
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
The fastest way to accept M-Pesa through Paystack is the Charge API. You send a POST request with the customer's phone number and the amount. Paystack sends an STK push to the customer's phone. The customer enters their M-Pesa PIN. Paystack sends you a webhook when the charge succeeds or fails.
Here is the basic flow in Node.js:
// Step 1: Initialize the M-Pesa charge
const response = await fetch('https://api.paystack.co/charge', {
method: 'POST',
headers: {
Authorization: 'Bearer sk_live_YOUR_SECRET_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'customer@example.com',
amount: 150000, // Amount in kobo/cents. 150000 = KES 1,500
currency: 'KES',
mobile_money: {
phone: '0712345678',
provider: 'mpesa',
},
}),
});
const data = await response.json();
// data.status === true means the charge was initiated
// data.data.status will be 'pay_offline' (the customer needs to complete on their phone)
console.log(data.data.reference); // Save this reference
A few things to note:
150000. This catches people the first time.07XXXXXXXX or 01XXXXXXXX) or the international format (2547XXXXXXXX). Check Paystack's docs for the exact format they expect, as it can change.Your webhook handler needs to listen for the charge.success event:
// Express webhook handler (simplified)
app.post('/webhooks/paystack', express.json(), (req, res) => {
const hash = crypto
.createHmac('sha512', process.env.PAYSTACK_SECRET_KEY)
.update(JSON.stringify(req.body))
.digest('hex');
if (hash !== req.headers['x-paystack-signature']) {
return res.status(401).send('Invalid signature');
}
const event = req.body;
if (event.event === 'charge.success') {
const { reference, amount, currency } = event.data;
// Verify the amount matches what you expected
// Update your database
// Send the customer a confirmation
console.log('Payment confirmed:', reference, amount, currency);
}
res.status(200).send('OK');
});
Always verify the webhook signature. Always check the amount and currency in the webhook match what you expected. Never trust the client side alone. These are not suggestions. Skipping them is how you lose money.
For a deeper look at the Charge API specifically, see Accepting M-Pesa Payments with the Paystack Charge API. For the Checkout (popup) approach instead of the Charge API, see Accepting M-Pesa Payments Through Paystack Checkout.
Accepting money is half the story. The other half is sending it out. In Kenya, Paystack Transfers let you move money from your Paystack balance to three destinations:
The Transfer API flow works like this:
transfer.success or transfer.failed event tells you the outcome.// Create a mobile money transfer recipient
const recipientRes = await fetch('https://api.paystack.co/transferrecipient', {
method: 'POST',
headers: {
Authorization: 'Bearer sk_live_YOUR_SECRET_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'mobile_money',
name: 'Jane Wanjiku',
account_number: '0712345678',
bank_code: 'MPESA',
currency: 'KES',
}),
});
const recipient = await recipientRes.json();
const recipientCode = recipient.data.recipient_code;
// Initiate the transfer
const transferRes = await fetch('https://api.paystack.co/transfer', {
method: 'POST',
headers: {
Authorization: 'Bearer sk_live_YOUR_SECRET_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
source: 'balance',
amount: 50000, // KES 500 in cents
recipient: recipientCode,
reason: 'Rider payout for July 20',
}),
});
const transfer = await transferRes.json();
console.log(transfer.data.transfer_code);
A few practical notes for Kenya:
For the full breakdown, see Paystack Transfers to M-Pesa Wallets Explained and Paystack Transfers to Paybill and Till Numbers.
Pesalink is the real-time interbank payment network run by the Kenya Bankers Association. It lets customers pay directly from their bank account without a card. The money moves between banks in real time, 24 hours a day, seven days a week.
Why does Pesalink matter for developers? Two reasons:
On Paystack, Pesalink appears as a payment channel. When you initialize a transaction or use the Paystack Checkout popup, you can include bank_transfer or the Pesalink-specific channel in the list of allowed channels. The customer selects Pesalink, chooses their bank, and authorizes the payment from their banking app or USSD.
From the developer's perspective, the integration code does not change much. You initialize the transaction with KES as the currency and include the relevant channel. Paystack handles the Pesalink connection, the bank authorization flow, and the confirmation. You receive the same charge.success webhook regardless of whether the customer paid with M-Pesa, a card, or Pesalink.
That uniformity is one of the real advantages of using a gateway. Your backend does not care which payment method the customer chose. The webhook payload structure is the same. Your reconciliation logic is the same.
For the full integration walkthrough, see Pay with Pesalink on Paystack: Developer Guide.
Settlement is when the money your customers paid actually arrives in your account. This is where many developers get surprised, because there is a gap between "customer paid" and "you have the money."
In Kenya, Paystack settles to:
Settlement timing varies. Paystack publishes settlement schedules on their website, but the actual timing depends on your account type, your transaction volume, and the payment method used. [TODO: verify current figure on paystack.com/pricing]
What you need to know as a developer:
transfer.failed events and keep your banking details current.For a deeper look at settlement mechanics, see Paystack Kenya Settlement to Bank or M-Pesa Wallet.
Building payment integrations in Kenya is not the same as building them in the US or Europe. The regulatory environment, the infrastructure, and the customer expectations are different. Here is what you need to think about.
CBK Regulations
The Central Bank of Kenya regulates payment service providers under the National Payment System Act. Paystack is licensed, so you do not need your own PSP license just to use their API. But you do need to understand the rules that affect your product. For example, there are regulations around how you store payment data, how you handle customer disputes, and what disclosures you need to make. See CBK Payment Service Provider Rules Developers Should Know.
KRA eTIMS
The Kenya Revenue Authority's electronic Tax Invoice Management System (eTIMS) requires businesses to generate electronic tax invoices for every sale. If your application processes payments, you likely need to integrate with eTIMS to generate compliant invoices. This is separate from Paystack, but your payment flow needs to account for it. Every successful payment should trigger an eTIMS invoice. See KRA eTIMS and Payment Receipt Integration Considerations.
Data Protection Act
Kenya's Data Protection Act (2019) governs how you collect, process, and store personal data, including payment data. Phone numbers, email addresses, and transaction histories are personal data. You need a privacy policy, you need consent, and you need to store data securely. Paystack handles the card data (they are PCI DSS compliant), but you are responsible for the customer data in your own database.
Digital Service Tax
If your product is a digital service, you may be subject to Kenya's Digital Service Tax. This applies to services delivered over the internet. The tax is collected at the point of payment in some cases. Your accounting team needs to understand whether your product falls under this category. See Kenya Digital Service Tax and Online Payment Products.
Network Conditions
Kenyan internet is good in Nairobi, Mombasa, and other major towns. It is less reliable in rural areas. And even in the city, mobile data connections drop. Your payment integration needs to handle:
These are not edge cases in Kenya. They are the normal operating conditions for a significant portion of your users. Build for them from day one. For implementation patterns, see Building for Kenyan Network Conditions: Retries and Timeouts.
This hub article is the starting point. The articles below go deeper into each topic. They are organized by category: overviews and comparisons, M-Pesa and Daraja specifics, other payment methods, transfers and payouts, real-world build guides, alternative channels, and regulatory considerations.
Overviews and Comparisons
M-Pesa and Daraja
Other Payment Methods
Transfers and Payouts
Build Guides: Real Kenyan Products
Alternative Channels
Regulatory and Compliance
This article and the 45 articles linked above exist because Paystack-in-Kenya is not a footnote. It is the core of what many developers here build every day. M-Pesa, Daraja, STK push, paybill, till number, Pesalink, eTIMS. These are not exotic technologies. They are the stack.
McTaba teaches this stack. Not as a side topic. As the main thing.
The McTaba M-Pesa/Daraja micro-course is a four-week guided cohort. KES 20,000, live sessions, project reviews, and a shippable deliverable. The full KES 20,000 applies as credit toward the 26-week bootcamp if you continue.
You build a working payment integration that handles STK push, callbacks, reconciliation, and error recovery. Not a tutorial project. A production-ready one. The kind you would put in front of actual customers.
If you want the full picture, the 26-week Full-Stack Software and AI Engineering bootcamp (KES 120,000) covers payments as part of a complete engineering education. You ship real products that accept real money.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course