npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

openmpesa-sdk

v1.0.8

Published

Official Node.js SDK for OpenMpesa API - Complete M-Pesa integration with 20+ endpoints

Readme

OpenMpesa Node.js SDK

Official Node.js SDK for the OpenMpesa API - Complete M-Pesa integration with 20+ endpoints

npm version License Downloads

🚀 Features

  • 20+ M-Pesa Endpoints: Complete Daraja API coverage
  • Promise-based: Modern async/await syntax
  • Lightweight: Minimal dependencies (only axios)
  • Well-documented: Comprehensive examples and guides
  • Production-ready: Battle-tested in production environments
  • Error Handling: Detailed error messages and status codes
  • TypeScript Ready: Full IntelliSense support
  • Platform Callback URLs: No need to provide URLs in each request (v2.0+)

⚠️ Version 2.0.0 Breaking Changes

Important: Version 2.0.0 introduces breaking changes. If you're upgrading from v1.x, please read the Migration Guide.

What Changed:

  • ✅ Removed resultURL and queueTimeOutURL from all transaction methods
  • ✅ Removed validationUrl and confirmationUrl from C2B registration
  • ✅ Removed callbackUrl from Bill Manager optin
  • ✅ Added shortCode requirement to C2B and Pull Transactions registration

Why? The OpenMpesa platform now handles all callbacks centrally, providing:

  • Automatic retry mechanism with exponential backoff
  • Callback signature verification for security
  • Centralized callback management
  • Simpler API calls

Quick Example:

// ❌ Old way (v1.x) - providing URLs in each request
await mpesa.b2c.initiate({
  amount: 1000,
  phone: '254712345678',
  resultURL: 'https://yourdomain.com/callback',  // No longer needed
  queueTimeOutURL: 'https://yourdomain.com/timeout'  // No longer needed
});

// ✅ New way (v2.0) - set callback URL once when creating merchant
await mpesa.b2c.initiate({
  amount: 1000,
  phone: '254712345678',
  remarks: 'Payment'
  // No URL parameters needed!
});

See the full migration guide below.

📋 Table of Contents

📦 Installation

npm install openmpesa-sdk

Or with yarn:

yarn add openmpesa-sdk

🏁 Getting Started

Step 1: Get Your API Key

  1. Sign up at OpenMpesa
  2. Login and navigate to your dashboard
  3. Create a merchant account with your M-Pesa credentials
  4. Copy your API key from the dashboard

Step 2: Initialize the SDK

const OpenMpesa = require('openmpesa-sdk');

// Initialize with your API key
const mpesa = new OpenMpesa('YOUR_API_KEY');

Step 3: Make Your First Request

async function makePayment() {
  try {
    const response = await mpesa.stk.push({
      amount: 100,
      phone: '254712345678',
      reference: 'ORDER-123',
      description: 'Payment for order'
    });
    
    console.log('Payment initiated:', response);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

makePayment();

🔐 Authentication

The SDK uses API key authentication. Include your API key when initializing:

const mpesa = new OpenMpesa(process.env.OPENMPESA_API_KEY);

Security Best Practices:

  • Never commit API keys to version control
  • Use environment variables to store sensitive credentials
  • Rotate API keys periodically
  • Use different API keys for development and production

Environment Variables Setup

Create a .env file in your project root:

OPENMPESA_API_KEY=your_api_key_here

Then load it in your application:

require('dotenv').config();

const mpesa = new OpenMpesa(process.env.OPENMPESA_API_KEY);

📡 API Reference

STK Push (Lipa Na M-Pesa Online)

Initiate a payment request to a customer's phone.

// Initiate STK Push
const response = await mpesa.stk.push({
  amount: 100,              // Required: Amount to charge
  phone: '254712345678',    // Required: Customer phone number (254...)
  reference: 'ORDER-123',   // Optional: Your reference/order ID
  description: 'Payment'    // Optional: Payment description
});

// Response
{
  success: true,
  MerchantRequestID: '29115-34620561-1',
  CheckoutRequestID: 'ws_CO_DMZ_123456789_12345678',
  ResponseCode: '0',
  ResponseDescription: 'Success. Request accepted for processing',
  CustomerMessage: 'Success. Request accepted for processing'
}

Query STK Push Status:

const status = await mpesa.stk.query({
  checkoutRequestId: 'ws_CO_DMZ_123456789_12345678'
});

// Response
{
  MerchantRequestID: '29115-34620561-1',
  CheckoutRequestID: 'ws_CO_DMZ_123456789_12345678',
  ResultCode: '0',  // 0 = Success, 1032 = Cancelled, etc.
  ResultDesc: 'The service request is processed successfully.'
}

Result Codes:

  • 0 - Success
  • 1032 - Request cancelled by user
  • 1037 - Timeout (user didn't enter PIN)
  • 2001 - Invalid initiator information

C2B (Customer to Business)

Simulate a customer payment to your business.

// Simulate C2B payment
const response = await mpesa.c2b.initiate({
  amount: 100,                    // Required: Amount
  phone: '254712345678',          // Required: Customer phone
  billRefNumber: 'ACCOUNT-123'    // Optional: Account reference
});

Register C2B URLs:

await mpesa.c2bRegister.register({
  validationUrl: 'https://yourdomain.com/api/validation',
  confirmationUrl: 'https://yourdomain.com/api/confirmation',
  responseType: 'Completed'  // or 'Cancelled'
});

Note: Your validation and confirmation URLs must be publicly accessible HTTPS endpoints.


B2C (Business to Customer)

Send money from your business to a customer.

const response = await mpesa.b2c.initiate({
  amount: 1000,                   // Required: Amount to send
  phone: '254712345678',          // Required: Recipient phone
  remarks: 'Salary payment',      // Optional: Transaction remarks
  occasion: 'Monthly salary'      // Optional: Occasion
});

Use Cases:

  • Salary payments
  • Refunds
  • Cashback
  • Rewards and incentives

B2B (Business to Business)

Transfer funds between businesses.

const response = await mpesa.b2b.initiate({
  amount: 5000,                       // Required: Amount
  receiverShortCode: '600000',        // Required: Receiver paybill/till
  accountReference: 'INV-2024-001',   // Optional: Invoice/reference
  remarks: 'Payment for services'     // Optional: Remarks
});

B2B Express

Fast business-to-business transfer.

const response = await mpesa.b2bExpress.initiate({
  primaryShortCode: '600000',      // Required: Sender shortcode
  receiverShortCode: '600001',     // Required: Receiver shortcode
  amount: 10000,                   // Required: Amount
  accountReference: 'TRANSFER-001' // Optional: Reference
});

B2P (Business to Pochi)

Transfer to M-Pesa Pochi (wallet).

const response = await mpesa.b2p.initiate({
  amount: 500,                // Required: Amount
  phone: '254712345678',      // Required: Recipient phone
  remarks: 'Pochi transfer'   // Optional: Remarks
});

B2C Top Up

Business to customer top-up.

const response = await mpesa.b2cTopup.initiate({
  amount: 1000,                   // Required: Amount
  partyA: '600000',               // Required: Sender shortcode
  partyB: '600001',               // Required: Receiver shortcode
  accountReference: 'TOPUP-001',  // Optional: Reference
  requester: '254712345678',      // Optional: Requester phone
  remarks: 'Account top up'       // Optional: Remarks
});

Paybill

Pay to a paybill number.

const response = await mpesa.paybill.initiate({
  amount: 500,                  // Required: Amount
  paybillNumber: '888880',      // Required: Paybill number
  billNumber: 'ACCOUNT-123',    // Required: Account number
  remarks: 'Utility payment'    // Optional: Remarks
});

Common Paybills:

  • 888880 - KRA (Tax)
  • 400200 - Equity Bank
  • 247247 - M-Pesa Paybill

Buy Goods

Pay to a till number.

const response = await mpesa.buygoods.initiate({
  amount: 1500,                  // Required: Amount
  tillNumber: '123456',          // Required: Till number
  remarks: 'Purchase from store' // Optional: Remarks
});

Account Balance

Check your M-Pesa account balance.

const response = await mpesa.balance.get({
  remarks: 'Balance check'  // Optional: Remarks
});

Note: Balance check is asynchronous. Results are sent to your callback URL.


Transaction Reversal

Reverse a completed transaction.

const response = await mpesa.reversal.initiate({
  transactionId: 'OEI2AK4Q16',        // Required: Original transaction ID
  amount: 100,                        // Required: Amount to reverse
  receiverParty: '254712345678',      // Required: Receiver party
  remarks: 'Refund for cancelled order' // Optional: Remarks
});

Important:

  • Can only reverse transactions within 24 hours
  • Requires the exact transaction ID from the original transaction
  • Amount must match the original transaction amount

Transaction Status

Query the status of any transaction.

const response = await mpesa.transactionStatus.query({
  transactionId: 'OEI2AK4Q16',  // Required: Transaction ID
  occasion: 'Status check'       // Optional: Occasion
});

Tax Remittance

Pay taxes to KRA (Kenya Revenue Authority).

const response = await mpesa.tax.remit({
  amount: 5000,                  // Required: Amount
  taxHead: 'VAT',                // Required: Tax type (VAT, PAYE, etc.)
  remarks: 'Monthly VAT payment' // Optional: Remarks
});

Tax Heads:

  • VAT - Value Added Tax
  • PAYE - Pay As You Earn
  • CORPORATION - Corporation Tax

Dynamic QR Code

Generate a QR code for payment.

const response = await mpesa.qr.generate({
  amount: 500,              // Required: Amount
  reference: 'QR-ORDER-123', // Required: Reference
  trxCode: 'BG'             // Required: Transaction code (BG, PB, etc.)
});

// Response includes base64 encoded QR code image
{
  success: true,
  ResponseCode: '0',
  QRCode: 'iVBORw0KGgoAAAANSUhEUgAA...' // Base64 image
}

Transaction Codes:

  • BG - Buy Goods
  • PB - Paybill
  • WA - Withdraw Cash
  • SM - Send Money

Standing Orders (Ratiba)

Set up recurring payments.

const response = await mpesa.ratiba.manage({
  amount: 1000,                    // Required: Amount
  phone: '254712345678',           // Required: Phone number
  frequency: 'Monthly',            // Required: Frequency
  startDate: '2024-01-01',         // Required: Start date
  endDate: '2024-12-31',           // Required: End date
  remarks: 'Monthly subscription'  // Optional: Remarks
});

Frequencies:

  • Daily
  • Weekly
  • Monthly
  • Quarterly
  • Annually

Bill Manager

M-Pesa Bill Manager enables businesses to send e-invoices and manage payments.

Important: You must opt-in before sending invoices (one-time setup).

// 1. Opt-in to Bill Manager (one-time setup)
await mpesa.billmanager.optin({
  email: '[email protected]',
  officialContact: '0710123456',
  sendReminders: true,  // Enable SMS payment reminders
  callbackUrl: 'https://yourdomain.com/mpesa/callback'
});

// 2. Send a single invoice
const invoice = await mpesa.billmanager.sendInvoice({
  externalReference: 'INV-2024-001',
  billedFullName: 'John Doe',
  billedPhoneNumber: '0722000000',
  billedPeriod: 'January 2024',
  invoiceName: 'Monthly Subscription',
  dueDate: '2024-02-15',
  accountReference: 'ACC-12345',
  amount: 5000,
  invoiceItems: [  // Optional
    { itemName: 'Service Fee', amount: '4000' },
    { itemName: 'Tax', amount: '1000' }
  ]
});

// 3. Send bulk invoices (up to 1000)
await mpesa.billmanager.sendBulkInvoices([
  {
    externalReference: 'INV-001',
    billedFullName: 'Customer 1',
    // ... other fields
  },
  {
    externalReference: 'INV-002',
    billedFullName: 'Customer 2',
    // ... other fields
  }
]);

// 4. Reconcile payment (acknowledge and send receipt)
await mpesa.billmanager.reconcile({
  paymentDate: '2024-01-15',
  paidAmount: 5000,
  accountReference: 'ACC-12345',
  transactionId: 'PJB53MYR1N',
  phoneNumber: '0722000000',
  fullName: 'John Doe',
  invoiceName: 'Monthly Subscription',
  externalReference: 'INV-2024-001'
});

// 5. Cancel a single invoice
await mpesa.billmanager.cancelInvoice('INV-2024-001');

// 6. Cancel multiple invoices
await mpesa.billmanager.cancelBulkInvoices(['INV-001', 'INV-002']);

Note: Bill Manager is a commercial API (KES 20 per invoice). Requires signed agreement with Safaricom.

Pull Transactions

Query M-Pesa transactions for a date range.

// Query transactions
const response = await mpesa.pullTransactions.query({
  startDate: '2024-01-01 00:00:00',  // Required: Start date
  endDate: '2024-01-31 23:59:59',    // Required: End date
  offSetValue: 0                      // Optional: Pagination offset
});

// Register for pull transactions (one-time setup)
await mpesa.pullTransactions.register({
  nominatedNumber: '254712345678'  // Required: Your phone number
});

Note: You must register before you can pull transactions.


IoT SIM Management

Manage IoT SIM cards (for IoT devices).

// Get all SIMs
const sims = await mpesa.iotSim.getAllSIMs('254712345678');

// Search messages
const messages = await mpesa.iotSim.searchMessages('254712345678');

// Activate SIM
await mpesa.iotSim.activateSIM('254712345678');

// Get lifecycle status
const status = await mpesa.iotSim.getLifeCycleStatus('254712345678');

// Get customer info
const info = await mpesa.iotSim.getCustomerInfo('254712345678');

// Get activation trends
const trends = await mpesa.iotSim.getActivationTrends();

// Rename asset
await mpesa.iotSim.renameAsset('254712345678', 'Device-001');

// Get location
const location = await mpesa.iotSim.getLocation('254712345678');

// Suspend or unsuspend
await mpesa.iotSim.suspendOrUnsuspend('254712345678', true); // true = suspend

// Generic manage method
await mpesa.iotSim.manage({
  action: 'getAllSIMs',
  msisdn: '254712345678'
});

Available Actions:

  • getAllSIMs - Get all SIM cards
  • searchMessages - Search SMS messages
  • simActivation - Activate a SIM
  • queryLifeCycleStatus - Check SIM lifecycle status
  • queryCustomerInfo - Get customer information
  • getActivationTrends - Get activation statistics
  • renameAsset - Rename a SIM asset
  • getLocationInfo - Get SIM location
  • suspendUnsuspend - Suspend/unsuspend SIM

IoT Location Info

Get IoT device location.

const location = await mpesa.iotLocation.get({
  msisdn: '254712345678'  // Required: Device phone number
});

// Response
{
  success: true,
  location: {
    latitude: -1.286389,
    longitude: 36.817223,
    accuracy: 100
  }
}

❌ Error Handling

Basic Error Handling

try {
  const response = await mpesa.stk.push({
    amount: 100,
    phone: '254712345678',
    reference: 'ORDER-123'
  });
  console.log('Success:', response);
} catch (error) {
  console.error('Error:', error.message);
}

Detailed Error Handling

try {
  const response = await mpesa.stk.push({
    amount: 100,
    phone: '254712345678',
    reference: 'ORDER-123'
  });
} catch (error) {
  if (error.response) {
    // API returned an error response
    console.error('API Error:', {
      status: error.response.status,
      message: error.response.data.message,
      details: error.response.data
    });
    
    // Handle specific error codes
    if (error.response.status === 401) {
      console.error('Invalid API key');
    } else if (error.response.status === 429) {
      console.error('Rate limit exceeded');
    }
  } else if (error.request) {
    // Request was made but no response received
    console.error('Network Error:', error.message);
  } else {
    // Error in request setup
    console.error('Error:', error.message);
  }
}

Common Error Codes

| Code | Meaning | Solution | |------|---------|----------| | 400 | Bad Request | Check request parameters | | 401 | Unauthorized | Verify API key is correct | | 403 | Forbidden | Check subscription status | | 404 | Not Found | Verify endpoint URL | | 429 | Too Many Requests | Reduce request rate or upgrade plan | | 500 | Server Error | Contact support |


💡 Best Practices

1. Use Environment Variables

// ✅ Good
const mpesa = new OpenMpesa(process.env.OPENMPESA_API_KEY);

// ❌ Bad
const mpesa = new OpenMpesa('hardcoded-api-key');

2. Implement Retry Logic

async function stkPushWithRetry(data, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await mpesa.stk.push(data);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}

3. Validate Phone Numbers

function validateKenyanPhone(phone) {
  // Remove spaces and special characters
  phone = phone.replace(/[\s\-\(\)]/g, '');
  
  // Convert to 254 format
  if (phone.startsWith('0')) {
    phone = '254' + phone.substring(1);
  } else if (phone.startsWith('+254')) {
    phone = phone.substring(1);
  } else if (phone.startsWith('254')) {
    // Already in correct format
  } else {
    throw new Error('Invalid phone number format');
  }
  
  // Validate length and format
  if (!/^254[17]\d{8}$/.test(phone)) {
    throw new Error('Invalid Kenyan phone number');
  }
  
  return phone;
}

// Usage
const phone = validateKenyanPhone('0712345678'); // Returns: 254712345678

4. Handle Callbacks Properly

// Express.js example
app.post('/mpesa/callback', async (req, res) => {
  // Always respond immediately
  res.json({ ResultCode: 0, ResultDesc: 'Accepted' });
  
  // Process callback asynchronously
  try {
    const { Body } = req.body;
    if (Body?.stkCallback) {
      const { CheckoutRequestID, ResultCode, ResultDesc } = Body.stkCallback;
      
      if (ResultCode === 0) {
        // Payment successful
        await processSuccessfulPayment(CheckoutRequestID);
      } else {
        // Payment failed
        await handleFailedPayment(CheckoutRequestID, ResultDesc);
      }
    }
  } catch (error) {
    console.error('Callback processing error:', error);
  }
});

5. Log Transactions

async function makePayment(orderData) {
  const startTime = Date.now();
  
  try {
    const response = await mpesa.stk.push({
      amount: orderData.amount,
      phone: orderData.phone,
      reference: orderData.orderId
    });
    
    // Log successful request
    console.log({
      timestamp: new Date().toISOString(),
      orderId: orderData.orderId,
      checkoutRequestId: response.CheckoutRequestID,
      duration: Date.now() - startTime,
      status: 'initiated'
    });
    
    return response;
  } catch (error) {
    // Log error
    console.error({
      timestamp: new Date().toISOString(),
      orderId: orderData.orderId,
      error: error.message,
      duration: Date.now() - startTime,
      status: 'failed'
    });
    
    throw error;
  }
}

📚 Examples

Complete Payment Flow

const OpenMpesa = require('openmpesa-sdk');
const mpesa = new OpenMpesa(process.env.OPENMPESA_API_KEY);

async function processOrder(order) {
  try {
    // 1. Initiate STK Push
    console.log('Initiating payment...');
    const payment = await mpesa.stk.push({
      amount: order.amount,
      phone: order.customerPhone,
      reference: order.orderId,
      description: `Payment for order ${order.orderId}`
    });
    
    console.log('Payment initiated:', payment.CheckoutRequestID);
    
    // 2. Save checkout request ID to database
    await saveToDatabase({
      orderId: order.orderId,
      checkoutRequestId: payment.CheckoutRequestID,
      status: 'pending'
    });
    
    // 3. Poll for status (optional - better to use callbacks)
    let attempts = 0;
    const maxAttempts = 6; // 60 seconds total
    
    while (attempts < maxAttempts) {
      await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10s
      
      const status = await mpesa.stk.query({
        checkoutRequestId: payment.CheckoutRequestID
      });
      
      if (status.ResultCode === '0') {
        console.log('Payment successful!');
        await updateOrderStatus(order.orderId, 'paid');
        return { success: true, status: 'paid' };
      } else if (status.ResultCode !== undefined && status.ResultCode !== '0') {
        console.log('Payment failed:', status.ResultDesc);
        await updateOrderStatus(order.orderId, 'failed');
        return { success: false, reason: status.ResultDesc };
      }
      
      attempts++;
    }
    
    console.log('Payment timeout');
    return { success: false, reason: 'timeout' };
    
  } catch (error) {
    console.error('Payment error:', error.message);
    await updateOrderStatus(order.orderId, 'error');
    throw error;
  }
}

// Usage
processOrder({
  orderId: 'ORD-123',
  amount: 1500,
  customerPhone: '254712345678'
});

Bulk Payments (B2C)

async function processBulkPayments(payments) {
  const results = [];
  
  for (const payment of payments) {
    try {
      const response = await mpesa.b2c.initiate({
        amount: payment.amount,
        phone: payment.phone,
        remarks: payment.remarks
      });
      
      results.push({
        phone: payment.phone,
        status: 'success',
        transactionId: response.ConversationID
      });
      
      // Rate limiting: wait 1 second between requests
      await new Promise(resolve => setTimeout(resolve, 1000));
      
    } catch (error) {
      results.push({
        phone: payment.phone,
        status: 'failed',
        error: error.message
      });
    }
  }
  
  return results;
}

// Usage
const payments = [
  { phone: '254712345678', amount: 1000, remarks: 'Salary' },
  { phone: '254798765432', amount: 1500, remarks: 'Salary' },
  { phone: '254723456789', amount: 2000, remarks: 'Salary' }
];

const results = await processBulkPayments(payments);
console.log('Bulk payment results:', results);

Subscription Payments

async function chargeSubscription(subscription) {
  try {
    const response = await mpesa.stk.push({
      amount: subscription.amount,
      phone: subscription.customerPhone,
      reference: `SUB-${subscription.id}`,
      description: `${subscription.plan} subscription`
    });
    
    // Save for webhook processing
    await saveSubscriptionCharge({
      subscriptionId: subscription.id,
      checkoutRequestId: response.CheckoutRequestID,
      amount: subscription.amount,
      status: 'pending'
    });
    
    return response;
  } catch (error) {
    // Handle failed charge
    await logFailedCharge(subscription.id, error.message);
    throw error;
  }
}

🔧 Troubleshooting

Issue: "Invalid API Key"

Solution:

  • Verify your API key is correct
  • Check if API key is properly loaded from environment variables
  • Ensure no extra spaces or newlines in the API key

Issue: "Request timeout"

Solution:

  • Check your internet connection
  • Verify the base URL is correct
  • Increase timeout in axios configuration

Issue: "Phone number invalid"

Solution:

  • Use format: 254XXXXXXXXX (12 digits)
  • Remove spaces, dashes, and parentheses
  • Ensure number starts with 254 (not +254 or 0)

Issue: "Insufficient funds"

Solution:

  • Check your M-Pesa account balance
  • Ensure you have enough float for B2C transactions
  • Contact Safaricom to increase your transaction limits

Issue: "Rate limit exceeded"

Solution:

  • Implement request throttling
  • Upgrade your subscription plan
  • Use batch processing for bulk operations

📞 Support

Documentation

Community

Contributing

Contributions are welcome! Please read our Contributing Guide first.


📄 License

MIT © OpenMpesa Team


🙏 Acknowledgments

Built with ❤️ by the OpenMpesa Team. Special thanks to all contributors and the M-Pesa developer community.


📊 API Endpoints Quick Reference

| Endpoint | Method | Description | |----------|--------|-------------| | stk.push() | POST | Initiate STK Push payment | | stk.query() | POST | Query STK Push status | | c2b.initiate() | POST | Simulate C2B payment | | c2bRegister.register() | POST | Register C2B URLs | | b2c.initiate() | POST | Business to Customer transfer | | b2cTopup.initiate() | POST | B2C Top Up | | b2b.initiate() | POST | Business to Business transfer | | b2bExpress.initiate() | POST | B2B Express transfer | | b2p.initiate() | POST | Business to Pochi transfer | | paybill.initiate() | POST | Pay to Paybill | | buygoods.initiate() | POST | Pay to Till Number | | balance.get() | POST | Check Account Balance | | reversal.initiate() | POST | Reverse Transaction | | transactionStatus.query() | POST | Query Transaction Status | | tax.remit() | POST | Tax Remittance to KRA | | qr.generate() | POST | Generate Dynamic QR Code | | ratiba.manage() | POST | Manage Standing Orders | | billmanager.manage() | POST | Manage Bills | | pullTransactions.query() | POST | Query Transactions | | pullTransactions.register() | POST | Register for Pull Transactions | | iotSim.manage() | POST | IoT SIM Management | | iotLocation.get() | POST | Get IoT Device Location |


Ready to integrate M-Pesa? Get started now! 🚀