Mobile Money · Ghana
Payments that fit your product.
Connect your POS or checkout to KolaPay. Request a Mobile Money payment directly, and receive a signed result on your server.
kp_live_. These endpoints can request real payments. A public sandbox is not available yet.Get your API key
- Register your KolaPay account with your owner identity and business details. This account gives you a dedicated payments portal, without inventory, POS sales, or vendor team access.
- In the KolaPay portal, submit your HTTPS business website and integration description to request live access. An administrator reviews your business identity and integration. You can follow the status and resubmit a rejected application with the requested changes.
- After approval, enter an integration name and HTTPS webhook URL in API keys. The URL must use port 443 and contain no embedded credentials. Generate your live API key and securely save both the key and webhook secret; they are shown only once.
Existing Makola vendors can continue using KolaPay in their vendor dashboard. Building for a client? Have the merchant create their account and issue credentials for that integration. Payments and wallet credits belong to that merchant.
Authenticate from your server
Send X-API-KEY on every payment API request. Keep the API key and webhook secret in server environment variables. Do not embed them in browser JavaScript or a distributed mobile app.
https://streetbuyai-production.up.railway.app/api/v1X-API-KEY: <your merchant API key>
Content-Type: application/jsonUse a unique merchant order ID for each checkout and reuse it when retrying initialization after a timeout.
Key management uses the merchant account access token rather than the payment API key: POST /auth/keys, GET /auth/keys, and DELETE /auth/keys/{id}. The dashboard handles these requests for you.
{
"name": "Main counter POS",
"callback_url": "https://merchant.example.com/kolapay/webhook"
}Your first payment
1. Initialize the payment
Set KOLAPAY_API_KEY on your server, then send the customer’s Mobile Money number, amount, and a unique merchant order ID. No SMS OTP is required. Amounts are in GHS.
curl 'https://streetbuyai-production.up.railway.app/api/v1/payments/initialize' \
-H "X-API-KEY: $KOLAPAY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"amount": 10.00,
"phone_number": "233245716396",
"currency": "GHS",
"payment_method": "mobile_money",
"merchant_order_id": "ORD-7789",
"narration": "Shop Order #123"
}'HTTP 200 returns a pending payment under data. Save data.payment_id and data.transaction_reference. The MoMo prompt is queued and the customer authorizes it on their phone.
{
"success": true,
"data": {
"payment_id": "00000000-0000-0000-0000-000000000000",
"transaction_reference": "MK-REFERENCE",
"status": "pending",
"amount": 10,
"currency": "GHS"
},
"message": "Payment initialized successfully"
}Use the same merchant_order_id when retrying a checkout. It is scoped to your merchant and returns the existing payment. Callback routing is taken from your API key.
2. Confirm the payment
Read payment status or receive a signed webhook. Fulfill the order only when the payment is completed. A queued prompt does not mean payment succeeded.
Payment resends
Use POST /payments/{reference}/resend with your API key and no JSON body to resend a pending payment prompt. No SMS code is required. A payment allows up to three prompt attempts with a minimum 20-second cooldown.
Check payment status before retrying. Respect retry_after_seconds when returned. Completed or failed payments cannot be resent.
Follow the payment result
curl 'https://streetbuyai-production.up.railway.app/api/v1/payments/status/TRANSACTION_REFERENCE' \
-H "X-API-KEY: $KOLAPAY_API_KEY"Replace TRANSACTION_REFERENCE with the reference returned by initialization. Read data.status. Poll every three seconds until status is completed or failed. Stop polling when your checkout closes and reconcile unresolved payments on your server.
To refresh provider status, send POST /payments/verify with the JSON body below and your X-API-KEY header.
{ "transaction_reference": "MK-REFERENCE" }You can optionally look up the customer’s Mobile Money name before initializing a payment using GET /payments/subscriber-name?phone=233245716396. The name is returned as data.name.
Endpoint reference
All payment endpoints below require X-API-KEY. Paths are relative to the production base URL.
| Method | Path | Purpose | HTTP |
|---|---|---|---|
| POST | /payments/initialize | Queue a Mobile Money prompt | 200 |
| POST | /payments/{reference}/resend | Resend a pending payment prompt | 200 |
| GET | /payments/subscriber-name?phone={phone} | Look up Mobile Money account name | 200 |
| GET | /payments/status/{transaction_reference} | Read payment status | 200 |
| POST | /payments/verify | Refresh provider status | 200 |
Receive signed webhooks
KolaPay processes provider callbacks and sends payment results to the HTTPS callback URL registered on your API key. Events include payment.completed and payment.failed; completion and failure timestamps are present when available. Check X-KolaPay-Signature before trusting an event.
{
"event": "payment.completed",
"payment_id": "00000000-0000-0000-0000-000000000000",
"merchant_order_id": "ORD-7789",
"vendor_id": "00000000-0000-0000-0000-000000000000",
"transaction_reference": "MK-REFERENCE",
"provider_reference": "PROVIDER-REFERENCE",
"status": "completed",
"amount": 10,
"currency": "GHS",
"payment_method": "mobile_money",
"paid_at": "2026-10-02T12:00:00Z"
}The signature is the hex-encoded HMAC-SHA256 of the exact raw JSON body using your webhook secret. Capture raw bytes before any JSON parser. This Node.js helper verifies a signature:
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyKolaPayWebhook(rawBody, signature, secret) {
if (!secret || typeof signature !== "string" ||
!/^[a-f0-9]{64}$/i.test(signature)) return false;
const expected = createHmac("sha256", secret)
.update(rawBody).digest();
return timingSafeEqual(expected, Buffer.from(signature, "hex"));
}Reject invalid signatures. For valid events, check the merchant order, amount, and currency against your own records. Process repeated events idempotently using the payment ID and event. Keep payment-status reconciliation available for unresolved checkouts.
Handle errors & retries
Error responses use error.code and error.message.
- 400 · Invalid request
- Check the amount, Mobile Money number, payment method, and order identifier.
- 401 / 403 · Authentication or access
- Check the API key, merchant ownership, and live approval.
- 409 · Payment final or prompt limit reached
- Check the existing payment before starting another checkout.
- 429 · Rate limit or resend cooldown
- Respect Retry-After and retry_after_seconds when supplied.
- Server error / network timeout
- Retry initialization with the same merchant order ID. Reconcile status before resending a prompt.
Settlement & support
Completed payments credit the merchant wallet, excluding the platform fee. The merchant can view payments, manage keys, and request withdrawals in the KolaPay dashboard. Withdrawals require merchant account authentication and are not available through payment API keys.
Need integration help? Email support@makolaai.com with the endpoint, error code, and transaction reference. Never include API keys, webhook secrets, or customer verification codes.
Get your API key →