Collect payments
| Method | Best for | Countries |
|---|---|---|
| M-Pesa STK Push | Charging a Kenyan phone directly from your server | KE |
| Mobile money push | Charging mobile money outside Kenya | UG, TZ, RW, CD, GH, NG, SN, CI, BF, CM |
| Checkout | A hosted payment page (cards, M-Pesa, Apple Pay, Google Pay, bank, crypto) | Global |
| Payment links | A no-code shareable link or QR code | Global |
| Payment requests | Emailing a customer an invoice to pay | Global |
| Bank and agent deposits | Standing account numbers, Co-op agent deposits | KE |
See Countries for the methods and currencies available in each country.
The invoice
Every payment attempt creates an invoice. Track it by invoice_id.
state | Meaning |
|---|---|
PENDING | Created; not yet sent to the provider |
PROCESSING | Sent: the customer has a prompt or has been redirected |
RETRY | Being retried. For example, after an M-Pesa timeout the customer receives paybill instructions |
PARTIAL | Part of the amount was paid |
COMPLETE | Paid |
FAILED | Failed. See failed_reason and failed_code |
CANCELED | Cancelled |
Key invoice fields: invoice_id, state, provider, value, charges, net_amount,
currency, account (the phone or email), api_ref (your reference), provider_ref
(for example the M-Pesa receipt), failed_reason, failed_code and clearing_status.
Most completed payments first land as CLEARING in your wallet, and become AVAILABLE once they
settle. clearing_status on the invoice shows which one applies.
Check payment status
curl -X POST https://api.intasend.com/api/v1/payment/status/ \
-H "Authorization: Bearer $INTASEND_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"invoice_id": "ABC123"}'
This endpoint also accepts a publishable key, so your frontend can poll it.
{
"invoice": {
"invoice_id": "ABC123",
"state": "COMPLETE",
"provider": "M-PESA",
"value": 100,
"charges": 3,
"net_amount": 97,
"currency": "KES",
"account": "254712345678",
"api_ref": "order-123",
"provider_ref": "QWE123RTY",
"failed_reason": null,
"failed_code": null
},
"meta": {"customer": {"phone_number": "254712345678", "email": null}}
}
Rather than polling, subscribe to the collection_event webhook, which fires on every state change.
Who pays the fees
Most collection endpoints accept a tariff field (mobile_tarrif, card_tarrif, bank_tarrif, …):
BUSINESS-PAYS: the fee is deducted from what you receive.CUSTOMER-PAYS: the fee is added to the amount the customer pays.
If you omit it, your account default applies.