Conventions de l'API
Cette page regroupe ce qui s'applique à tous les endpoints : URL de base, en-têtes, format des réponses, codes d'erreur, pagination et règles sur les montants. Les pages suivantes ne le répètent pas.
URL de base
https://efn.efaina.com/api/public/v1
Tous les endpoints publics sont préfixés par /api/public/{version}. La version courante est v1.
En sandbox, l'URL de base est https://sandback.efaina.com/api/public/v1. Une clé API générée en sandbox ne fonctionne pas en production, et inversement.
En-têtes
| En-tête | Obligatoire | Rôle |
|---|---|---|
Authorization: Bearer {jeton} | Oui | Authentifie le compte. Voir Jeton d'accès. |
Accept: application/json | Oui | Sans lui, les erreurs peuvent être renvoyées en HTML. |
Content-Type: application/json | Sur POST/PUT | Sauf en multipart/form-data (création de wallet avec pièces jointes). |
X-App-Id: {app_id} | Non | Désigne l'application appelante : webhook et liste blanche d'IP dédiés. |
Format des réponses
Toutes les réponses de l'API publique utilisent la même enveloppe :
{
"statusHttp": "success",
"message": "",
"response": { }
}
statusHttp:successouerror. C'est le statut applicatif, à ne pas confondre avec le code HTTP.message: message lisible, éventuellement vide en cas de succès.response: la charge utile — objet, tableau ou structure paginée selon l'endpoint.errorCode: présent uniquement en cas d'erreur (la clé est retirée des réponses en succès).
Exemple d'erreur :
{
"statusHttp": "error",
"errorCode": "PAYLOAD_VALIDATION",
"message": "Invalid payload",
"response": {
"amount": ["The amount must be at least 300."]
}
}
Codes d'erreur applicatifs
errorCode | Code HTTP usuel | Signification |
|---|---|---|
PAYLOAD_VALIDATION | 422 | Le corps de la requête est invalide. response contient le détail champ par champ. |
NOT_FOUND_DATA | 404 | La ressource visée n'existe pas. |
UNAUTHORIZED | 403 | La ressource existe mais n'appartient pas à votre compte. |
SERVER_ERROR | 500 | Erreur inattendue de notre côté. L'incident est journalisé chez nous. |
Erreurs sans enveloppe
Les rejets qui interviennent avant le contrôleur — authentification, autorisation, liste blanche d'IP, X-App-Id invalide — sont renvoyés au format Laravel standard, sans enveloppe :
{
"message": "Unauthenticated."
}
Votre client doit donc gérer les deux formes. En pratique : fiez-vous d'abord au code HTTP, puis lisez response/message si l'enveloppe est présente.
| Code HTTP | Quand |
|---|---|
200 | Lecture réussie. |
201 | Création réussie (checkout, retrait, remboursement, wallet). |
202 | Traitement accepté et mis en file (opérations de masse). |
401 | Jeton absent, invalide ou expiré. |
403 | Ressource d'un autre compte, IP non autorisée, ou application désactivée. |
404 | Ressource inexistante. |
422 | Payload invalide. |
500 | Erreur serveur. |
Pagination et filtres
Les endpoints de listing (wallets, get-transactions, refunds, cash-outs) renvoient une structure paginée Laravel dans response :
{
"statusHttp": "success",
"message": "",
"response": {
"current_page": 1,
"data": [],
"per_page": 15,
"last_page": 2,
"total": 20,
"next_page_url": "…",
"prev_page_url": null
}
}
Paramètres communs, en query string :
| Paramètre | Description |
|---|---|
pagination | Nombre de résultats par page. Défaut 15, plafonné à 100. |
page | Numéro de page, à partir de 1. |
search | Recherche globale de type LIKE sur les colonnes principales de la ressource. |
sort | Champs de tri séparés par des virgules, préfixés de - pour l'ordre décroissant. Exemple : sort=-created_at,amount. |
filter[champ] | Filtre exact sur un champ, ou partiel sur un champ de relation. Exemple : filter[status.slug]=pending. |
between[champ] | Filtre d'intervalle min,max. Exemple : between[amount]=1000,500000. |
Les champs acceptés varient selon la ressource ; la référence API générée en donne la liste exhaustive pour chaque endpoint.
Montants
- Les montants sont exprimés en ariary (MGA), en nombres entiers. Les décimales sont refusées.
- Minimum : 300 MGA. Maximum : 20 000 000 MGA.
- Ces bornes s'appliquent aux paiements, transferts P2P, remboursements et retraits.
Statuts
Les ressources financières partagent le même jeu de statuts, exposé sous forme de slug :
| Slug | Signification |
|---|---|
pending | En attente : créée, pas encore confirmée par l'opérateur. |
success | Confirmée et définitive. |
error | Échouée. |
canceled | Annulée. |
Un checkout ou un retrait est créé en pending. La confirmation arrive de l'opérateur mobile ensuite, de façon asynchrone. C'est le webhook — ou une relecture de la transaction — qui fait foi, jamais la réponse à votre appel de création.
Champs de rapprochement
Plusieurs endpoints acceptent un identifiant côté marchand pour rapprocher nos ressources de vos enregistrements internes :
custom_id— sur les transferts P2P et les remboursements.comment/description— libellé métier, 100 caractères maximum.X-App-Id— l'intégration à l'origine de l'appel, si vous utilisez les applications.