Initiate a payment
Payment Collection
Initiate Payment Collection
Charge a mobile-money account to credit your company’s pay-in wallet. Supports MTN, Orange, Moov, Wave, M-Pesa, and other African operators.
POST
Initiate a payment
Overview
POST /payment/collect initiates a pay-in: it charges a mobile-money account and credits the proceeds to your company’s pay-in wallet for the matching country/currency. The call returns immediately with status: PENDING; the final outcome (SUCCESS or FAILED) reaches you asynchronously via webhook (or via notify_url if you supply one).
For some operators, the end user must approve the charge with an OTP or USSD step — see the country/operator matrix in Payment guidelines.
When to use it
- You need to charge an end user’s mobile-money account to settle a bill, top up a balance, or fund a service.
POST /payment/payout.
Prerequisites
- Your company has a wallet for the requested
(country, currency)pair. If not, create it first viaPOST /wallets. - The combination of
country,currency, andoperatoris supported — see Payment guidelines.
Request
Headers
Body
Orange Money workflow (Burkina Faso & Senegal)
Orange Money in Burkina Faso and Senegal requires an OTP. The operator does not push a confirmation prompt to the payer — instead the payer must generate the one-time code themselves and give it to you, then you submit it with the collection:- The payer dials the Orange USSD code on their phone to generate the payment OTP:
- Burkina Faso (
country: "BF"):*144*4*6*<amount>#— where<amount>is the collection amount. - Senegal (
country: "SN"):#144*391#
- Burkina Faso (
- The payer gives you the generated OTP.
- You call
POST /payment/collectwithoperator: "orange", the matchingcountry,currency: "XOF", and the OTP inotp_code.
Other operators also require an OTP (e.g. Wallet LigdiCash in Burkina
Faso). Whenever the operator requires one, send it in
otp_code. See the
Payment guidelines for the full
country/operator OTP matrix.Idempotency
Always supply your ownexternal_id. Cartevo rejects duplicates with 400 (after the first call), so storing the value before you send the request and reusing it on retry is safe. If you let Cartevo auto-generate one, you lose this protection.
Response
200 — Collection initiated
Wave workflow (payment link)
Wave (Côte d’Ivoire, Senegal, …) requires a payment link. Wave does not push a USSD/OTP prompt; instead AfribaPay returns aprovider_link in the
response and the payer must open it to confirm:
- Call
POST /payment/collectwithoperator: "wave". - The response contains a non-null
provider_link(e.g.https://pay.wave.com/c/cos-...). - Redirect the payer to that URL (or open it). They confirm the payment on Wave’s page.
- The transaction stays
PENDINGuntil they confirm; the finalSUCCESS/FAILEDarrives via webhook.
Lifecycle
PENDING— Cartevo accepted the request; the operator has been notified.PROCESSING— The operator is awaiting user action (OTP / USSD) or processing internally.SUCCESS— Funds have been credited to your pay-in wallet. Thepayment.collectwebhook fires.FAILED— End user rejected, insufficient funds at the operator, OTP timeout, etc. Seeerror_messagein the status endpoint.
PROCESSING can last up to 15 minutes for OTP-required operators. Beyond that, treat as failed and reconcile via the status endpoint.
Error responses
Webhooks fired
payment.collect— fires when the collection is initiated, then again on status changes (SUCCESS/FAILED).- If you supplied
notify_url, it receives a copy of each status change.
Code examples
cURL
Node.js (axios)
Related
GET /payment/transactions/{id}/status— poll for the outcome.POST /payment/payout— send money out via mobile money.- Payment guidelines — supported countries, operators, OTP/USSD requirements.
- Webhooks — full webhook catalogue.
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/json
Available options:
mtn, orange, moov, airtel, mpesa, afrimoney, vodacom, wave, wligdicash, expresso, free, tmoney, celtiis, coris Example:
"mtn"
Pattern:
^[A-Z]{2}$Example:
"CM"
Example:
"237670000000"
Required range:
x >= 1Example:
1000
Example:
"XAF"
Example:
"https://example.com/webhook/payment"
Idempotency key (up to 255 chars). Duplicate values are rejected with 400 after the first call. Auto-generated if omitted.
Free-form reference shown in the dashboard (up to 255 chars).
Two-letter language code for operator-side prompts (e.g. en, fr).
Free-form description of the payment's purpose.