Idempotence et rejeu
Clé orderId, conflit 409, et la règle de l'issue indéterminée.
orderId est la clé, et il n'y en a pas d'autre
L'identification d'une transaction repose entièrement sur l'orderId que
vous fournissez. Il n'existe pas de header Idempotency-Key.
- Unique par organisation — pas globalement. Deux marchands peuvent porter
le même
orderIdsans se gêner. - 1 à 100 caractères,
^[A-Za-z0-9_-]+$: lettres, chiffres,_et-uniquement.
À vous de le rendre stable et unique. Un compteur séquentiel (order_1,
order_2) est un mauvais choix : il est devinable, et le
reçu public est adressable par orderId seul. Préférez un
identifiant non devinable, par exemple order-<uuid v4>.
Conservez le transactionId (un UUID) renvoyé dans la réponse : c'est la
référence de corrélation à citer au support az54.
Rejouer : la règle de l'issue indéterminée
C'est le point qui distingue une intégration robuste d'une intégration qui perd de l'argent.
Un 502 ou un timeout ne vous autorise pas à conclure que le paiement a
échoué. Dans ces deux cas, la requête a pu atteindre le PSP et le paiement a
pu aboutir. Le statut ne fait pas foi tant que le webhook n'a pas parlé.
La bonne réaction est toujours la même : rejouer strictement la même requête,
avec le même orderId et le même corps.
Deux issues possibles :
200— votre première tentative n'avait rien créé. La demande est maintenant enregistrée.409 CONFLICT— la transaction existait déjà.dataporte{ orderId, status }: c'est son état courant. C'est une réponse normale, pas une erreur à remonter. Vous venez d'apprendre ce que vous cherchiez.
Ne changez pas d'orderId au rejeu
Un orderId neuf au rejeu crée une seconde transaction : deux
sollicitations, potentiellement deux débits chez le payeur.
Ne modifiez pas non plus les autres champs. Un corps différent peut être rejeté
par une validation en amont du contrôle d'unicité — vous recevez alors un 400
qui masque le fait que la transaction existe déjà, et vous concluez à tort à un
échec.
Ce qui n'est pas dédupliqué
L'unicité porte sur la création. Les notifications sortantes ne sont pas numérotées : concevez votre handler de webhook comme idempotent, en vous appuyant sur la monotonie des statuts — la première notification terminale fait foi, les suivantes sont sans effet.
