M-PESA Gateway API v1 β€” Partner Integration Guide

This guide is strictly focused on how partners interact with the gateway and the callback payloads the gateway will forward to the partner’s endpoint. All examples are server-side (recommended).


Overview

Partners call the gateway to request STK Push payments. The gateway processes the request and will forward a summarized result to the partner's callback_url. For the gateway to accept a request, callback_url is required. Requests without it will be rejected.

🌐 Base URL

https://payments.kodawaritechnologies.com/api/v1

πŸ” Authentication

Include your partner API key in the header X-API-KEY. Keep it secret and server-side.

HeaderPurposeRequired
X-API-KEYPartner API key (secret)Yes
Content-Typeapplication/jsonYes
X-Idempotency-KeyPrevent duplicate requestsRecommended

πŸ’³ Initiate Payment β€” STK Push

Endpoint: POST https://payments.kodawaritechnologies.com/api/v1/mpesa/stk_push

Request body (JSON)
FieldTypeRequiredDescription
phonestringYes2547XXXXXXXX (international format)
amountnumberYesAmount in KES
referencestringNoPartner reference (optional)
callback_urlstringYes β€” requiredURL the gateway will POST the summarized result to (required)
curl -X POST "https://payments.kodawaritechnologies.com/api/v1/mpesa/stk_push" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: YOUR_CLIENT_API_KEY" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -d '{
    "phone":"254712345678",
    "amount":150,
    "reference":"INV-2025-001",
    "callback_url":"https://yourapp.example.com/payment_callback"
  }'
Accepted / success response
{
  "status": "success",
  "transaction_id": 102,
  "message": "STK Push accepted for processing"
}
Rejected request (missing callback_url)
HTTP 400 Bad Request
{
  "status": "error",
  "message": "callback_url is required"
}
Idempotent duplicate response
{
  "status": "duplicate",
  "transaction_id": 102,
  "message": "Duplicate request (idempotency)"
}

πŸ” What the gateway forwards to your callback_url

When the transaction completes (success or fail), the gateway will POST a summarized JSON payload to the callback_url you supplied. The gateway will also store the full raw payload for auditing.

{
  "transaction_id": 102,
  "merchant_request_id": "29115-34620561-1",
  "checkout_request_id": "ws_CO_22052025084523789",
  "result_code": 0,
  "result_desc": "Processed successfully.",
  "amount": 150,
  "mpesa_receipt": "RKT7S9T2UB",
  "transaction_date": "2025-05-22T08:47:05Z",
  "phone": "254712345678",
  "status": "successful"
}

βœ… Recommended callback handling (partner)

Your callback endpoint must:

  • Accept an HTTP POST with JSON.
  • Return HTTP 200 quickly to acknowledge receipt.
  • Update your internal records and perform any business logic (e.g., credit user account) when you receive a successful status.
  • Validate payload authenticity if you implement HMAC or other verification (optional β€” we can add an HMAC option later).
# Example partner callback endpoint (pseudo)
POST /payment_callback
Content-Type: application/json

# gateway will send JSON like the 'partner-callback' example above
# MUST return 200 OK to acknowledge

πŸ”§ Client examples (server-side)

Always call the gateway from server-side code. Do not embed X-API-KEY in front-end code.

Python (requests)
import os, requests, uuid
API_KEY = os.getenv('MPESA_GATEWAY_API_KEY')
URL = "https://payments.kodawaritechnologies.com/api/v1/mpesa/stk_push"
payload = {"phone":"254712345678","amount":150,"reference":"INV-2025-001","callback_url":"https://yourapp.example.com/payment_callback"}
headers = {"Content-Type":"application/json","X-API-KEY": API_KEY,"X-Idempotency-Key": str(uuid.uuid4())}
resp = requests.post(URL, json=payload, headers=headers, timeout=30)
print(resp.status_code, resp.json())
PHP (cURL)
<?php
$apiKey = getenv('MPESA_GATEWAY_API_KEY');
$url = 'https://payments.kodawaritechnologies.com/api/v1/mpesa/stk_push';
$data = json_encode(['phone'=>'254712345678','amount'=>150,'reference'=>'INV-2025-001','callback_url'=>'https://yourapp.example.com/payment_callback']);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json','X-API-KEY: '.$apiKey,'X-Idempotency-Key: '.bin2hex(random_bytes(8))]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch); curl_close($ch);
echo $response;
?>

πŸ“˜ Best practices

  • Every request must include callback_url. Missing callback_url results in a 400 rejection.
  • Use X-Idempotency-Key to prevent duplicate transactions.
  • Keep X-API-KEY server-side (never in browser JS).
  • Persist transaction IDs returned by gateway for reconciliation.
  • Use HTTPS for your callback endpoint and validate incoming requests if possible.

🀝 Support

Email: support@kodawaritechnologies.com
Phone: 254 768 737 559 / 254 755 977 252

Version: API v1.0 β€’ Last Updated: November 7, 2025 β€’ Status: Production