Treat your API key like a password. Never put it in mobile apps, browser JS, or public repos. Call the API from your backend only.
01 Getting started
- Create a merchant account
- Complete KYC and pay the onboarding fee
- Open Dashboard → API and copy your Live API Key
- (Recommended) Set a Webhook URL for payment results
02 Authentication
Every request must include:
Authorization: Bearer tp_live_XXXXXXXX Content-Type: application/json
- Use the Live key only on your backend
- If leaked → Dashboard → Regenerate keys immediately
- Optional: IP allowlist in Dashboard → API
03 Idempotency
For POST /payments, send a unique Idempotency-Key per attempt.
Retries with the same key return the same response (no duplicate charge).
Idempotency-Key: order-1042-attempt-1
New payment → new key. Same key + different body is rejected. Keys expire after 24 hours.
04 Create payment
Sends a Push USSD prompt to the customer. Status starts as pending until they enter PIN.
POST https://tigopay.online/api/v1/payments
Request body
{
"amount": 5000,
"phone": "0758668707"
}
Required: amount + phone. Auth: Authorization: Bearer YOUR_API_KEY. Mobile network (M-PESA / Airtel / Tigo / Halo) is detected automatically from the phone number — do not send it.
| Field | Type | Description |
|---|---|---|
amount | number | Required. Amount in TZS (> 0) |
phone | string | Required. Customer MSISDN (07… or +255…) |
reference | string | Optional. Your order id (auto-generated if omitted) |
Success response 201
{
"id": "TXN-…",
"reference": "REF-…",
"status": "pending",
"amount": 5000,
"fee": 75,
"net": 4925,
"phone": "255758668707",
"network": "mpesa",
"message": "USSD push sent. Customer should enter PIN on their phone.",
"created_at": "2026-07-23 18:00:00"
}
pending · success · failed — poll GET /transactions/{id} or receive a webhook when status changes.
Do not trust client-side status. Verify with GET /transactions/{id} and/or a signed webhook (payment.success / payment.failed).
05 Check status
GET https://tigopay.online/api/v1/transactions/{id}
Only transactions belonging to your merchant are returned.
{
"id": "TXN-…",
"reference": "REF-…",
"status": "success",
"amount": 5000,
"fee": 75,
"net": 4925,
"phone": "255758668707",
"network": "mpesa",
"message": "Payment completed successfully.",
"created_at": "2026-07-23 18:00:00"
}
06 Webhooks
After payment completes, TigoPay can POST to your HTTPS URL. Configure under Dashboard → API → Merchant webhooks.
Headers
X-TigoPay-Event: payment.success X-TigoPay-Timestamp: 1710000000 X-TigoPay-Signature: t=1710000000,v1=<hmac_sha256>
Verify signature (required)
signed_payload = timestamp + "." + raw_body expected = HMAC_SHA256(signed_payload, webhook_secret) constant-time compare with v1 from Signature
- Reject invalid or missing signatures
- Reject stale timestamps (replay protection)
- Hash the raw body, not re-encoded JSON
- Keep
webhook_secreton your server only
Example payload
{
"id": "evt_…",
"type": "payment.success",
"created_at": "2026-07-23T00:00:00+03:00",
"data": {
"id": "TXN-…",
"reference": "REF-…",
"status": "success",
"amount": 5000,
"fee": 75,
"net": 4925,
"phone": "255758668707",
"network": "mpesa",
"message": "Payment completed successfully."
}
}
Events: payment.success, payment.failed. HTTPS required.
07 Security rules
- Call the API from your backend only
- Confirm every success via status API or signed webhook before fulfilling
- Never fake
successon the client - Never share API keys or webhook secrets
- Use unique
referencevalues - Abuse or payment-bypass attempts may suspend the account
08 Errors
| HTTP | error | Meaning |
|---|---|---|
| 400 | invalid_request | Missing or invalid fields |
| 401 | unauthorized | Invalid API key |
| 403 | ip_forbidden | IP not on allowlist |
| 404 | not_found | Transaction not found |
| 409 | duplicate_reference | Reference already used |
| 409 | idempotency_conflict | Key still processing |
| 422 | idempotency_mismatch | Same key, different body |
| 429 | rate_limited | Too many requests |
| 502 | payment_failed | USSD push could not be sent |
09 Examples
Create payment
curl -X POST "https://tigopay.online/api/v1/payments" \
-H "Authorization: Bearer tp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"phone": "0758668707"
}'
Check status
curl "https://tigopay.online/api/v1/transactions/TXN-XXXX" \ -H "Authorization: Bearer tp_live_YOUR_KEY"