# Traiter les événements webhook non envoyés Découvrez comment traiter manuellement les événements webhook non envoyés. Si votre endpoint de webhook ne peut temporairement pas traiter les événements, Stripe [renvoie automatiquement](https://docs.stripe.com/webhooks.md#automatic-retries) les événements non remis à votre endpoint pendant trois jours maximum, ce qui augmente le temps nécessaire pour que votre endpoint de webhook reçoive et traite tous les événements. Ce guide explique comment accélérer ce processus en traitant manuellement les événements non envoyés. ## Répertorier les événements webhook Appel à l’API [List Events](https://docs.stripe.com/api/events/list.md) avec les paramètres suivants : - `ending_before` : indiquez un ID d’événement envoyé juste avant que l’endpoint de webhook ne devienne indisponible. - `types` : spécifiez la liste des types d’événements à récupérer. - `delivery_success` : définissez ce paramètre sur `false` pour récupérer les événements qui ont été envoyés sans succès à au moins l’un de vos endpoints de webhook. Stripe ne renvoie que les événements créés au cours des 30 derniers jours. ```curl curl -G https://api.stripe.com/v1/events \ -u "<>:" \ -d ending_before=evt_001 \ -d "types[]=payment_intent.succeeded" \ -d "types[]=payment_intent.payment_failed" \ -d delivery_success=false ``` Par défaut, la réponse renvoie jusqu’à 10 événements. Pour récupérer tous les événements, utilisez l’[autopagination](https://docs.stripe.com/api/pagination/auto.md) après avoir récupéré les résultats. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') events = client.v1.events.list({ ending_before: 'evt_001', types: ['payment_intent.succeeded', 'payment_intent.payment_failed'], delivery_success: false, }) events.auto_paging_each do |event| # This function is defined in the next section process_event(event) end ``` L’utilisation de `ending_before` avec l’autopagination renvoie les événements dans l’ordre chronologique. Cela vous permet de traiter les événements dans l’ordre dans lequel ils ont été créés. ## Traiter les événements Ne traitez que les événements traités sans succès selon votre propre logique afin d’éviter de traiter un même événement plusieurs fois, par exemple : - En exécutant involontairement le script deux fois de suite - En exécutant simultanément le script pendant que Stripe renvoie automatiquement certains des événements non traités #### Ruby ```ruby def process_event(event) if is_processing_or_processed(event) puts "skipping event #{event.id}" else puts "processing event #{event.id}" mark_as_processing(event) # Process the event # ... mark_as_processed(event) end end ``` Définissez les fonctionnalités suivantes qui permettent d’éviter la duplication des traitements : - `is_processing_or_processed` pour vérifier l’état de l’événement dans votre base de données. - `mark_as_processing` pour mettre à jour votre base de données afin de marquer l’événement comme étant en cours de traitement. - `mark_as_processed` pour mettre à jour votre base de données afin de marquer l’événement comme étant traité. ## Répondre aux relances automatiques Stripe considère toujours que vos événements traités manuellement n’ont pas été envoyés et effectue en continu de nouvelles tentatives automatiques. Lorsque votre endpoint de webhook reçoit un événement déjà traité, ignorez l’événement et renvoyez une réponse positive afin d’empêcher les tentatives ultérieures. #### Ruby ```ruby require 'json' require 'stripe' client = Stripe::StripeClient.new(ENV.fetch('STRIPE_API_KEY')) # Using Sinatra post '/webhook' do payload = request.body.read event = nil begin event = Stripe::Event.construct_from( JSON.parse(payload, symbolize_names: true) ) rescue JSON::ParserError => e # Invalid payload status 400 return end if is_processing_or_processed(event) puts "skipping event #{event.id}" else puts "processing event #{event.id}" mark_as_processing(event) # Process the event # ... mark_as_processed(event) end status 200 end ```