ZonmPay API v2

Developer Documentation

One API for every payment channel in Tanzania: collections, payouts, statuses, balances, customer verification and signed webhooks.

HomeDocumentation

ZonmPay Payments API

One API gives you access to every payment channel in Tanzania: mobile money from all five MNOs (M-Pesa, Mixx by YAS, Airtel Money, Halotel, TTCL Pesa), bank BillPay, USSD, tills and cards. You describe who is paying rather than how the plumbing works, and ZonmPay routes it. Collections cost 2.5% of the transaction, payouts TZS 2,500 or 2.5% (whichever is higher), and settlement to your own bank account is free.

Prerequisites

  1. API KeyAPI Key — go to Dashboard → Settings → Developer then click Generate API Key.
  2. Webhook URLWebhook URL — register your URL to receive notifications whenever a payment status changes.
  3. Whitelisted IPWhitelisted IP — required only before your own server can approve a payout. Register every egress address; entries are matched exactly, with no CIDR support.

How it works

  • Step 1 — CollectionPOST /api/v2/payment/collection with service + account + amount. You describe who is paying, not how the plumbing works — the channel is routed for you. It returns immediately with status PROCESSING.
  • Step 2 — WebhookWhen the payment reaches a final state we POST payment.confirmed / payment.failed to your URL. Verify the X-SpeedPesa-Signature header before you trust it.
  • Step 3 — ReconcileIf your webhook was unreachable, poll GET /api/v1/payment/reference/{reference} — no more than once every 10 seconds and stop after 5 minutes.

Authentication

Every request is authenticated with your secret key in the apiToken header. There is one base URL and one key: your account behaves as a sandbox until go-live is approved, on the same URL. Keep the key server-side only, and note that rotating it expires the previous one immediately.

Required Headers

apiToken

sp_sk_prod_XXXXXXXXXXXX

Content-Type

application/json

Base URL

All endpoint paths are appended to the base URL.

https://zonmpay.com

API versions

These docs describe v2, the current API. It collects and pays out on every channel through one pair of endpoints, so you write the integration once and enable new rails without changing code. v1 (/api/public/v1/...) still works and existing integrations are unaffected — build new integrations on v2 and migrate when convenient.

All APIs

Click any group to open full details, request body and code samples.

Test the Connection

GET

Test your API Key

Confirm your key works before you send real money. GET /api/v2/payment/channels is harmless and needs no body, so it is the standard smoke test: a 200 means the key is valid, a 403 means it is missing, wrong or suspended.

GET https://zonmpay.com/api/v2/payment/channels

Use zonmpay.com specifically (without www the request is redirected and some HTTP clients drop the POST body — which causes a server error).

bash
curl https://zonmpay.com/api/v2/payment/channels \
  -H "apiToken: SPP_live_YOUR_API_KEY"

Note: ZonmPay returns 403 for every authentication failure on these routes, not 401.

Error Codes

Every response carries a code that is more specific than the HTTP status, alongside success, message.

CodeHTTPMeaningFix
1109200Collection acceptedThe customer is being prompted. Wait for the webhook.
1120200Disbursement created, awaiting approvalApprove it with POST /api/v2/payment/approve.
1111200Disbursement or batch acceptedApprove each record by its own reference.
1117200Disbursement approved and dispatchedReconcile against debit.totalDebit.
1112400Disbursement rejectedRead failureReason; no money left your wallet.
400400Bad request: invalid parameters or phone formatUse 255XXXXXXXXX. The minimum collection is TZS 100.
402402Daily or monthly transaction cap reachedCheck GET /api/v1/payment/limits.
403403Invalid or missing apiToken, a suspended account, or an IP that is not whitelisted on the approve endpointConfirm the token with GET /api/v2/payment/channels. If that works and approve still 403s, it is the IP.
404404Not foundCheck you are using the ZonmPay reference, not your own.
409409Conflict: the resource was changed concurrentlyDo not retry blindly. Read the payment; it is probably already approved.
429429Rate limit exceededSlow down. Poll no more than once every 10 seconds.
500500Server errorRetry after a few seconds; contact support with the reference.
502502Accepted and debited, but the channel did not accept the dispatchIt is queued for retry — do not re-submit. Poll the reference.

Support & Resources

Our team helps with integration, troubleshooting and account management.

ChannelContactResponse Time
Emailsupport@zonmpay.com24 hours
Phone / WhatsApp+255 700 000 00008:00 – 20:00 EAT

© 2026 ZonmPay API Documentation. All rights reserved.