Appearance
Idempotence
Garantit qu'un retry réseau ou une double soumission ne crée pas deux encaissements ni deux effets métier.
Deux mécanismes complémentaires
| Mécanisme | Clé | Portée | Comportement |
|---|---|---|---|
Idempotency-Key (en-tête HTTP) | Chaîne libre, trim | Par application | Replay exact du corps → même session 201 |
order_id (corps) | Identifiant dossier | Par application | Une notice ; une session open max ; retry après clôture autorisé |
Séquence : création avec retry
Règles POST /checkout/sessions
Même Idempotency-Key, même corps
L'API compare une empreinte des champs métier : order_id, amount, currency, mode, URLs, description, note, customer, customer_id, metadata, et le service catalogue résolu le cas échéant.
- Empreinte identique → renvoie la session existante (
201, pas de second webhook de création). - Empreinte différente →
409 idempotency.conflict.
Unicité : une clé d'idempotence ne peut être réutilisée qu'avec le même corps, au sein de la même application.
Même order_id, nouvelle Idempotency-Key
| État notice / session | Résultat |
|---|---|
| Collect réussi sur la notice | 409 checkout.completed |
Session open active sur la notice | 409 checkout.session_open |
Dernière session terminale (failed, expired, cancelled) | Nouvelle session autorisée ; même payment_ref (notice réutilisée) |
Première demande pour order_id | Nouvelle notice + session |
Le citoyen ne peut pas reprendre un checkout hébergé sur une session terminée : le SI doit rouvrir une session (nouvelle Idempotency-Key).
Rate limit
POST /checkout/sessions : 30 requêtes / minute / application. Dépassement : 429 generic.rate_limited sans écriture en base.
Idempotence webhook
Clé recommandée côté SI : (session_id, event) ou en-tête x-epayment-event-id (UUID de livraison).
Les retries plateforme (jusqu'à 5 tentatives, backoff 1 s / 5 s / 25 s / 125 s) peuvent reproduire le même événement. Le handler webhook doit être idempotent (unlockDossier(order_id) sans double effet).
Idempotence verify-completion
Après consommation du jeton cpt_…, un second appel avec le même token renvoie 200 avec l'état courant de la session (replay idempotent). Premier appel concurrent perdant : 409 checkout.completion_token_consumed.
Combiner avec webhook : les deux chemins doivent appeler la même logique métier idempotente.
Idempotence annulation
POST /checkout/sessions/{id}/cancel sur une session déjà cancelled renvoie l'état actuel sans erreur.
Bonnes pratiques
| Pratique | Recommandation |
|---|---|
Valeur Idempotency-Key | UUID v4 ou identifiant métier stable par tentative logique |
| Retry création | Rejouer la même clé et le même corps |
| Retry après échec paiement | Nouvelle clé, même order_id possible |
| Effet métier | Clé naturelle order_id ou notice_id, pas l'identifiant de livraison webhook seul |