Référence API v1
Documentation complète des endpoints REST.
POST /api/v1/payments/cashin
Initie un paiement entrant client → marchand via Orange Money.
Body JSON
| Champ | Type | Requis | Description |
|---|---|---|---|
merchant_order_id | string | oui | Identifiant unique de la commande (idempotency key). |
amount | integer | oui | Montant en plus petite unité de la devise. |
currency | string(3) | non | Code ISO 4217 (XOF, XAF). Déduit du pays si omis. |
customer_msisdn | string | oui | Numéro client format E.164 (+22376123456). |
country_code | string(2) | non | Code ISO pays. Détecté automatiquement sinon. |
motif | string | non | Motif affiché au client dans le push USSD (255 car. max). |
return_url | string | non | URL de redirection après paiement. |
notify_url | string | non | URL de webhook (override du webhook configuré). |
metadata | object | non | Données libres (jusqu'à 10 clés). |
Paiement en deux étapes.
L'encaissement déclenche un push USSD sur le téléphone du client, qui
confirme avec son code secret. La réponse
202 n'est qu'un accusé de
réception : le statut reste PENDING jusqu'à cette confirmation, notifiée
ensuite par webhook.
Exemple de requête
JSON{
"merchant_order_id": "order_2026_0001",
"amount": 50000,
"currency": "XOF",
"customer_msisdn": "+22376123456",
"country_code": "ML",
"motif": "Commande #2026-0001",
"return_url": "https://shop.example.com/checkout/success",
"notify_url": "https://api.example.com/webhooks/nekapay",
"metadata": {"customer_id": "12345", "cart_id": "abc-def"}
}
Réponse 202 Accepted
JSON{
"data": {
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_order_id": "order_2026_0001",
"type": "CASHIN",
"status": "PENDING",
"amount": 50000,
"currency": "XOF",
"country_code": "ML",
"msisdn": "+223*****56",
"payment_method": "USSD_PUSH",
"payment_url": "https://nekapaie.com/payment/pending/CLI-260429-A4B7C2",
"provider_reference": "NP2604291430A4B7C2",
"provider_tx_id": null,
"provider_session_id": null,
"provider_state": "PENDING",
"provider_txn_status": null,
"created_at": "2026-04-29T14:30:00Z",
"updated_at": "2026-04-29T14:30:01Z"
}
}
| Champ de réponse | Signification |
|---|---|
payment_url | Page Neka Paie de suivi de la confirmation USSD. Redirigez-y votre client, ou affichez votre propre écran d'attente. |
provider_reference | Référence partenaire envoyée à Orange Money — clé de rapprochement en cas de litige. |
provider_tx_id | Identifiant de transaction Orange. null tant que le client n'a pas confirmé. |
provider_state | État brut Orange : PENDING, OK, canceled, KO. |
provider_txn_status | Code Orange détaillé en cas d'échec (solde, code secret, seuils). Table des codes → |
POST /api/v1/payments/cashout
Reverse des fonds depuis le solde marchand vers un wallet client.
Décaissement temporairement indisponible.
Le contrat d'interface Orange Money actuellement en vigueur (AskPayment V2) ne couvre
que l'encaissement : aucun webservice de décaissement n'est exposé par Orange Finances
Mobiles Mali. L'endpoint répond
501 tant que ce webservice n'a pas été
fourni et configuré — aucun solde n'est débité.
Body JSON
| Champ | Type | Requis | Description |
|---|---|---|---|
merchant_order_id | string | oui | Idempotency key. |
amount | integer | oui | Montant en plus petite unité. |
beneficiary_msisdn | string | oui | Numéro du bénéficiaire E.164. |
currency | string | non | Auto-déduit. |
reason | string | non | Motif (remboursement, payout, gain...). |
notify_url | string | non | URL webhook. |
JSON{
"merchant_order_id": "payout_2026_001",
"amount": 100000,
"beneficiary_msisdn": "+22377777777",
"currency": "XOF",
"reason": "Gain de jeu - tirage du 28/04"
}
Validation à deux yeux : les montants ≥
cashout_approval_threshold (défaut 1 000 000 XOF) déclenchent un workflow d'approbation côté back-office.
GET /api/v1/payments/{id}
Consulte le statut courant d'une transaction.
Paramètre URL
{id} : UUID de la transaction.
Réponse 200 OK
JSON{
"data": {
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_order_id": "order_2026_0001",
"type": "CASHIN",
"status": "SUCCESS",
"amount": 50000,
"currency": "XOF",
"country_code": "ML",
"payment_method": "USSD_PUSH",
"provider_reference": "NP2604291430A4B7C2",
"provider_tx_id": "MP260429.1432.C01280",
"provider_session_id": "30949960121638848938577",
"provider_state": "OK",
"provider_txn_status": "200",
"completed_at": "2026-04-29T14:32:18Z"
}
}
Statuts possibles
CREATED | Enregistrée mais pas encore envoyée à Orange. |
INITIATED | Envoyée à Orange, en attente de l'accusé de réception. |
PENDING | Push USSD délivré — en attente de la confirmation du client sur son téléphone. |
SUCCESS | Confirmée par le client et validée par Orange (état terminal). |
FAILED | Échec définitif — client n'ayant pas validé, solde insuffisant, code secret erroné, seuil atteint (état terminal). |
EXPIRED | Délai de confirmation dépassé. |
REVERSED | Remboursement effectué. |
Correspondance avec le contrat Orange.
provider_state et provider_txn_status reprennent tels quels les
champs state et txn_status renvoyés par Orange Money :
OK + 200 → SUCCESS ;
PENDING → PENDING ;
canceled + null → le client n'a pas validé ;
canceled + 54321 → échec dont la cause précise
(60019 solde insuffisant, 00017 code secret incorrect,
100004→100090 seuils) est reportée dans
failure_reason.
POST /api/v1/refunds
Déclenche un remboursement total ou partiel d'un Cash-In réussi.
JSON{
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": 50000,
"reason": "Annulation commande"
}
Si amount est omis, le montant total de la transaction est remboursé.
GET /api/v1/balances
Renvoie le solde du compte marchand par filiale.
JSON{
"data": [
{
"country_code": "ML",
"country_name": "Mali",
"currency": "XOF",
"available_balance": 8750000,
"pending_balance": 125000,
"updated_at": "2026-04-29T14:25:00Z"
}
]
}
D'autres filiales apparaîtront ici dès leur activation par l'équipe Neka Paie.
GET /api/v1/transactions/export
Export des transactions pour réconciliation.
Paramètres query
date_from | Date début (ISO 8601). Requis. |
date_to | Date fin. Requis. |
country_code | Filtrer par pays. |
format | json (défaut) ou csv. |
BASHGET /api/v1/transactions/export?date_from=2026-04-01&date_to=2026-04-30&format=csv