API - Transaction
La section Transaction regroupe la consultation des mouvements financiers, le calcul des frais et les transferts entre portefeuilles.
Les conventions générales s'appliquent : en-têtes, enveloppe de réponse, pagination et codes d'erreur.
Consulter une transaction​
GET /api/public/v1/details-transaction/{transaction}
L'identifiant accepté est celui de la transaction ou celui du checkout : ils sont identiques. C'est l'endpoint à interroger pour vérifier l'état réel d'un paiement, notamment si vous n'avez pas reçu le webhook attendu.
Champs renvoyés​
| Champ | Type | Description |
|---|---|---|
id | uuid | Identifiant de la transaction, identique Ă celui du checkout. |
ref | string | Référence lisible de la transaction. |
amount | entier | Montant en ariary. |
company | string | Entité rattachée à l'opération. |
comment | string | Libellé métier fourni à la création. |
wallet | objet | Portefeuille concerné. |
customer_fee | entier | Frais Ă la charge du client. |
status | objet | Statut courant, exposé sous forme de slug : pending, success, error ou canceled. |
type | objet | null | Sens du mouvement : money-in ou money-out. null tant que la transaction est en pending. |
created_at | date | null | Date de création. null tant que la transaction est en pending. |
invoice | objet | Facture associée, si elle existe. |
type et created_at sont nuls avant confirmationCes deux champs ne sont renseignés qu'une fois la transaction sortie de l'état pending. Un tri ou un regroupement par created_at sur une liste fraîche doit donc traiter la valeur null, et non la supposer présente.
Frais d'une transaction​
GET /api/public/v1/amount-commission-transaction/{transaction}
Renvoie le total des commissions générées par une transaction donnée.
Tant que la transaction n'est pas réglée, cet endpoint répond 404 : les commissions n'existent pas encore. Ce 404 ne signifie pas que la transaction est inconnue — utilisez details-transaction pour vérifier son existence et son statut.
Lister les transactions​
GET /api/public/v1/get-transactions
Résultat paginé, avec les filtres communs. Champs utiles :
filter[wallet_id]— transactions d'un portefeuille précis ;filter[type.slug]—money-in(encaissements) oumoney-out(sorties) ;filter[status.slug]—pending,success,error,canceled;between[created_at]— intervalle de dates, formatmin,max;between[amount]— intervalle de montants.
Simuler les frais​
POST /api/public/v1/transaction/calc-fee
À appeler avant une opération pour afficher le coût à votre client ou vérifier qu'un solde suffit.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
amount | entier | Oui | Montant brut à évaluer, entre 300 et 20 000 000. |
transaction_type | string | Oui | payment, refund ou cash-out. |
method | string | Conditionnel | Moyen de paiement ou canal de versement. Obligatoire sauf si transaction_type vaut refund. Valeurs acceptées ci-dessous. |
Valeurs acceptées pour method​
| Valeur | Opérateur |
|---|---|
MVOLA | MVola (Telma) |
OrangeMoney | Orange Money |
AirtelMoney | Airtel Money |
MVOLA s'écrit en capitales, OrangeMoney et AirtelMoney en casse chameau. Toute autre graphie — MVola, orangemoney, airtel_money — est refusée en 422 avec le message « Le champ method sélectionné est invalide ».
method n'utilise pas le vocabulaire de cash_outDeux nomenclatures coexistent, et elles ne sont pas interchangeables. La configuration de retrait d'un portefeuille attend un canal (mobile_money ou bank_transfer) dans cash_out.info.first_choice, alors que calc-fee attend un nom d'opérateur. Envoyer mobile_money, bank_transfer ou card à calc-fee est refusé.
curl --request POST \
"https://efn.efaina.com/api/public/v1/transaction/calc-fee" \
--header "Authorization: Bearer VOTRE_TOKEN" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"amount": 150000,
"transaction_type": "cash-out",
"method": "MVOLA"
}'
Transfert entre portefeuilles (P2P)​
POST /api/public/v1/transaction/p2p
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
from_wallet_id | uuid | Oui | Portefeuille source. |
to_wallet_id | uuid | Oui | Portefeuille destinataire. |
amount | entier | Oui | Montant en ariary, entre 300 et 20 000 000. |
comment | string | Oui | Libellé du transfert, 100 caractères maximum. |
company | string | Oui | Nom rattaché aux deux transactions générées. |
custom_id | string | Non | Votre référence interne, pour le rapprochement. |
Un transfert P2P ne peut pas envoyer de fonds vers le portefeuille d'un autre marchand. La demande est refusée si from_wallet_id et to_wallet_id n'ont pas le même propriétaire.
Autres conditions : le portefeuille source doit disposer du solde nécessaire, et le solde du destinataire après transfert ne doit pas dépasser le plafond de 20 000 000 MGA.
Le transfert crée deux transactions : une sortie (money-out) sur la source, une entrée (money-in) sur la destination.
curl --request POST \
"https://efn.efaina.com/api/public/v1/transaction/p2p" \
--header "Authorization: Bearer VOTRE_TOKEN" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"from_wallet_id": "9a6c9375-210b-4c6b-8ac9-41dcdf640213",
"to_wallet_id": "a3bb189e-b1be-49d4-aec2-a9b02d7a5c20",
"amount": 75000,
"comment": "Répartition interne",
"company": "MyCompany SARL",
"custom_id": "P2P-2024-07-001"
}'
Une transaction issue d'un transfert P2P n'est pas remboursable via l'API de remboursement.