Going live on Daraja requires a registered Kenyan business, KRA compliance, production API credentials from Safaricom, a valid SSL certificate on your callback URLs, proper error handling, and a reconciliation strategy. Most applications get rejected for incomplete business documentation or invalid callback URLs. Budget 2 to 10 business days for the full approval process.
Safaricom does not issue production Daraja credentials to individuals. You need a registered business entity. This catches a lot of solo developers off guard, especially those who built something cool in sandbox and want to launch immediately.
What you need before applying:
For sole proprietorships, the process is relatively straightforward. For limited companies, you may also need board resolutions authorizing the API integration. The more organized your paperwork is before you start, the faster the approval process goes.
One important note: if you are building an integration for a client's business, the application must be in the client's name using their business documents. You cannot use your own business credentials to process payments on behalf of another business. This is a compliance requirement from the Central Bank of Kenya.
Once your business documentation is in order, you apply for production credentials through the Daraja developer portal.
Step 1: Log in to the Daraja portal at developer.safaricom.co.ke with the same account you used for sandbox development.
Step 2: Navigate to "Go Live" (or "Production" depending on the current portal UI). Fill in your business details and upload the required documents.
Step 3: Specify which APIs you need. Select only the ones your application actually uses. Requesting APIs you do not need can slow down the review. For most applications, you need Lipa Na M-Pesa (STK Push) at minimum. If you also need C2B, B2C, or B2B, select those as well.
Step 4: Submit and wait. Safaricom reviews your application manually. Typical turnaround is 2 to 5 business days, but it can stretch to 10 during busy periods or if your documentation is incomplete. You will receive an email when approved.
Step 5: Receive your production credentials. After approval, you will get:
These are completely different from your sandbox credentials. Do not mix them up. Store them securely in environment variables, never in source code or version control.
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
Print this out and check each item off. Seriously. Missing any one of these can cause silent failures in production that cost you real money and real customer trust.
Infrastructure
sandbox.safaricom.co.ke must be replaced with api.safaricom.co.ke. Search your entire codebase. Check environment variables, config files, and hardcoded strings.openssl s_client or ssllabs.com.Application Logic
CheckoutRequestID as a unique key.Reliability
Safaricom reviews production applications manually, and a significant number get rejected on the first attempt. Knowing the common rejection reasons saves you days of back-and-forth.
Incomplete or mismatched business documents. The business name on your registration certificate must match what you entered in the application. The KRA PIN must belong to the business, not to you personally. If you are a sole proprietor, these might be the same, but for a limited company, they are different documents. Upload clear, legible scans (not blurry phone photos).
No active M-Pesa business account. You need an existing Paybill or Till Number before applying for API access. Some developers assume the API application creates one. It does not. Apply for the business M-Pesa account first through Safaricom Business, wait for it to be activated, then apply for Daraja production access.
Invalid callback URLs. If you submit callback URLs that are not reachable via HTTPS at the time of review, your application may be flagged. Make sure your production server and SSL certificate are set up before applying, or at least before the review.
Requesting unnecessary APIs. If you request access to B2C (sending money to customers) but your application is an e-commerce store that only receives payments, the reviewer may ask for clarification, which delays the process. Only request what you actually need.
How to speed up the process: Submit everything correctly the first time. Include a brief description of your application and how it will use M-Pesa. If your documents are complete and clear, approval typically comes within 2 to 3 business days. If you need to follow up, email the Daraja support team with your application reference number rather than resubmitting.
The cleanest approach is to use environment variables for everything that changes between sandbox and production. This way, switching environments is a matter of changing your .env file, not your code.
# .env.sandbox
MPESA_ENV=sandbox
MPESA_BASE_URL=https://sandbox.safaricom.co.ke
MPESA_CONSUMER_KEY=your_sandbox_consumer_key
MPESA_CONSUMER_SECRET=your_sandbox_consumer_secret
MPESA_SHORTCODE=174379
MPESA_PASSKEY=your_sandbox_passkey
MPESA_CALLBACK_URL=https://your-ngrok-url.ngrok-free.app/api/mpesa/callback
# .env.production
MPESA_ENV=production
MPESA_BASE_URL=https://api.safaricom.co.ke
MPESA_CONSUMER_KEY=your_production_consumer_key
MPESA_CONSUMER_SECRET=your_production_consumer_secret
MPESA_SHORTCODE=your_real_shortcode
MPESA_PASSKEY=your_production_passkey
MPESA_CALLBACK_URL=https://yourdomain.com/api/mpesa/callback
In your code, reference the environment variables rather than hardcoding any URLs or credentials:
// mpesa-config.js
const config = {
baseUrl: process.env.MPESA_BASE_URL,
consumerKey: process.env.MPESA_CONSUMER_KEY,
consumerSecret: process.env.MPESA_CONSUMER_SECRET,
shortcode: process.env.MPESA_SHORTCODE,
passkey: process.env.MPESA_PASSKEY,
callbackUrl: process.env.MPESA_CALLBACK_URL,
};
// Sanity check at startup
if (process.env.MPESA_ENV === 'production') {
if (config.baseUrl.includes('sandbox')) {
throw new Error('Production env but sandbox URL detected!');
}
if (config.shortcode === '174379') {
throw new Error('Production env but sandbox shortcode detected!');
}
console.log('M-Pesa: Running in PRODUCTION mode');
} else {
console.log('M-Pesa: Running in SANDBOX mode');
}
module.exports = config;
That sanity check at startup has saved us (and our students at McTaba Labs) from accidentally hitting production with sandbox credentials, or worse, hitting sandbox with production credentials and wondering why real money is not moving. Spend five minutes adding validation. It will save you hours of confusion later.
You have production credentials. Your code is configured. Your callback URL is live. Do not announce the launch yet. Test with real money first, in small amounts.
Step 1: Make a KES 1 payment to yourself. Initiate an STK Push for KES 1 using your own phone number. Enter your PIN. Verify that the callback arrives, your database updates, and the customer (you) sees the correct confirmation. Check your M-Pesa statement to confirm the money actually moved.
Step 2: Test failure scenarios.
Step 3: Test with 2 to 3 other people. Have team members or friends make small payments. Different phone models, different network conditions, different M-Pesa account types. The goal is to surface edge cases you will not find testing alone. One common issue: phone number formats. Your friend might type their number as "0712 345 678" with spaces, and your normalizer might not handle that.
Step 4: Verify reconciliation. After all test transactions, compare your database records against the M-Pesa business statement. Every transaction should match. If any are missing or have incorrect amounts, fix the issue before going live.
Step 5: Go live gradually. If your app has existing users, do not enable M-Pesa for everyone at once. Start with a small percentage or a beta group. Monitor callback success rates, error rates, and customer complaints. Scale up once you are confident everything works.
This testing process takes a day or two and costs less than KES 100 in test transactions. That is a tiny investment compared to the cost of discovering bugs when hundreds of customers are trying to pay.
Going live is not the end. It is the beginning of ongoing operational responsibility. You are handling people's money now. That demands a level of vigilance you might not be used to from other features.
Daily reconciliation. Every day, compare your transaction records against the M-Pesa statement. This catches edge cases: callbacks that were lost, transactions that were double-processed, or amounts that do not match. Automate this if your volume justifies it. For low-volume applications, a manual daily check takes 10 minutes.
Monitor callback health. Track what percentage of your STK Push requests result in a callback within 5 minutes. If this drops below 95%, something is wrong with your infrastructure. Set up alerts for sudden drops.
SSL certificate renewal. If you use Let's Encrypt, certificates expire every 90 days. Set up auto-renewal with certbot and verify it is working. An expired certificate means zero callbacks until you fix it, and Safaricom will not tell you. You will just see a sudden stop in payments.
Keep up with Daraja changes. Safaricom occasionally updates the Daraja API (new endpoints, changed response formats, deprecated fields). Follow the Daraja developer portal for announcements. Breaking changes are rare but not unheard of.
Customer support playbook. Have a clear process for when a customer says "I paid but my order was not updated." The investigation steps are: check your callback logs for their phone number, check the Transaction Status API, check the M-Pesa statement. In most cases, the payment either failed (customer thought they completed it but actually cancelled) or the callback was lost (use Transaction Status to confirm and manually update).
M-Pesa integration is one of the most career-relevant skills for developers in East Africa. If you want to go beyond the basics and build production-grade payment systems with proper architecture, our Software and AI Engineering programme at McTaba Labs covers the full payment stack in depth.
KES 9,999
Master Daraja API, STK Push, C2B, B2C, and callback handling. Build a real payment flow from scratch. 10 modules, 57 lessons.
Enrol in M-Pesa Integration