Avatar

Lipwa API Documentation

Visit lipwa.app →

API Documentation

Welcome to the Lipwa API documentation. Our API provides seamless M-Pesa payment integration for your applications with simple REST endpoints.

Authentication

All API requests require authentication using an API key. You can find your API key in the account dashboard under the settings page.

Headers

Authorization: 'Bearer {your_api_key}'

Note: Your API KEY can be found in the account section on the settings page.

Send M-Pesa STK Push

POST https://pay.lipwa.app/api/payments

Headers

Authorization: 'Bearer {apikey}' required

Request Body

amount integer required e.g., 1000 (min amount: 10)
phone_number string required All formats supported (254, 07, 01) provided it's a valid M-Pesa number
channel_id string required Channel ID of the account receiving payment (found in channels section)
callback_url string Endpoint URL where payment status response will be sent
api_ref string or an object Your reference code for identifying the payment

Response (Status 201)

{
  "MerchantRequestID": "f373-48f0-8696-f5c35e1b0dc622175462",
  "CheckoutRequestID": "ws_CO_210820251023364117077820",
  "ResponseCode": "0",
  "ResponseDescription": "Success. Request accepted for processing",
  "CustomerMessage": "Success. Request accepted for processing"
}

Sample Code (Node.js)

const axios = require('axios');

async function sendStkPush() {
  let options = {
    method: 'POST',
    url: 'https://pay.lipwa.app/api/payments',
    headers: {
      Authorization: 'Bearer {your_apikey}',
      'Content-Type': 'application/json'
    },
    data: {
      phone_number: '0712345678', // You can also use 254** format
      amount: 100,
      channel_id: 'CH_EIU3939',
      callback_url: 'https://callback.com', // Use your own callback endpoint
      api_ref: {
           name: 'John Doe',
           email: 'johndoe@gmail.com'
      } // Used to track user/person who made payment
    }
  };
  
  let response = await axios(options);
  console.log(response.data);
}

Callback Response

Successful Payment

{
  "status": "payment.success",
  "transaction_id": "TR_TKJKJ93JOP",
  "checkout_id": "ws_CO_210820251023364117077820",
  "amount": 100,
  "phone_number": "25412345678",
  "mpesa_code": "TKJKJ93JOP",
  "api_ref": {
           name: "John Doe",
           email: "johndoe@gmail.com"
      },
  "payment_date": "2025-08-21T10:42:32+03:00" // Africa/Nairobi timezone
}

Failed Payment

{
  "status": "payment.failed",
  "checkout_id": "ws_CO_210820251023364117077820",
  "amount": 100,
  "phone_number": "25412345678",
  "mpesa_code": null,
  "api_ref": {
           name: "John Doe",
           email: "johndoe@gmail.com"
      },
  "payment_date": "2025-08-21T10:42:32+03:00" // Africa/Nairobi timezone
}

Payment Status Types

payment.queued - When a payment request is created
payment.success - When payment is successfully processed
payment.failed - When payment fails or is cancelled

Check Transaction Status

GET https://pay.lipwa.app/api/status?ref={mpesaCheckoutId}

Headers

Authorization: 'Bearer {apikey}' required

Query Parameters

ref string required M-Pesa checkout ID

Sample Code (Node.js)

const axios = require('axios');

async function payStatus() {
  let options = {
    method: 'GET',
    url: 'https://pay.lipwa.app/api/status?ref={mpesaCheckoutId}',
    headers: {
      Authorization: 'Bearer {your_api_key}'
    }
  };
  
  let response = await axios(options);
  console.log(response.data);
}

payStatus();

Response Sample

{
  "status": "payment.success",
  "pay_reference": "ws_CO_200820251019562117077820",
  "transaction_date": "2025-08-20T10:19:54+03:00",
  "amount": "5",
  "receipt": "THK74U6CTV",
  "api_ref": "name@gmail.com"
}

Get Account Transactions

GET https://pay.lipwa.app/api/transactions?limit=50

Headers

Authorization: 'Bearer {apikey}' required

Query Parameters

limit string optional e.g., 50 (fetches recent 50 transactions, if not included fetches all)

Sample Code (Node.js)

const axios = require('axios');

async function Transactions() {
  let options = {
    method: 'GET',
    url: 'https://pay.lipwa.app/api/transactions?limit=2',
    headers: {
      Authorization: 'Bearer {your_api_key}'
    }
  };
  
  let response = await axios(options);
  console.log(response.data);
}

Transactions();

Response Sample

{
  "transactions": [
    {
      "transaction_id": "TR_THK75EOH2Z",
      "description": "Received Kes 500 from 254187079824",
      "amount": 500,
      "transaction_type": "Credit",
      "phone": 254187079824,
      "reference": "ws_CO_200820251228371117077820",
      "receipt_number": "THK75EOH2Z",
      "payment_date": "2025-08-20T12:28:48+03:00"
    },
    {
      "transaction_id": "TR_THK86OFIMS",
      "description": "Received Kes 1200 from 254734479920",
      "amount": 1200,
      "transaction_type": "Credit",
      "phone": 254734479920,
      "reference": "ws_CO_200820251652424117077820",
      "receipt_number": "THK86OFIMS",
      "payment_date": "2025-08-20T16:52:54+03:00"
    }
  ]
}

Rate Limits

To ensure service stability, we enforce the following rate limits:

10 requests per second

Warning: If you exceed these limits, you'll receive a 429 Too Many Requests response.