# Nicht zugestellte Webhook-Ereignisse verarbeiten Erfahren Sie, wie Sie nicht zugestellte Webhook-Ereignisse manuell verarbeiten können. Wenn Ihr Webhook-Endpoint Ereignisse vorübergehend nicht verarbeiten kann, sendet Stripe die nicht zugestellten Ereignisse bis zu drei Tage lang [automatisch](https://docs.stripe.com/webhooks.md#automatic-retries) an Ihren Endpoint zurück, wodurch die Zeit für den Empfang und die Verarbeitung aller Ereignisse durch den Webhook-Endpoint verlängert wird. In diesem Leitfaden wird erläutert, wie Sie diesen Prozess beschleunigen können, indem Sie die nicht zugestellten Ereignisse manuell verarbeiten. ## Webhook-Ereignisse auflisten Rufen Sie die [List Events](https://docs.stripe.com/api/events/list.md) API mit den folgenden Parametern auf: - `ending_before`: Geben Sie eine Ereignis-ID an, die gesendet wurde, kurz bevor der Webhook-Endpoint nicht mehr verfügbar war. - `types`: Geben Sie die Liste der abzurufenden Ereignistypen an. - `delivery_success`: Auf `false` setzen, um Ereignisse abzurufen, die nicht erfolgreich an mindestens einen Ihrer Webhook-Endpoints gesendet wurden. Stripe gibt nur Ereignisse zurück, die in den letzten 30 Tagen erstellt wurden. ```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 ``` Standardmäßig gibt die Antwort bis zu 10 Ereignisse zurück. Um alle Ereignisse abzurufen, verwenden Sie den [automatischen Seitenumbruch](https://docs.stripe.com/api/pagination/auto.md) nach dem Abrufen der Ergebnisse. #### 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 ``` Die Verwendung von `ending_before` mit automatischem Seitenumbruch gibt Ereignisse in chronologischer Reihenfolge zurück. Auf diese Weise können Sie Ereignisse in der erstellten Reihenfolge verarbeiten. ## Die Ereignisse verarbeiten Verarbeiten Sie nur erfolglos verarbeitete Ereignisse nach Ihrer eigenen Logik, um die mehrfache Verarbeitung eines einzelnen Ereignisses zu vermeiden, indem Sie zum Beispiel: - das Skript versehentlich zweimal hintereinander ausführen - das Skript gleichzeitig ausführen, während Stripe einige der nicht verarbeiteten Ereignisse automatisch erneut sendet #### 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 ``` Definieren Sie die folgenden Funktionen, die die doppelte Verarbeitung verhindern: - `is_processing_or_processed`, um den Status des Ereignisses in Ihrer Datenbank zu überprüfen. - `mark_as_processing`, um Ihre Datenbank zu aktualisieren, um das Ereignis als „wird verarbeitet“ zu markieren. - `mark_as_processed`, um Ihre Datenbank zu aktualisieren, um das Ereignis als „verarbeitet“ zu markieren. ## Auf automatische Wiederholungsversuche reagieren Stripe betrachtet Ihre manuell verarbeiteten Ereignisse weiterhin als nicht zugestellt und versucht automatisch, sie erneut auszuführen. Wenn Ihr Webhook-Endpoint ein bereits verarbeitetes Ereignis empfängt, ignorieren Sie das Ereignis und geben Sie eine erfolgreiche Antwort zurück, um zukünftige Wiederholungen zu stoppen. #### 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 ```