To set up your Daraja sandbox, register at developer.safaricom.co.ke, create an app to get your consumer key and secret, then use the provided test shortcode (174379) and passkey from the API documentation. Store credentials in a .env file, set up ngrok for callback testing, and generate an OAuth token to verify everything works. The whole setup takes about 30 minutes.
The Daraja sandbox is a test environment that simulates the entire M-Pesa payment flow without moving real money. Every M-Pesa integration should start here. No exceptions.
Here is why this matters: in production, API mistakes have real consequences. A malformed B2C request could send real money to the wrong phone number. A bug in your STK Push handler could charge a customer twice. A misconfigured callback could mean you accept payments but never record them. The sandbox lets you make all these mistakes safely while you learn the API.
The sandbox is also free and instant. You do not need a registered business, a paybill number, or approval from Safaricom to use it. You sign up, create an app, and start making API calls within minutes. Compare that to production setup, which requires business registration, Safaricom review, and can take days or weeks.
There are some differences between sandbox and production that you should know about upfront. The sandbox does not send actual push notifications to phones. Response times are different (sometimes faster, sometimes slower). Some edge cases and error conditions are not perfectly simulated. But for learning the API structure, testing your code logic, and building your integration, the sandbox is exactly what you need.
We have seen developers try to skip the sandbox and go straight to production "to save time." This always ends badly. You end up debugging credential issues and API format problems with real money on the line. Start in the sandbox. Move to production only when your integration is tested and working.
The developer portal at developer.safaricom.co.ke is where everything begins. Here is the registration process:
A few things to know about the portal itself. The UI is functional but not always intuitive. Pages sometimes load slowly, and the navigation can feel cluttered. Do not let this discourage you. The portal is primarily a credential management tool, not a place you will spend a lot of time once you have your credentials.
After logging in, you will see your dashboard. The main sections you will use are "My Apps" (where you create and manage API credentials), the API documentation, and the "APIs" section (where you can browse available endpoints). The documentation section is worth reading through at least once, though we will cover the practical parts in this guide.
If the portal is temporarily unavailable (it does go down occasionally, especially during maintenance windows), try again in an hour. There is no alternative portal or workaround. The official developer portal is the only place to get legitimate Daraja credentials.
One more thing: your developer portal account is completely separate from your personal M-Pesa account or any Safaricom business account. Having a developer account does not give you access to production M-Pesa services or business features. It only gives you sandbox access and the ability to request production credentials later when you are ready.
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
Once you are logged into the portal, you need to create an "app." This is not an application you deploy somewhere. It is just a named container on the portal that holds your API credentials.
After the app is created, click on it to view its details. You will see two critical values:
Copy both of these immediately and store them in a secure place. You will need them for every API call you make.
Important: do not share your consumer secret with anyone, do not post it in forums or Stack Overflow questions, and absolutely do not commit it to a public Git repository. If your credentials are compromised, someone else could make API calls on your behalf. In the sandbox this is mostly harmless, but it is a terrible habit that will cause real problems when you move to production.
You only need one app for a given project. Do not create multiple apps thinking you need separate credentials for different API endpoints. A single consumer key and secret pair works for all the Daraja APIs you selected when creating the app.
Besides your consumer key and secret, several Daraja API calls require a shortcode and passkey. In production, these come from your registered M-Pesa business account. In the sandbox, Safaricom provides standard test values that everyone uses.
Here are the sandbox test credentials you will need:
174379bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919254708374149 (use this as the PartyA / PhoneNumber in STK Push requests)You can find these in the API documentation section of the developer portal, or in the "Test Credentials" page under the sandbox documentation. The passkey is particularly important because it is used to generate the password for STK Push and other Lipa Na M-Pesa calls. The password is a Base64-encoded combination of shortcode + passkey + timestamp.
Now, set up your project's environment variables. Create a .env file in the root of your project:
# Daraja API Credentials
DARAJA_CONSUMER_KEY=your_consumer_key_from_the_portal
DARAJA_CONSUMER_SECRET=your_consumer_secret_from_the_portal
# Sandbox Config
DARAJA_BASE_URL=https://sandbox.safaricom.co.ke
DARAJA_SHORTCODE=174379
DARAJA_PASSKEY=bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919
DARAJA_PHONE=254708374149
# Callback URL (update this with your ngrok URL)
DARAJA_CALLBACK_URL=https://your-ngrok-url.ngrok-free.app/mpesa/callback
Add .env to your .gitignore file immediately if it is not already there. This prevents you from accidentally committing credentials to version control:
# Add this line to .gitignore
.env
If you are using Node.js, install the dotenv package to load these variables: npm install dotenv. Then at the top of your entry file, add require('dotenv').config() (CommonJS) or import 'dotenv/config' (ES modules). Your credentials are now available as process.env.DARAJA_CONSUMER_KEY and so on.
Here is a problem you will hit immediately when testing M-Pesa integrations locally: Safaricom needs to send callback responses to a URL on the internet, but your development server runs on localhost. Safaricom's servers cannot reach your machine directly.
The solution is ngrok, a tool that creates a secure tunnel from the internet to your local machine. When you run ngrok, it gives you a public URL (like https://abc123.ngrok-free.app) that forwards all traffic to your localhost.
Installing ngrok:
ngrok config add-authtoken YOUR_AUTH_TOKEN
Using ngrok:
Start your local server first (for example, your Express server running on port 3000). Then in a separate terminal window, run:
ngrok http 3000
ngrok will display something like this:
Forwarding https://abc123.ngrok-free.app -> http://localhost:3000
That HTTPS URL is now publicly accessible and forwards to your localhost:3000. Copy it and use it as your callback URL in Daraja API calls. For example, if your callback endpoint is /mpesa/callback, your full callback URL becomes https://abc123.ngrok-free.app/mpesa/callback.
A few important things about ngrok in practice:
.env file each time you restart. The paid plans let you reserve a stable URL, which is more convenient for ongoing development.An alternative to ngrok is localtunnel (npx localtunnel --port 3000), which is free and does not require an account. The downside is it is less reliable and sometimes the URLs do not work consistently. For serious M-Pesa development, ngrok is worth the minor setup effort.
Before you try anything complex, verify that your credentials and environment are working by generating an OAuth access token. This is the simplest API call you can make, and if it works, your setup is correct.
Create a simple test script. If you are using Node.js, create a file called test-setup.js:
require('dotenv').config();
async function testSetup() {
const consumerKey = process.env.DARAJA_CONSUMER_KEY;
const consumerSecret = process.env.DARAJA_CONSUMER_SECRET;
const baseUrl = process.env.DARAJA_BASE_URL;
if (!consumerKey || !consumerSecret) {
console.error('Missing credentials. Check your .env file.');
return;
}
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString('base64');
try {
const response = await fetch(
`${baseUrl}/oauth/v1/generate?grant_type=client_credentials`,
{
method: 'GET',
headers: {
Authorization: `Basic ${auth}`,
},
}
);
if (!response.ok) {
console.error(`HTTP Error: ${response.status} ${response.statusText}`);
const errorBody = await response.text();
console.error('Response:', errorBody);
return;
}
const data = await response.json();
console.log('Setup verified successfully!');
console.log('Access Token:', data.access_token.substring(0, 20) + '...');
console.log('Expires in:', data.expires_in, 'seconds');
} catch (error) {
console.error('Request failed:', error.message);
}
}
testSetup();
Run it with node test-setup.js. If you see "Setup verified successfully!" and a truncated access token, everything is configured correctly. You are ready to make real API calls.
If the request fails, check these things in order:
https://sandbox.safaricom.co.ke for sandbox. Not http, not api.safaricom.co.ke, not developer.safaricom.co.ke.Once this test passes, save the script. It is useful to run it whenever you suspect a credential issue or after rotating your keys.
After watching hundreds of developers set up their Daraja sandbox at McTaba Labs, these are the mistakes we see most frequently. Save yourself the debugging time by reading through these before you get stuck.
1. Whitespace in credentials. When you copy your consumer key or secret from the portal, you sometimes pick up an invisible space or newline character at the beginning or end. This breaks the Base64 encoding and causes authentication failures. After pasting into your .env file, make sure there are no extra spaces around the values.
2. Mixing sandbox and production URLs. The sandbox URL is sandbox.safaricom.co.ke. The production URL is api.safaricom.co.ke. Using production URLs with sandbox credentials (or vice versa) will always fail. Keep the base URL in your .env file so you can switch cleanly between environments without changing code.
3. Forgetting to add .env to .gitignore. This one can have real consequences. If you commit your .env file and push to a public GitHub repository, your credentials are exposed to anyone. Even if you delete the file in a later commit, it remains in the Git history. If this happens, go to the developer portal immediately and regenerate your credentials.
4. Not installing dotenv (Node.js). Creating a .env file does nothing on its own. You need the dotenv package (npm install dotenv) and you need to call require('dotenv').config() at the very top of your entry file, before you try to access any process.env values. Without this, all your environment variables will be undefined.
5. Forgetting to restart ngrok and update the callback URL. Every time you restart ngrok on the free tier, you get a new URL. If your .env file still has the old URL, callbacks will go to a dead address and you will never receive them. Update the DARAJA_CALLBACK_URL in your .env file each time you restart ngrok, and restart your server to pick up the change.
6. Trying to test with personal phone numbers in sandbox. The sandbox does not send real STK Push prompts to real phones. Use the test phone number 254708374149 provided by Safaricom. Your personal M-Pesa number will not receive any prompts during sandbox testing.
7. Creating multiple apps for the same project. You only need one app on the developer portal per project. Each app has one set of credentials that works for all the APIs you selected. Creating multiple apps just creates confusion about which credentials to use.
If you are building a production M-Pesa integration and want to avoid these pitfalls entirely, our M-Pesa Integration for Developers course (KES 9,999) walks you through the complete setup with a tested, production-ready project structure. You get a working integration you can deploy, not just sandbox experiments.
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