Developers
Three calls, every rail, one reference.
SmatPay exposes one public gateway. Start a payment, keep the reference it returns, and track that reference until it reaches a terminal state. The same paths serve hosted checkout, stored cards and POS terminals, and every one of them has a sandbox twin.
How a payment moves
A client calls the public gateway. The transaction service resolves your merchant account, payment profile and fee rule, asks the provider for the payment, and persists a reference with its current outcome. Mobile-money payments usually start as Pending. Provider callbacks and background workers reconcile the final outcome, then send receipts, fiscalise the sale and call your endpoint.
- 1
Initiate
POST a payment. You get a reference and a status straight back.
- 2
Track
Poll the reference, or wait for the callback. Pending is not Paid.
- 3
Complete
Confirm the sale when the persisted status is Paid. Receipt and fiscal invoice follow.
Payment methods
| Identifier | Type | What the customer does |
|---|---|---|
| ECOCASH | Mobile money | Customer's mobile number; they approve on their phone. |
| OMARI | Mobile money | Customer's mobile number; they approve on their phone. |
| INNBUCKS | Mobile money | Returns a payment code and QR; show the code as a string so leading zeroes survive. |
| ZIMSWITCH | Card | Card entered in the acquirer's widget on the hosted page. |
| VISA | Card | Returns a POS reference, a QR and a six-digit pay code valid for 15 minutes. |
| MASTERCARD | Card | Same as Visa. |
Hosted checkout and payment links
The fastest integration is none at all. Create a payment link in the merchant portal or through the account API, send the customer to it, and receive a callback when it is paid. For a website or app, create a payment against your profile and redirect the customer to the hosted page at payments.smatpay.africa. Card numbers are typed there, never on your site.
Authorization: Bearer <merchant-token>
{
"profileId": 42,
"amount": 120.00,
"currency": "USD",
"description": "Invoice 2041",
"expiresAt": "2026-11-14"
}{
"token": "inv-2041",
"url": "https://payments.smatpay.africa/l/inv-2041",
"status": "Active"
}POS terminals
Terminals are authenticated by the device, not by a login. SmatPay registers each terminal, attaches a SIM and allocates it to your merchant account and payment profile. The device then sends its deviceId with each request, and the gateway resolves the merchant from it. Never let an operator type a merchant ID or provider credential.
{
"deviceId": "123",
"paymentMethod": "INNBUCKS",
"amount": 15.00,
"currency": "USD",
"agentId": "tariro.moyo"
}{
"reference": "POS-3d1f…",
"status": "Pending",
"paymentCode": "0482913",
"paymentQrCode": "…",
"message": "POS payment queued"
}- Track by reference
- POST /init/trackPaymentTransaction with the reference. It reads the persisted record; complete the sale only on Paid.
- Inventory POS
- Carts, sales, cash shifts and receipts under /inventory/pos, authenticated with X-Device-ID and X-Branch-ID headers and an Idempotency-Key.
- Reports
- GET /init/deviceDailyReport?deviceId=…&date=YYYY-MM-DD returns the day's transactions for one terminal.
- Refunds
- Supervisor-approved refunds from the device, with credit notes to ZIMRA where a fiscal invoice was issued.
Stored cards
Register a card once and charge the token later, for subscriptions or one-tap repeat purchases. Token charges use your merchant token and can carry an optional device and customer number so the transaction is attributed in your reports.
Authorization: Bearer <merchant-token>
{
"profileId": 42,
"customerNumber": "CUST-123",
"returnUrl": "https://example.co.zw/cards"
}Authorization: Bearer <merchant-token>
{
"token": "tok_…",
"amount": 15.00,
"currency": "USD",
"deviceId": "123",
"customerNumber": "CUST-123"
}Airtime, electricity and water
Terminals and the merchant portal can sell value-added services against a prefunded wallet. Each product has a lookup where one is needed, a purchase, and a status check for the slow ones.
| Purpose | Path |
|---|---|
| Buy airtime or a bundle | POST /init/pos/purchase-airtime |
| Look up a water meter | POST /init/pos/water-customer-info |
| Buy a water token | POST /init/pos/purchase-water |
| Buy a ZESA token | POST /init/pos/purchase-electricity |
| Check a pending ZESA purchase | POST /init/pos/electricity-status |
| Top up the wallet | POST /init/pos/wallet-top-up |
| Wallet dashboard | GET /init/pos/wallet-transactions-dashboard?deviceId=… |
Callbacks
Set a callback URL on each payment profile. When a payment reaches Paid, Failed or Refunded, the gateway posts the reference and status to it. Pending payments are rechecked by the background worker until they resolve, and the callback is sent once they do. Use the reference, never the queue item, as the record of truth, and reply with a 2xx so we stop retrying.
{
"reference": "POS-8f3a2c1e-…",
"status": "Paid",
"paymentMethod": "Ecocash",
"amount": 48.00,
"currency": "USD",
"deviceId": "123",
"customerNumber": "CUST-123"
}Sandbox
Every production path has a sandbox twin with /sandbox in front: /sandbox/init/pos-payment, /sandbox/api/tokenizePayment, and so on. Sandbox profiles, devices and credentials are separate from production, and the sandbox exposes extra controls for forcing a provider outcome, listing a device's history and refunding a POS payment.

