Quickstart
Patronise Dev lets your website or app take Mobile Money payments (MTN, Orange, Moov, Airtel, Wave, M-Pesa…) in Central and West Africa through one REST API. This page takes you from zero to a working test payment in about five minutes.
Working with an AI agent? Give it
llms-full.txt: the whole documentation in one file. See Integrate with an AI agent.
1. Create an account and a test key
- Sign up with your email. No password, no paperwork.
- Open Dashboard → API keys and create a secret test key. It starts with
sk_test_. - Keep it on your server, in an environment variable such as
PATRONISE_SECRET_KEY. Never put a secret key in a browser or a mobile app.
Test keys never move real money. Live keys (sk_live_) arrive once your account is verified.
2. Create a payment
curl https://api.patronise.me/v1/payments \
-H "Authorization: Bearer $PATRONISE_SECRET_KEY" \
-H "Idempotency-Key: order-1042" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "XAF",
"operator": "mtn_cm",
"phone": "670000000",
"reference": "order-1042"
}'
amountis an integer in the currency's smallest unit. FCFA has no decimals, so5000is 5 000 FCFA. FCFA amounts must be multiples of 5.operatoris one of the operator codes. For Cameroonian numbers you can leave it out: we detect MTN or Orange from the prefix.Idempotency-Keymakes the call safe to retry: the same key never creates two payments.
The answer comes at once, with status: "pending":
{
"id": "pay_3hX9kQ2mVb8sLr4tN7wYc1Ze",
"object": "payment",
"status": "pending",
"amount": 5000,
"charge": 5000,
"fee": 138,
"net": 4862,
"currency": "XAF",
"operator": "mtn_cm",
"next_action": { "type": "ussd_prompt", "ussd": "*126#" },
"reference": "order-1042"
}
next_action tells you what the customer does next:
next_action.type |
What happens | What you show |
|---|---|---|
ussd_prompt |
A prompt pops up on the customer's phone; they type their PIN. | "Confirm the payment on your phone." |
redirect |
The operator needs its own page (Wave, Orange Côte d'Ivoire, cards…). | Send the customer to next_action.url. |
3. Get the result
A payment ends as succeeded or failed, usually within a minute. Learn about it in one of two ways:
- Webhook (recommended). Add an endpoint in Dashboard → Webhooks. We
POSTa signedpayment.succeededorpayment.failedevent to it. See Webhooks. - Polling.
GET /v1/payments/{id}every few seconds until the status is no longerpending.
Only deliver the order when you see
succeededfrom a verified webhook or fromGET /v1/payments/{id}. Never trust a redirect or a query string alone.
In test mode, the number 670000000 succeeds about five seconds later. Other test numbers fail or time out on purpose.
4. No code? Use a hosted page or a link
- Hosted checkout:
POST /v1/checkout-sessionsreturns aurl. Send your customer there; they pick their operator and pay. See Hosted checkout. - Payment links: create one in the dashboard and share it on WhatsApp. See Payment links.