Mobile Money is the default way millions of customers pay across Kenya, Zimbabwe, Ghana, Uganda, Tanzania, Rwanda and beyond. The Opei Payments API abstracts every operator behind a single, consistent interface so you can charge a wallet, confirm a payment, and settle to your business account in minutes — not weeks of per-operator onboarding.
01What you get out of the box
- One API for M-Pesa, EcoCash, MTN MoMo, Airtel Money, Orange Money and more.
- Real-time settlement into your Opei balance — no T+2 waits.
- Automatic retries, idempotency keys and signed webhooks.
- Test wallets for every operator, no operator sandbox paperwork.
- Local currencies preserved end-to-end (KES, ZWG, GHS, UGX, TZS, RWF, XOF).
02Prerequisites
- An Opei Business account and a live-mode API key from your dashboard.
- A server that can make outbound HTTPS requests and receive webhooks.
- The country and operator you want to collect from (e.g.
KE/mpesa).
03Authenticate your requests
All requests to https://api.opei.business are authenticated with a bearer token. Never ship a secret key to the browser — call the API from your backend.
curl https://api.opei.business/v1/health \
-H "Authorization: Bearer $OPEI_SECRET_KEY"04Create a Mobile Money charge
A charge tells Opei to prompt the customer's phone for a payment. Pass the amount in the local currency's smallest unit, the customer's MSISDN in E.164 format, and the operator.
curl https://api.opei.business/v1/charges \
-H "Authorization: Bearer $OPEI_SECRET_KEY" \
-H "Idempotency-Key: order_10231" \
-H "Content-Type: application/json" \
-d '{
"amount": 25000,
"currency": "KES",
"method": "mobile_money",
"operator": "mpesa",
"country": "KE",
"phone": "+254712345678",
"reference": "ORDER-10231",
"description": "Order #10231",
"callback_url": "https://yourapp.com/webhooks/opei"
}'The response returns a charge_id and a status of pending. Opei then pushes an STK/USSD prompt to the customer's SIM.
05Handle the webhook
When the customer enters their PIN, Opei POSTs a signed event to your callback_url. Verify the signature and update your order.
// Node.js (Express)
import crypto from "node:crypto";
app.post("/webhooks/opei", express.raw({ type: "*/*" }), (req, res) => {
const signature = req.headers["opei-signature"];
const expected = crypto
.createHmac("sha256", process.env.OPEI_WEBHOOK_SECRET)
.update(req.body)
.digest("hex");
if (signature !== expected) return res.sendStatus(400);
const event = JSON.parse(req.body.toString());
if (event.type === "charge.succeeded") {
fulfillOrder(event.data.reference);
}
res.sendStatus(200);
});06Confirm a charge (fallback polling)
If your infrastructure can't receive webhooks yet, poll the charge until the status settles.
curl https://api.opei.business/v1/charges/ch_01HXYZ... \
-H "Authorization: Bearer $OPEI_SECRET_KEY"Statuses move through pending → processing → succeeded or failed. Once succeeded, funds are already in your Opei balance — no separate settlement window.
07Real-time settlement
Every successful Mobile Money charge credits your Opei balance the same second the operator confirms the debit. From there you can:
- Pay suppliers directly from your balance.
- Issue Opei Virtual Cards funded from the balance.
- Sweep to a linked bank account on your own schedule.
08Operator coverage
| Country | Operator code | Currency |
|---|---|---|
| Kenya | mpesa | KES |
| Zimbabwe | ecocash | ZWG / USD |
| Ghana | mtn_momo, airtel_tigo, vodafone | GHS |
| Uganda | mtn_momo, airtel_money | UGX |
| Tanzania | mpesa, airtel_money, tigo_pesa | TZS |
| Rwanda | mtn_momo, airtel_money | RWF |
| Côte d'Ivoire | orange_money, mtn_momo, moov | XOF |
09Testing without touching a real SIM
In test mode, use the reserved phone numbers below to simulate outcomes deterministically:
+254700000001— succeeds instantly.+254700000002— customer cancels the prompt.+254700000003— insufficient balance.+254700000004— times out (no PIN entered).
10Production checklist
- Rotate keys and store the secret key in a server-side vault.
- Always send an
Idempotency-Keyper order. - Verify webhook signatures — reject on mismatch.
- Handle
failedandexpiredcharges in your UI. - Log the
charge_idalongside your internal order ID.
Start accepting Mobile Money today
Create your Opei account, grab a test key, and charge your first wallet in under 10 minutes.
