Remboursement (Refund)
L’endpoint POST /v1/payin/{reference}/refund permet de rembourser partiellement ou totalement un paiement client (Payin) précédemment validé.
Cette opération crédite le compte du client ou annule la transaction selon le mode de règlement initial.
Endpoint
| Élément | Description |
|---|---|
| Méthode | POST |
| Url | /v1/payin/{reference}/refund |
| Auth | ✅ Authorization: Basic base64(api_key:api_client) |
| Idempotence | ✅ X-Idempotency-Key obligatoire |
| Payload Type | application/json |
| Timeout recommandé | 30 secondes |
Objectif
- Effectuer un remboursement total d’un paiement validé.
- Effectuer un remboursement partiel si le montant remboursé est inférieur au paiement original.
- Rétablir la cohérence entre les transactions client et les soldes marchands.
- Automatiser la gestion des litiges et annulations.
Exemple de Requête
POST /v1/payin/tr_fhchi842jyimwiugjgszcxvb8n/refundHeaders
| Key | Description | Obligatoire |
|---|---|---|
Authorization | Basic base64(api_key:api_client) | ✅ |
X-Idempotency-Key | UUID garantissant l’unicité de la requête | ✅ |
Request Body
{
"amount": 150,
"reason": "Client cancellation",
"externalReference": "refund_9843b-9911c-qa87"
}Exemple de Réponse
{
"type": "refund",
"reference": "rf_fhchi842jyimwiugjgszcxvb8n",
"originalReference": "tr_fhchi842jyimwiugjgszcxvb8n",
"amount": 150,
"fee": 0,
"currency": "XOF",
"status": "processing",
"reason": "Client cancellation",
"refundType": "partial",
"customerMsisdn": "+2250702968786",
"customerName": "John",
"createdAt": "2025-08-23T12:34:48.189Z",
"transaction": {
"reference": "tr_rf84dhf9pqiuhd38",
"status": "pending",
"processedAt": null
}
}Interprétation des Champs
| Champ | Description |
|---|---|
| type | Type d’opération (refund). |
| reference | Identifiant unique du remboursement. |
| originalReference | Référence du paiement d’origine à rembourser. |
| amount | Montant à rembourser. |
| fee | Frais associés (si applicables). |
| currency | Devise du remboursement (XOF, USD, etc.). |
| status | Statut du remboursement (pending, processing, completed, failed). |
| reason | Motif du remboursement transmis par le marchand. |
| refundType | Type de remboursement (full ou partial). |
| customerMsisdn | Numéro de téléphone du client remboursé. |
| customerName | Nom du client. |
| createdAt | Horodatage de création de la demande de remboursement. |
| transaction | Détails de la transaction de remboursement côté Core System. |
Les Statuts de Remboursement
| Statut | Description |
|---|---|
| pending | Demande reçue, en attente de traitement. |
| processing | Remboursement en cours d’exécution. |
| completed | Remboursement validé et crédité au client. |
| failed | Remboursement refusé ou rejeté (fonds insuffisants, délai dépassé, etc.). |
| reversed | Montant reversé au marchand après un échec ou une annulation manuelle. |
Différence entre Remboursement Total et Partiel
| Type | Description | Condition |
|---|---|---|
Total (full) | Remboursement intégral du montant initial. | amount = montant du paiement original |
Partiel (partial) | Remboursement d’une partie du montant initial. | amount < montant du paiement original |
💡 Un paiement peut être remboursé plusieurs fois partiellement, tant que le total des montants remboursés ≤ montant initial.
Vérification du Remboursement
Une fois le remboursement initié, son statut peut être suivi via :
GET /v1/payin/{reference}ou via les webhooks :
| Événement | Description |
|---|---|
refund.processing | Remboursement en cours. |
refund.completed | Remboursement exécuté avec succès. |
refund.failed | Remboursement refusé. |
Cycle de Vie d’un Refund
Contraintes et Bonnes Pratiques
| Règle | Description |
|---|---|
| Remboursement unique par référence | Chaque remboursement génère une nouvelle référence (rf_...). |
| Montant maximal | Ne peut pas dépasser le montant original de la transaction. |
| Fenêtre temporelle | Un remboursement ne peut être demandé que pendant la période autorisée (ex. 7 jours après le paiement). |
| Fonds disponibles | Le marchand doit disposer d’un solde suffisant pour couvrir le remboursement. |
| Sécurité | Vérification par signature HMAC et journalisation des remboursements |
Erreurs Possibles
| Code | Message | Cause probable | Action recommandée |
|---|---|---|---|
| 400 | Invalid amount | Montant supérieur au paiement original | Vérifier le montant |
| 401 | Unauthorized | Authentification invalide | Vérifier la clé API |
| 403 | Refund not allowed | Transaction non remboursable | Vérifier les conditions de remboursement |
| 404 | Payment not found | Référence introuvable | Vérifier la référence d’origine |
| 409 | Duplicate refund | Tentative de remboursement déjà effectuée | Utiliser une clé d’idempotence différente |
| 500 | Internal Server Error | Erreur du serveur | Réessayer plus tard |
Exemple d’Utilisation Courante
| Cas | Exemple | Description |
|---|---|---|
| Annulation client | reason: "Client cancellation" | L’utilisateur annule sa commande après paiement. |
| Remboursement partiel | amount: 500 | Le marchand rembourse partiellement un achat. |
| Erreur de facturation | reason: "Duplicate charge" | Paiement doublon à rembourser. |
Typologie des Transactions
| Type | Confirmation Client | Interaction Mobile Money | Notification |
|---|---|---|---|
| Paiement déclenché | ✅ Oui | ❌ Non | ✅ Oui |
| Transfert interne (P2P) | ❌ Non | ❌ Non | ✅ OuI |