PlugPay

Mwenaro PlugPay API

Integrate M-Pesa into your application in minutes. The easiest way to accept, disburse, and manage mobile money.

Authentication

All requests to the Mwenaro API must encompass a valid API key in the Authorization header. You can generate Sandbox or Live keys directly from your developer dashboard.

Request Headers
Authorization: Bearer mpl_test_YOUR_API_KEY
Content-Type: application/json

STK Push (Lipa na M-Pesa)

Trigger a prompt on the customer's phone to enter their M-Pesa PIN and complete a payment.

curl -X POST "https://plugnpay.mwenaro.com/api/v1/payments?type=stk" \
  -H "Authorization: Bearer mpl_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "254712345678",
    "amount": 1050,
    "accountReference": "INV-2026",
    "transactionDesc": "Premium Subscription"
  }'

Success Response (200 OK)

{
  "success": true,
  "transactionId": "uuid-v4-string",
  "ResponseCode": "0",
  "ResponseDescription": "Success. Request accepted for processing.",
  "CheckoutRequestID": "ws_CO_1234567890",
  "CustomerMessage": "Success. Request accepted for processing."
}

Error Response (400 Bad Request)

{
  "error": "Missing required fields for STK Push",
  "status": 400
}

B2C & C2C Transfers

Send money directly from your business till to a customer (B2C), or programmatically initiate a transfer between two customers (C2C).

B2C Request Body
POST /v1/payments?type=b2c

{
  "b2cReceiver": "254712345678",
  "b2cAmount": 500,
  "b2cRemarks": "Driver Payout"
}
C2C Request Body
POST /v1/payments?type=c2c

{
  "senderPhone": "254711111111",
  "receiverPhone": "254722222222",
  "c2cAmount": 1500,
  "c2cRemarks": "Peer Transfer"
}

Webhooks

Since mobile money payments are asynchronous, SafariCom will hit Mwenaro PlugPay when a real-world event occurs (e.g. the user enters their PIN). PlugPay will then instantly POST a standardized JSON payload to your configured Webhook URL.

1. Successful Payment Event (payment.success)
POST https://your-domain.com/webhooks/mwenaro
Content-Type: application/json

{
  "event": "payment.success",
  "data": {
    "transactionId": "uuid-v4-from-initiation",
    "type": "STK_PUSH",
    "status": "SUCCESS",
    "amount": 1050,
    "phoneNumber": "254712345678",
    "mpesaReceiptNumber": "RJS8XQZZL9",
    "timestamp": "2026-03-21T10:30:00Z"
  }
}
2. Customer Canceled Event (payment.cancelled)
POST https://your-domain.com/webhooks/mwenaro
Content-Type: application/json

{
  "event": "payment.cancelled",
  "data": {
    "transactionId": "uuid-v4-from-initiation",
    "type": "STK_PUSH",
    "status": "FAILED",
    "errorMessage": "Request cancelled by user",
    "timestamp": "2026-03-21T10:31:00Z"
  }
}
3. Generic Failure / Timeout Event (payment.failed)
POST https://your-domain.com/webhooks/mwenaro
Content-Type: application/json

{
  "event": "payment.failed",
  "data": {
    "transactionId": "uuid-v4-from-initiation",
    "type": "STK_PUSH",
    "status": "FAILED",
    "errorMessage": "The balance is insufficient for the transaction",
    "timestamp": "2026-03-21T10:30:45Z"
  }
}

Security Tip

Always acknowledge receipt of a webhook with a 200 OK status. If your server fails to respond, PlugPay will retry the delivery up to 5 times using exponential backoff.