Send money
Transfers move money out: you send an amount to the Mobile Money account of a supplier, an employee or a customer to refund. Cartflox hands the transfer to one of your gateways that supports it, with your own keys. Workspaces managed by nyole (money held by Cartflox) do not have access to transfers for now.
/v1/transfersSend money to a Mobile Money accountParameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
amount |
number | Yes | Amount received by the recipient, integer for francs (5000 for 5,000 XOF) |
country |
string | Yes | Recipient’s country, ISO 3166-1 alpha-2: CI, SN, BJ, BF, TG, ML, NE, GN, CM, GA, CG, CD, GH, NG, KE, TZ, UG, RW, ZM |
operator |
string | Yes | Recipient’s operator: orange_money, mtn_money, moov_money, wave, free_money, tmoney, mpesa, airtel_money… Common aliases (mtn, orange, MTN_MOMO_CIV) are accepted. |
phone |
string | Yes | Recipient’s number, as dialed in the country (0712345678) or in international format (+2250712345678) |
currency |
string | No | Currency, inferred from the country (XOF, XAF, GHS, KES…). A currency that does not match the country is rejected. |
recipient_name |
string | No | Recipient’s name, for your statements and for the provider |
description |
string | No | Reason, passed on when the operator shows it to the recipient |
idempotency_key |
string | No | Same role as the Idempotency-Key header below |
metadata |
object | No | Your own data, stored with the transfer |
Headers
Section titled “Headers”| Header | Value |
|---|---|
Authorization |
Bearer af_live_sec_... (or x-api-key). The secret key only: the widget’s public key is rejected, it cannot move money out. |
Content-Type |
application/json |
Idempotency-Key |
Strongly recommended. A unique string per transfer (invoice number, payroll ID…): if the same call is replayed, the existing transfer is returned (HTTP 200, Idempotent-Replayed: true header) instead of sending the money a second time. |
Examples
Section titled “Examples”curl -X POST https://cartflox.com/api/v1/transfers \ -H "Authorization: Bearer af_live_sec_YOUR_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: salary-2026-09-awa" \ -d '{ "amount": 50000, "country": "CI", "operator": "orange_money", "phone": "0712345678", "recipient_name": "Awa Koné", "description": "September salary" }'const res = await fetch("https://cartflox.com/api/v1/transfers", { method: "POST", headers: { Authorization: `Bearer ${process.env.CARTFLOX_SECRET_KEY}`, "Content-Type": "application/json", "Idempotency-Key": "salary-2026-09-awa", }, body: JSON.stringify({ amount: 50000, country: "CI", operator: "orange_money", phone: "0712345678", recipient_name: "Awa Koné", description: "September salary", }),});const transfert = await res.json();console.log(transfert.status); // "processing" most of the time, "succeeded" or "failed"$ch = curl_init("https://cartflox.com/api/v1/transfers");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . getenv("CARTFLOX_SECRET_KEY"), "Content-Type: application/json", "Idempotency-Key: salary-2026-09-awa", ], CURLOPT_POSTFIELDS => json_encode([ "amount" => 50000, "country" => "CI", "operator" => "orange_money", "phone" => "0712345678", "recipient_name" => "Awa Koné", "description" => "September salary", ]),]);$transfert = json_decode(curl_exec($ch), true);echo $transfert["status"];import os, requests
res = requests.post( "https://cartflox.com/api/v1/transfers", headers={ "Authorization": f"Bearer {os.environ['CARTFLOX_SECRET_KEY']}", "Idempotency-Key": "salary-2026-09-awa", }, json={ "amount": 50000, "country": "CI", "operator": "orange_money", "phone": "0712345678", "recipient_name": "Awa Koné", "description": "September salary", },)print(res.json()["status"])Response
Section titled “Response”{ "id": "cmfx1a2b3c4d5e6f7g8h9i0j", "reference": "ddf9f0bf-f310-4126-83d9-dc8bc92b6e79", "status": "processing", "amount": 50000, "currency": "XOF", "fee": 0, "country": "CI", "operator": "orange_money", "provider_operator": "ORANGE_CIV", "phone": "2250712345678", "recipient_name": "Awa Koné", "description": "September salary", "provider": "PawaPay", "provider_reference": null, "failure": null, "idempotency_key": "salary-2026-09-awa", "created": "2026-09-18T09:12:41.000Z", "completed": null}| Status | Meaning |
|---|---|
pending |
Created, not yet handed to the provider |
processing |
Handed to the provider, the operator is processing the transfer. This is the most common case right after the call. |
succeeded |
The money has reached the recipient’s account. completed carries the date. |
failed |
Rejected by the operator or the provider. failure.code and failure.message say why. Nothing has been debited. |
fee is 0: Cartflox takes nothing on a transfer, your aggregator applies its own fees to its wallet.
Track a transfer
Section titled “Track a transfer”The status changes after the call. Two ways to track it, to be used together:
/v1/transfers/{id}One transfer, by Cartflox identifier or by reference/v1/transfers?status=processing&limit=50Your latest transfers, filterable by statusAnd the transfer.succeeded and transfer.failed webhooks, sent to the address configured for your payments, signed the same way, with the full transfer in data. See the events.
Countries and operators of your workspace
Section titled “Countries and operators of your workspace”The available operators depend on the gateways you have connected. To know them without guessing:
/v1/transfers?options=1Countries, currencies and operators open to this workspace{ "countries": [ { "code": "CI", "name": "Côte d'Ivoire", "currency": "XOF", "operators": [ { "code": "orange_money", "name": "Orange Money", "provider": "PawaPay" }, { "code": "mtn_money", "name": "MTN Mobile Money", "provider": "PawaPay" }, { "code": "moov_money", "name": "Moov Money", "provider": "PawaPay" }, { "code": "wave", "name": "Wave", "provider": "PawaPay" } ] } ]}Errors
Section titled “Errors”| HTTP | code |
Meaning |
|---|---|---|
| 401 | unauthorized |
Missing or invalid key, or public key |
| 403 | transferts_inactifs |
Transfers are not open on this workspace |
| 403 | connect_non_disponible |
Workspaces managed by nyole do not have access to transfers |
| 400 | pays_non_desservi |
Country not in the list |
| 400 | operateur_non_desservi |
None of your gateways can send to this operator in this country |
| 400 | methode_desactivee |
You have disabled this operator in your transfer methods |
| 400 | telephone_invalide |
The number is not a possible number for this country |
| 400 | devise_invalide |
The currency does not match the country |
| 400 | montant_invalide |
Zero or negative amount |
| 429 | plafond_journalier |
The workspace’s daily number of transfers has been reached |
| 429 | rate_limited |
More than 30 calls per minute |