INOPAS
Fondamentaux

Idempotence

Une requête d’encaissement part, la connexion tombe, aucune réponse ne revient. Le paiement a-t-il été créé ? Avec une clé d’idempotence, la question ne se pose plus : renvoyez la même requête, vous obtenez la réponse d’origine, jamais un second encaissement.

Une clé par opération

Toute écriture (POST /v1/charges, /v1/refunds, /v1/payouts) porte un en-tête Idempotency-Key. La clé fait partie de la chaîne signée: elle ne peut pas être remplacée en chemin.

  • Une clé par opération, pas par tentative. Les relances d’un même paiement réutilisent la même clé ; un nouveau paiement en prend une nouvelle.
  • Dérivez-la de votre propre référence, par exemple commande-1042-paiement-1. Après un redémarrage, votre code la recalcule à l’identique, là où un identifiant aléatoire perdu en mémoire serait introuvable.
  • 255 caractères au plus. Au-delà, la requête est refusée en 400 avec le code validation_error, sans rien créer.
  • Les clés sont propres à votre compte : celles d’un autre marchand ne peuvent pas entrer en collision avec les vôtres.
Envoyer deux fois la même opération
KEY="ak_sandbox"
SECRET="sk_sandbox_demo"
BODY='{"amount_minor":2500000,"currency":"CDF","customer_ref":"+243810000000"}'
# Une clé par OPÉRATION, pas par tentative. Dans le Sandbox public, la clé est
# partagée entre visiteurs : on y ajoute un aléa pour ne pas croiser la leur.
IDEM="commande-1042-paiement-$(uuidgen)"

for tentative in 1 2; do
  TS=$(date +%s)
  SIG=$(printf '%s' "$TS.POST./v1/charges.$IDEM.$BODY" \
    | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.*= //')
  curl -s https://sandbox.inopas.net/v1/charges \
    -H "Content-Type: application/json" \
    -H "X-Inopas-Key: $KEY" \
    -H "X-Inopas-Timestamp: $TS" \
    -H "X-Inopas-Signature: sha256=$SIG" \
    -H "Idempotency-Key: $IDEM" \
    -d "$BODY"
  echo
done
# Les deux réponses portent le même id : un seul encaissement existe.

Ce que répond l’API

Réponse de l’API selon l’usage de la clé
SituationRéponse
Première requête avec cette cléExécutée normalement. Une réponse réussie est enregistrée avec la clé.
Même clé, même requêteLa réponse enregistrée, à l’identique : même statut, même corps, même id. Rien n’est créé.
Même clé, requête différente (méthode, chemin ou corps)409 idempotency_conflict. Rien n’est exécuté.
Même clé, première requête encore en cours409 idempotency_in_progress, avec Retry-After: 1. Renvoyez ensuite la même requête.
Requête refusée pendant son traitementRien n’est enregistré et la clé reste libre : corrigez la cause, puis renvoyez.
Écriture sans clé400 idempotency_key_required.

Si une requête reste bloquée en cours, par exemple parce que le serveur qui la traitait s’est arrêté, la clé redevient utilisable au bout d’une minute.

Et ensuite

L’idempotence rend les relances sûres ; encore faut-il savoir quand relancer. Les règles de relance disent quelles erreurs se relancent et à quel rythme.

Un seul branchement, tous les paiements.