Advanced Configuration
Detailed configuration guide for B2C, B2B, reversals, and advanced M-Pesa operations
Overview
This guide covers advanced M-Pesa operations including B2C payments, B2B transfers, transaction reversals, status queries, and account balance checks. These operations require additional credentials beyond the basic STK Push configuration.
Required Credentials
Complete Configuration Interface
interface MpesaConfig {
consumerKey: string;
consumerSecret: string;
passkey: string;
shortcode: string;
environment: "sandbox" | "production";
callbackUrl?: string;
initiatorName: string;
securityCredential: string;
resultUrl: string;
timeoutUrl: string;
}Full SDK Initialization
import { MpesaClient } from "@singularity-payments/nextjs";
const client = new MpesaClient({
consumerKey: process.env.MPESA_CONSUMER_KEY,
consumerSecret: process.env.MPESA_CONSUMER_SECRET,
passkey: process.env.MPESA_PASSKEY,
shortcode: process.env.MPESA_SHORTCODE,
environment: "sandbox",
callbackUrl: process.env.MPESA_CALLBACK_URL,
initiatorName: process.env.MPESA_INITIATOR_NAME,
securityCredential: process.env.MPESA_SECURITY_CREDENTIAL,
resultUrl: process.env.MPESA_RESULT_URL,
timeoutUrl: process.env.MPESA_TIMEOUT_URL,
});Sandbox Test Credentials
STK Push Configuration
For STK Push operations, use shortcode 174379:
MPESA_CONSUMER_KEY=your_sandbox_consumer_key
MPESA_CONSUMER_SECRET=your_sandbox_consumer_secret
MPESA_PASSKEY=bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919
MPESA_SHORTCODE=174379
MPESA_ENVIRONMENT=sandbox
MPESA_CALLBACK_URL=https://your-ngrok-url.ngrok.io/api/mpesa/callbackB2C, B2B, and Advanced Operations Configuration
For B2C, B2B, reversals, transaction status, and account balance operations, use shortcode 600998:
MPESA_CONSUMER_KEY=your_sandbox_consumer_key
MPESA_CONSUMER_SECRET=your_sandbox_consumer_secret
MPESA_SHORTCODE=600998
MPESA_ENVIRONMENT=sandbox
MPESA_INITIATOR_NAME=testapi
MPESA_RESULT_URL=https://your-ngrok-url.ngrok.io/api/mpesa/result
MPESA_TIMEOUT_URL=https://your-ngrok-url.ngrok.io/api/mpesa/timeoutInitiator Password: Safaricom123!!
Complete Environment Variables
MPESA_CONSUMER_KEY=your_sandbox_consumer_key
MPESA_CONSUMER_SECRET=your_sandbox_consumer_secret
MPESA_PASSKEY=bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919
MPESA_SHORTCODE=174379
MPESA_ENVIRONMENT=sandbox
MPESA_CALLBACK_URL=https://your-ngrok-url.ngrok.io/api/mpesa/callback
MPESA_INITIATOR_NAME=testapi
MPESA_SECURITY_CREDENTIAL=your_generated_security_credential
MPESA_RESULT_URL=https://your-ngrok-url.ngrok.io/api/mpesa/result
MPESA_TIMEOUT_URL=https://your-ngrok-url.ngrok.io/api/mpesa/timeoutGenerating Security Credential
The security credential is an encrypted version of your initiator password. Here's how to generate it:
Step 1: Access Credential Generator
- Go to Safaricom Developer Portal Test Credentials
- Log in to your account
Step 2: Generate Credential
- In the Initiator Security Password field, enter:
Safaricom123!! - Select Sandbox from the environment dropdown
- Click Generate Security Credential
- Copy the generated credential
Step 3: Add to Environment Variables
MPESA_SECURITY_CREDENTIAL=<paste_generated_credential_here>Production Security Credential
For production:
- Use your production initiator password provided by Safaricom
- Select Production environment when generating
- Store securely in environment variables
Configuration Fields Explained
Consumer Key & Consumer Secret
OAuth credentials used to authenticate your application with the M-Pesa API.
Sandbox: Generated when you create an app on the developer portal
Production: Provided by Safaricom after going live
Security: Never commit to version control. Store in environment variables and rotate regularly.
MPESA_CONSUMER_KEY=your_consumer_key
MPESA_CONSUMER_SECRET=your_consumer_secretPasskey
A unique key used to generate passwords for STK Push requests.
Sandbox Passkey:
bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919Production Passkey: Provided by Safaricom when your app goes live
The SDK automatically generates a password using:
Base64(Shortcode + Passkey + Timestamp)MPESA_PASSKEY=bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919Shortcode
Your M-Pesa business number used for transactions.
Sandbox Shortcodes:
174379: For STK Push operations600998: For B2C, B2B, reversals, transaction status, and account balance operations
Production Shortcode: Your actual business number provided by Safaricom
MPESA_SHORTCODE=174379
MPESA_SHORTCODE=600998Environment
Specifies which M-Pesa environment to use.
Sandbox (Development/Testing):
- Base URL:
https://sandbox.safaricom.co.ke - Uses test credentials
- No real money transactions
- Transactions refunded automatically
Production (Live):
- Base URL:
https://api.safaricom.co.ke - Uses production credentials
- Real money transactions
- Requires Safaricom approval
environment: "sandbox";
environment: "production";Callback URL
The URL where M-Pesa sends transaction notifications after processing STK Push requests.
Requirements:
- Must be publicly accessible
- Must use HTTPS in production
- Must respond with status 200
- Must respond within 30 seconds
Development: Use ngrok, Cloudflare Tunnel, or LocalTunnel
MPESA_CALLBACK_URL=https://abc123.ngrok.io/api/mpesa/callback
MPESA_CALLBACK_URL=https://yourdomain.com/api/mpesa/callbackInitiator Name
The username for initiating B2C, B2B, reversals, and other organizational transactions.
When Required:
- B2C (Business to Customer)
- B2B (Business to Business)
- Transaction Reversal
- Transaction Status Query
- Account Balance Query
Sandbox Initiator: testapi
Production Initiator: Provided by Safaricom during onboarding
MPESA_INITIATOR_NAME=testapiSecurity Credential
An encrypted password used to authenticate organizational transactions.
Generated using the Safaricom Developer Portal credential generator with your initiator password.
Sandbox: Generate using password Safaricom123!!
Production: Generate using your production initiator password
MPESA_SECURITY_CREDENTIAL=<paste_generated_credential_here>Result URL
URL where M-Pesa sends the final result of organizational transactions. In the SDK the result url is usually passed when initiating transactions, but we set it globally if you are not doing multiple types of transactions eg( B2C and Reversals) and as a fallback.
When Required:
- B2C payments
- B2B payments
- Transaction reversals
- Transaction status queries
- Account balance queries
Requirements:
- Must be publicly accessible
- Must use HTTPS in production
- Should return status 200
MPESA_RESULT_URL=https://yourdomain.com/api/mpesa/resultTimeout URL
URL where M-Pesa sends a notification if a transaction times out.
When Called:
- Transaction takes too long to process
- No response from customer
- System timeout (usually after 30-60 seconds)
MPESA_TIMEOUT_URL=https://yourdomain.com/api/mpesa/timeoutAdvanced Client Options
Complete Configuration with Options
interface MpesaClientOptions {
callbackOptions?: {
onSuccess?: (data: ParsedCallbackData) => void | Promise<void>;
onFailure?: (data: ParsedCallbackData) => void | Promise<void>;
validateIp?: boolean;
allowedIps?: string[];
isDuplicate?: (checkoutRequestId: string) => boolean | Promise<boolean>;
};
retryOptions?: {
maxRetries?: number;
initialDelayMs?: number;
maxDelayMs?: number;
backoffMultiplier?: number;
};
rateLimitOptions?: {
enabled?: boolean;
maxRequests?: number;
windowMs?: number;
redis?: RedisLike;
};
requestTimeout?: number;
}Full Implementation Example
import { MpesaClient } from "@singularity-payments/core";
const client = new MpesaClient(
{
consumerKey: process.env.MPESA_CONSUMER_KEY,
consumerSecret: process.env.MPESA_CONSUMER_SECRET,
passkey: process.env.MPESA_PASSKEY,
shortcode: process.env.MPESA_SHORTCODE,
environment: "sandbox",
callbackUrl: process.env.MPESA_CALLBACK_URL,
initiatorName: process.env.MPESA_INITIATOR_NAME,
securityCredential: process.env.MPESA_SECURITY_CREDENTIAL,
resultUrl: process.env.MPESA_RESULT_URL,
timeoutUrl: process.env.MPESA_TIMEOUT_URL,
},
{
callbackOptions: {
onSuccess: async (data) => {
console.log("Payment successful:", data);
},
onFailure: async (data) => {
console.log("Payment failed:", data);
},
validateIp: true,
isDuplicate: async (checkoutRequestId) => {
return false;
},
},
retryOptions: {
maxRetries: 3,
initialDelayMs: 1000,
maxDelayMs: 10000,
backoffMultiplier: 2,
},
rateLimitOptions: {
enabled: true,
maxRequests: 100,
windowMs: 60000,
},
requestTimeout: 30000,
},
);Testing Different Operations
STK Push
await client.stkPush({
amount: 1,
phoneNumber: "254712345678",
accountReference: "TEST-001",
transactionDesc: "Test payment",
});B2C Payment
await client.b2c({
amount: 100,
phoneNumber: "254712345678",
commandID: "BusinessPayment",
remarks: "Salary payment",
occasion: "Monthly",
});B2B Payment
await client.b2b({
amount: 1000,
receiverShortcode: "600000",
commandID: "BusinessPayBill",
remarks: "Payment for goods",
accountReference: "INV-001",
});Transaction Reversal
await client.reversal({
transactionID: "NEF61H8J60",
amount: 100,
remarks: "Reversal request",
occasion: "Customer refund",
});Transaction Status
await client.transactionStatus({
transactionID: "NEF61H8J60",
remarks: "Status check",
occasion: "Verification",
});Account Balance
await client.accountBalance({
remarks: "Balance check",
});Moving to Production
Production Checklist
- Applied for production access on Safaricom Developer Portal
- Completed all compliance requirements
- Received production credentials
- Generated production security credential
- Updated all environment variables
- Changed
environmenttoproduction - Updated callback URLs to production domains
- Tested with real phone numbers
- Implemented proper error handling
- Set up monitoring and logging
- Configured rate limiting
- Implemented duplicate prevention
- Secured all API keys
Production Configuration
MPESA_CONSUMER_KEY=prod_consumer_key_here
MPESA_CONSUMER_SECRET=prod_consumer_secret_here
MPESA_PASSKEY=prod_passkey_from_safaricom
MPESA_SHORTCODE=your_actual_business_number
MPESA_ENVIRONMENT=production
MPESA_CALLBACK_URL=https://api.yourdomain.com/api/mpesa/callback
MPESA_INITIATOR_NAME=your_production_initiator
MPESA_SECURITY_CREDENTIAL=prod_security_credential_here
MPESA_RESULT_URL=https://api.yourdomain.com/api/mpesa/result
MPESA_TIMEOUT_URL=https://api.yourdomain.com/api/mpesa/timeoutSecurity Best Practices
Environment Variables
Never commit .env to version control:
.env
.env.local
.env.productionMultiple Environments
MPESA_ENVIRONMENT=sandbox
MPESA_ENVIRONMENT=productionCredential Rotation
- Change consumer keys every 90 days
- Update security credentials quarterly
Secret Management Services
- AWS Secrets Manager
- Google Cloud Secret Manager
- Azure Key Vault
- Vercel Environment Variables
- Railway Variables
Common Configuration Issues
401 Unauthorized
Cause: Invalid consumer key or consumer secret
Solution:
- Verify credentials from developer portal
- Ensure no extra spaces or quotes in
.env - Check if credentials are for correct environment
- Regenerate credentials if needed
400 Bad Request - Invalid Shortcode
Cause: Using wrong shortcode for operation
Solution:
- STK Push: Use
174379 - B2C/B2B/Advanced: Use
600998 - Production: Use your actual business shortcode
- Verify shortcode matches your app configuration
Callback Not Received
Cause: Callback URL not accessible
Solution:
- Use ngrok or similar for local development
- Ensure URL is publicly accessible
- Check firewall settings
- Verify route is correctly set up
- Return status 200 from callback endpoint
Phone Number Format Error
Cause: Incorrect phone number format
Solution:
- Use format:
254XXXXXXXXX(12 digits) - Start with country code
254 - Remove spaces, dashes, plus signs
- Example:
254712345678
Invalid Security Credential
Cause: Incorrectly generated or expired security credential
Solution:
- Regenerate using Safaricom Developer Portal
- Ensure using correct initiator password
- Select correct environment when generating
- Copy entire credential without modifications