Remboursements

Rendre tout ou partie d'un encaissement, et suivre ce qui a déjà été rendu.

Créer un remboursement

POST/v1/refunds

Vise une transaction succeeded. Omettez amount pour rembourser la totalité du reste dû.

Orange Money : pas de remboursement par API. Orange Money CI n'expose pas d'API de remboursement. Une demande sur une transaction orange est refusée en 422 avec NGP002 (« Orange Money ne supporte pas les remboursements automatiques ») : le remboursement est enregistré en failed et le montant réservé est rendu, refunded_amount_xof ne bouge pas. Pour rembourser un client Orange Money, faites la demande au support NguePay, qui la traite manuellement. Seuls les paiements par carte (stripe) se remboursent par API pour l'instant.
ChampTypeRequisDescription
transaction_uuiduuid✅La transaction à rembourser.
amountentier❌XOF entiers. Omis = remboursement total.
reasonchaîne (≤ 255)❌Votre motif, enregistré et renvoyé tel quel dans le reason de la réponse (espaces de début et de fin retirés). Omis ou vide : NguePay pose requested_by_merchant.

Ajoutez l'en-tête Idempotency-Key si votre client HTTP peut rejouer l'appel : la même clé sur la même transaction rend le remboursement déjà enregistré au lieu d'en créer un second, et l'opérateur n'est sollicité qu'une fois par clé. La même clé avec un autre montant est refusée en 422 : ce n'est pas un rejeu. Voir Idempotence & rejeu.

curl -X POST https://api.live.nguepay.com/api/v1/refunds \
  -H "Authorization: Bearer sk_live_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_uuid": "9f1c0c2e-2b4a-4f0d-9a1b-6d2f7c3e4a55",
    "amount": 5000,
    "reason": "Article indisponible"
  }'
{
  "success": true,
  "data": {
    "uuid": "b17e3a44-9c21-4f77-8a0e-1d5c2b9f3e10",
    "status": "succeeded",
    "amount_xof": 5000,
    "reason": "Article indisponible",
    "failure_reason": null,
    "processed_at": "2026-09-17T22:14:03.000000Z",
    "created_at": "2026-09-17T22:14:01.000000Z",
    "transaction": {
      "uuid": "9f1c0c2e-2b4a-4f0d-9a1b-6d2f7c3e4a55",
      "reference": "cmd_10452",
      "provider_code": "stripe"
    }
  },
  "message": "Remboursement effectué."
}
ChampTypeDescription
uuiduuidIdentifiant du remboursement — le refund_id du webhook refund.succeeded.
statuschaîneVoir Statuts.
amount_xofentierMontant remboursé en XOF entiers. Pas de champ amount en centimes sur cet objet.
reasonchaîne | nullLe motif que vous avez envoyé, tel quel ; sans motif, requested_by_merchant ; pour un remboursement fait depuis la console Stripe, stripe_charge_refunded.
failure_reasonchaîne | nullMotif du refus, en failed.
processed_atdate | nullExécution par l'opérateur ; null tant qu'elle n'est pas confirmée.
created_atdateCréation.
transactionobjet{ uuid, reference, provider_code } de la transaction remboursée.

Réponse 201. Le message vaut Remboursement effectué., ou Remboursement en cours de traitement. quand l'opérateur confirme plus tard (status: processing). GET /refunds (liste data.refunds) et GET /refunds/{uuid} renvoient le même objet.

Ce qui change sur la transaction

La transaction reste en succeeded : il n'existe pas de statut « remboursé ». Ce qui bouge, c'est refunded_amount_xof, le cumul déjà rendu. Pour savoir si une commande est intégralement remboursée, comparez ce cumul à amount_xof.

Ce choix évite une ambiguïté coûteuse : un remboursement partiel ne doit pas faire disparaître le fait que l'argent a été encaissé, ni fausser votre chiffre d'affaires.

Raccourci par transaction

curl -X POST https://api.live.nguepay.com/api/v1/transactions/{uuid}/refund \
  -H "Authorization: Bearer sk_live_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"amount": 5000, "reason": "Geste commercial"}'
Ce raccourci ne renvoie pas le remboursement mais la transaction mise à jour (objet Transaction, 200), avec son nouveau refunded_amount_xof. Pour obtenir l'uuid du remboursement dès la réponse, utilisez POST /refunds.

Statuts

StatutSignification
pendingTransmis à l'opérateur, en cours.
processingAccepté par l'opérateur, exécution pas encore confirmée. Le montant reste réservé.
succeededL'argent est reparti chez le client.
failedRefusé ; failure_reason précise pourquoi.

L'événement refund.succeeded est envoyé à toutes vos destinations webhook abonnées. Comme pour un paiement, c'est lui qui fait foi.

Limites

Besoin d'aide ?