Skip to content

Idempotency

Toute requête mutante (POST, PUT, PATCH, DELETE) sur l'API HayBTech doit porter un header Idempotency-Key. Sans ce header, la requête est rejetée avec 400 idempotency_key_required.

Pourquoi

Sans idempotency, un timeout réseau pendant un POST /payments vous oblige à choisir entre :

  • réessayer risque de double-création ;
  • abandonner risque de perdre la transaction si elle a réussi côté HayBTech.

Avec idempotency, vous pouvez retenter sans danger : HayBTech reconnaît la clé et rejoue la même réponse que la première fois, sans recréer la ressource.

Format

Idempotency-Key: <chaîne unique, max 255 caractères>

Recommandé : un UUID v4 généré côté client. Une clé est valide 24h après sa première utilisation.

Sémantique

CasRéponse
Clé jamais vueAction exécutée, réponse cachée
Clé déjà vue + même bodyRéponse cachée rejouée + header Idempotent-Replay: true
Clé déjà vue + body différent409 idempotency_conflict
Clé en cours de traitement (race)409 idempotency_conflict

Le fingerprint est un hash SHA-256 de (method, path, body, query). Si un seul caractère diffère, c'est un conflit.

Quoi cacher / ne pas cacher

StatusCaché ?
2xx, 3xxOui la requête a abouti
4xxOui l'erreur est déterministe (validation), la rejouer la reproduit
5xxNon l'incident est transitoire, on autorise la retry

Conséquence pratique : réessayez avec la même clé après un 5xx ; pour un 4xx, corrigez puis utilisez une nouvelle clé.

Exemple

Premier appel :

bash
curl -X POST https://app.haybtech.com/v1/payments \
  -H "Authorization: Bearer pk_test_xxx" \
  -H "Idempotency-Key: 4f1c2c8a-9d4e-4b8f-9a1c-2c8a9d4e4b8f" \
  -H "Content-Type: application/json" \
  -d '{"merchant_ref":"ORDER-42","amount":5000,"provider":"orange_money"}'
# => 201 + Transaction TXN-A1B2C3D4E5

Réessai (timeout réseau supposé) avec la même clé et le même body :

bash
curl -X POST https://app.haybtech.com/v1/payments \
  -H "Authorization: Bearer pk_test_xxx" \
  -H "Idempotency-Key: 4f1c2c8a-9d4e-4b8f-9a1c-2c8a9d4e4b8f" \
  ...
# => 201 + même Transaction TXN-A1B2C3D4E5
# => header Idempotent-Replay: true
# => DB : 1 seule ligne dans transactions

Avec un body différent :

bash
# Même clé, montant changé
curl -X POST .../v1/payments \
  -H "Idempotency-Key: 4f1c2c8a-9d4e-4b8f-9a1c-2c8a9d4e4b8f" \
  -d '{"merchant_ref":"ORDER-42","amount":9999,...}'
# => 409 idempotency_conflict

Bonnes pratiques

  • Une clé par opération métier, pas par requête HTTP. Si l'utilisateur clique deux fois sur "Payer", générez la clé au premier clic et réutilisez-la.
  • Persistez la clé côté client jusqu'à la confirmation finale (success/failed/cancelled), pas seulement le temps de la requête.
  • Évitez les timestamps comme clé : deux retries à la milliseconde près généreraient deux clés différentes.

Documentation de l'API de paiement HayBTech.