Introduction
Welcome to the Merchant Portal API documentation. This API allows you to integrate M-Pesa payments into your website or application, create payment links, manage subscriptions, and more.
Base URL
https://yourdomain.com/index.php
Response Format
All API responses are returned in JSON format with a standard structure:
{
"status": "ok" | "error",
"message": "Descriptive message",
"data": {} // Optional additional data
}
Authentication
Most endpoints require authentication. You can authenticate using either:
- Session cookies (for browser-based applications)
- API keys (for programmatic access)
POST ?action=login
Authenticate a user and establish a session.
Request Parameters
| Parameter |
Type |
Required |
Description |
| user |
String |
Yes |
Username or email address |
| password |
String |
Yes |
User's password |
Example Request
// Using fetch API
const formData = new FormData();
formData.append('action', 'login');
formData.append('user', 'merchant@example.com');
formData.append('password', 'yourpassword');
const response = await fetch('https://yourdomain.com/index.php', {
method: 'POST',
body: formData
});
const result = await response.json();
POST ?action=api_stk
Initiate an STK push using an API key for authentication.
Request Parameters
| Parameter |
Type |
Required |
Description |
| api_key |
String |
Yes |
Your API key (sk_...) |
| phone |
String |
Yes |
Customer phone number (format: 07XXXXXXXX) |
| amount |
Number |
Yes |
Amount to charge (must be greater than 0) |
| payment_id |
String |
No |
Route the STK to a specific payment account (defaults to your primary account when omitted) |
Find payment IDs in your dashboard under Payment Accounts. They follow the format #00001, #00002, and so on.
User Management
POST ?action=register
Register a new merchant account.
Request Parameters
| Parameter |
Type |
Required |
Description |
| username |
String |
Yes |
Desired username |
| email |
String |
Yes |
Valid email address |
| password |
String |
Yes |
Password (min 6 characters) |
| phone |
String |
No |
Phone number (format: 07XXXXXXXX) |
GET ?action=me
Get current user profile (requires authentication).
Example Response
{
"status": "ok",
"user": {
"id": "u_abc123",
"username": "merchant123",
"email": "merchant@example.com",
"phone": "0712345678",
"created_at": 1645628400,
"subscription": {
"status": "active",
"expires_at": 1648210800
},
"api_keys": [
{
"key": "sk_abc123def456",
"label": "Production",
"created_at": 1645628400
}
],
"payment_accounts": [
{
"type": "paybill",
"number": "123456",
"accountReference": "MyBusiness",
"payment_id": "#00001"
}
],
"links": [
{
"id": "link_abc123",
"title": "Product Payment",
"amount": 1000,
"min": 100,
"max": 5000,
"logo": "https://example.com/logo.png",
"created_at": 1645628400
}
]
}
}
Payment Account Management
POST ?action=save_payment_account
Set or update your payment account details (requires authentication).
Request Parameters
| Parameter |
Type |
Required |
Description |
| type |
String |
Yes |
Account type: "paybill" or "till" |
| number |
String |
Yes |
Business number |
| accountReference |
String |
No |
Default payment reference |
Each saved account is assigned a unique payment_id automatically. Use this identifier in API requests when you need to target a specific till or paybill.
Payment Links
POST ?action=create_link
Create a new payment link (requires authentication).
Request Parameters
| Parameter |
Type |
Required |
Description |
| title |
String |
Yes |
Link title/description |
| amount |
Number |
No |
Fixed amount (if not set, customer can enter any amount) |
| min |
Number |
No |
Minimum amount (for flexible amounts) |
| max |
Number |
No |
Maximum amount (for flexible amounts) |
| logo |
String |
No |
URL to a logo image |
Example Response
{
"status": "ok",
"public_url": "https://yourdomain.com/index.php?action=paylink&uid=u_abc123&lid=link_def456"
}
POST ?action=pay_from_link
Process a payment through a payment link (public endpoint).
Request Parameters
| Parameter |
Type |
Required |
Description |
| uid |
String |
Yes |
User ID from the payment link URL |
| lid |
String |
Yes |
Link ID from the payment link URL |
| phone |
String |
Yes |
Customer phone number (format: 07XXXXXXXX) |
| amount |
Number |
Yes |
Payment amount (must be within link limits) |
API Keys Management
POST ?action=generate_api_key
Generate a new API key (requires authentication).
Request Parameters
| Parameter |
Type |
Required |
Description |
| label |
String |
No |
Descriptive label for the key |
Example Response
{
"status": "ok",
"key": "sk_abc123def456ghi789jkl012mno345pqr678stu901"
}
Note: The API key is only returned once upon generation. Store it securely.
Code Examples
JavaScript Example - STK Push
// Function to initiate STK push
async function initiateSTKPush(apiKey, phone, amount) {
try {
const formData = new FormData();
formData.append('action', 'api_stk');
formData.append('api_key', apiKey);
formData.append('phone', phone);
formData.append('amount', amount);
formData.append('payment_id', '#00002'); // optional: target a specific payment account
const response = await fetch('https://yourdomain.com/index.php', {
method: 'POST',
body: formData
});
const result = await response.json();
if (result.status === 'ok') {
console.log('STK push initiated successfully');
return result;
} else {
throw new Error(result.message);
}
} catch (error) {
console.error('Error initiating STK push:', error);
throw error;
}
}
// Usage
initiateSTKPush('sk_your_api_key_here', '0712345678', 100)
.then(result => {
// Handle success
})
.catch(error => {
// Handle error
});
PHP Example - Create Payment Link
<?php
// Function to create a payment link
function createPaymentLink($title, $amount = null, $min = null, $max = null, $logo = '') {
// First authenticate (if not already done)
$authData = [
'action' => 'login',
'user' => 'your_username',
'password' => 'your_password'
];
// Login to get session cookie
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://yourdomain.com/index.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $authData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt'); // Save cookies
$response = curl_exec($ch);
// Now create the payment link
$linkData = [
'action' => 'create_link',
'title' => $title,
'amount' => $amount,
'min' => $min,
'max' => $max,
'logo' => $logo
];
curl_setopt($ch, CURLOPT_URL, "https://yourdomain.com/index.php");
curl_setopt($ch, CURLOPT_POSTFIELDS, $linkData);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt'); // Use saved cookies
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// Usage
$result = createPaymentLink('Product Payment', 1000, 100, 5000, 'https://example.com/logo.png');
if ($result['status'] === 'ok') {
echo "Payment link created: " . $result['public_url'];
} else {
echo "Error: " . $result['message'];
}
?>