> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mercy-pay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Idempotence

> Rejouez une création sans créer de doublon, grâce à l'en-tête Idempotency-Key.

Après un timeout, vous ne savez pas si Mercy Pay a traité votre requête. La renvoyer telle quelle pourrait créer un doublon (deux paiements, deux retraits). Avec un en-tête `Idempotency-Key` unique par opération, une même clé ne crée jamais deux fois.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl https://mercy-pay.com/api/v1/payouts \
  -H "Authorization: Bearer mp_live_XXXXXXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout-2026-10-03-001" \
  -d '{"amount": 4000, "currency": "XAF", "destination": {"type": "mobile_money", "country": "CMR", "provider": "MTN_MOMO_CMR", "phone": "237680000000"}}'
```

## Une clé par opération, jamais par tentative

La clé identifie l'opération (cette commande, ce retrait), pas la requête HTTP. Générez-la **une seule fois**, au moment où vous décidez de créer le retrait (ou la charge, ou la session), par exemple à partir de l'identifiant de commande déjà présent dans votre propre système. Si l'appel échoue ou time-out, vous **renvoyez la requête à l'identique, avec la même clé**, autant de fois que nécessaire : vous ne générez jamais une nouvelle clé pour « réessayer ».

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
1. Votre code décide de créer le retrait pour la commande #4521.
2. Il appelle l'API avec Idempotency-Key: commande-4521.
3. Le réseau coupe avant que vous ne receviez la réponse, succès ou échec : vous ne savez pas.
4. Vous rappelez l'API avec EXACTEMENT la même requête et la même clé commande-4521.
   → Si le premier appel avait réussi : Mercy Pay renvoie la réponse d'origine, rien n'est recréé.
   → Si le premier appel n'était jamais arrivé : Mercy Pay le traite pour de vrai, cette fois.
```

Dans les deux cas, votre code peut traiter la réponse exactement de la même façon : il n'a pas besoin de savoir si c'était le premier essai ou une relance.

> [!WARNING]
>
> Générer une clé différente à chaque tentative (par exemple un `uuid()` appelé au moment de l'envoi plutôt que mémorisé avec la commande) annule complètement la protection : chaque relance est alors vue comme une opération différente, et un double paiement redevient possible.

## Comportement

| Situation | Réponse |
| - | - |
| Première requête | Création, `201` |
| Même clé, même contenu | Réponse d'origine rejouée, `200`, sans nouvelle création |
| Même clé, contenu différent | `409`, `error.code` : `idempotency_key_reused` |
| Même clé, première requête encore en cours | `409`, `error.code` : `idempotency_key_in_use`. Patientez quelques secondes et renvoyez. |
| Clé absente sur une charge directe ou un retrait | `400`, `error.code` : `idempotency_key_missing` |

Les clés sont conservées **24 heures**. Au-delà, la même clé n'est plus reconnue et recrée une ressource.

## Conseils

* Générez une clé par opération logique (une commande, un retrait, une charge directe), pas une par tentative réseau.
* Ne réutilisez jamais une clé pour une autre opération, même après un échec : son rôle est justement d'identifier une seule opération sans ambiguïté.
* `Idempotency-Key` est accepté sur toutes les créations : sessions de checkout, charges directes, retraits, liens de paiement, plans et abonnements. Il est **obligatoire** pour une charge directe (`POST /api/v1/payments`) et pour un retrait (`POST /api/v1/payouts`) : la requête est rejetée sans lui. Pour les autres, il reste recommandé mais optionnel.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.