# Connect-Webhooks Erfahren Sie mehr über die Verwendung von Webhooks mit Connect, um über Stripe-Aktivitäten benachrichtigt zu werden. Stripe nutzt *Webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests), um Ihre Anwendung bei einem Ereignis in Ihrem Konto zu benachrichtigen. Alle *Connect* (Connect is Stripe's solution for multi-party businesses, such as marketplace or software platforms, to route payments between sellers, customers, and other recipients)-Integrationen sollten einen [Webhook-Endpoint](https://dashboard.stripe.com/account/webhooks) einrichten, um auf Connect-Ereignisse aufmerksam gemacht zu werden. ## Connect-Webhooks Webhooks für Nutzer/innen von Connect überwachen Ereignisse in unterschiedlichen Bereichen, je nach Quelle des Ereignisses: - **Ihr Konto**: Die meisten Ereignisse werden durch Ressourcen ausgelöst, die in Ihrem Konto vorhanden sind. Dazu gehören die meisten Anfragen, die unter Verwendung Ihrer API-Schlüssel und ohne [Authentifizierung als anderes Stripe-Konto](https://docs.stripe.com/connect/authentication.md) getätigt werden, wie zum Beispiel: - `v2.core.account.*`-Ereignisse für v2-`Accounts` in Ihrem Konto - Ereignisse für `Customers` in Ihrem Konto - Ereignisse für Direct Charges in Ihrem Konto - Ereignisse im Zusammenhang mit *indirekten Gebühren* (A charge type where customers transact directly with your platform instead of with a connected account. Indirect charges include destination charges and separate charges and transfers) auf Ihrem Konto für Ihre verbundenen Konten - **Verbundene Konten**: Ereignisse, die durch Ressourcen in verbundenen Konten und durch bestimmte Ressourcen in Ihrem Konto ausgelöst werden, wie zum Beispiel: - `v2.core.account.*`-Ereignisse für v2 `Accounts`, die Kundinnen und Kunden sowie Empfänger/innen Ihrer verbundenen Konten darstellen - v1-`account.updated`-Ereignisse für v1- und v2-`Accounts`, die Kundinnen und Kunden sowie Empfänger/innen Ihrer verbundenen Konten darstellen - *Direct Charges* (A charge type where customers transact directly with a connected account, which is always the merchant of record. With each payment, the connected account pays fees to Stripe and, optionally, to your platform) für Kundinnen und Kunden Ihrer verbundenen Konten > #### Ereignisbereiche für v2 Accounts, die verbundene Konten repräsentieren > > v2-`Account`-Objekte lösen sowohl v1- als auch v2-`Events` aus, die unterschiedliche Bereiche haben können. Bei Ereignissen, die durch verbundene Konten ausgelöst werden, verwenden v2-`Events` den Bereich **Ihr Konto**, während v1-`Events` den Bereich **Verbundene Konten** verwenden, selbst wenn sie durch dasselbe v2-`Account` ausgelöst werden. Wenn Sie einen Webhook in [Workbench](https://dashboard.stripe.com/workbench/webhooks) erstellen, legen Sie den Geltungsbereich fest, indem Sie unter **Ereignisse von** die Option **Ihr Konto** oder **Verbundene Konten** auswählen. Wenn Sie einen Webhook über die API erstellen, legen Sie den Geltungsbereich fest, indem Sie den Parameter [connect](https://docs.stripe.com/api/webhook_endpoints/create.md#create_webhook_endpoint-connect) auf „false“ (für **Ihr Konto**) oder „true“ (für **Verbundene Konten**) setzen. Bei Connect-Webhooks empfangen Ihre Entwicklungs-Webhook-URLs nur Test-Webhooks, Ihre Produktions-Webhook-URLs empfangen jedoch sowohl Live- als auch Test-Webhooks. Dies liegt daran, dass Sie in einer Produktionsanwendung sowohl Live- als auch Testtransaktionen durchführen können. Wir empfehlen Ihnen, den Wert für den `livemode` zu überprüfen, wenn Sie einen Ereignis-Webhook erhalten, um festzustellen, ob Nutzer/innen Maßnahmen ergreifen müssen. Sie müssen für Ihre Konten in der [Sandbox](https://docs.stripe.com/sandboxes.md) separate Webhook-Endpoints definieren, um Ereignisse für diese Konten zu empfangen. Jedes Ereignis für ein verbundenes Konto enthält eine Top-Level-Eigenschaft `account`, die das verbundene Konto identifiziert. Da das verbundene Konto [das Objekt, das das Ereignis ausgelöst hat](https://docs.stripe.com/api/events/object.md#event_object-data-object) besitzt, müssen Sie [als verbundenes Konto](https://docs.stripe.com/connect/authentication.md) API-Anfragen für dieses Objekt stellen. ```json { "id": ""{{EVENT_ID}}"", "livemode": true, "object": "event", "type": "customer.created", "account": ""{{CONNECTED_ACCOUNT_ID}}"", "pending_webhooks": 2, "created": 1349654313, "data": {...} } ``` In der folgenden Tabelle werden einige der häufigsten und wichtigsten Ereignisse im Zusammenhang mit verbundenen Konten beschrieben: | Ereignis | data.object type | Beschreibung | | ---------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `account.application.deauthorized` | `application` | Tritt auf, wenn ein verbundenes Konto die Verbindung zu Ihrer Plattform trennt. Sie können damit eine Bereinigung Ihres Servers auslösen. Verfügbar für verbundene Konten mit Zugriff auf das Stripe-Dashboard. Dazu zählen [Standard-Konten](https://docs.stripe.com/connect/standard-accounts.md). | | `account.external_account.updated` | Ein externes Konto, zum Beispiel `card` oder `bank_account` | Tritt auf, wenn [ein Bankkonto oder eine Debitkarte, das/die mit einem verbundenen Konto verknüpft ist, aktualisiert wird](https://docs.stripe.com/connect/payouts-bank-accounts.md). Dies kann sich auf Auszahlungen auswirken. Verfügbar für verbundene Konten, die von Ihrer Plattform gesteuert werden, einschließlich Custom- und Express- sowie Standard-Konten mit aktivierten [Plattformkontrollen](https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts.md). | | `account.updated` | `account` | Ermöglicht Ihnen die Überwachung von Veränderungen bei den Anforderungen verbundener Konten sowie von Statusänderungen. Verfügbar für alle verbundenen Konten. | | `balance.available` | `balance` | Tritt auf, wenn Ihr Stripe-Guthaben aktualisiert wurde (zum Beispiel, wenn [von Ihrem Bankkonto eingezahlte Geldmittel](https://docs.stripe.com/connect/top-ups.md) zur Übertragung auf Ihr verbundenes Konto verfügbar sind). | | `payment_intent.succeeded` | `payment_intent` | Tritt auf, wenn ein Payment Intent eine erfolgreiche Zahlungsabwicklung zur Folge hat. Verfügbar für alle Zahlungen, einschließlich [Destination](https://docs.stripe.com/connect/destination-charges.md) und [Direct Charges](https://docs.stripe.com/connect/direct-charges.md)-Zahlungen. | | `payout.failed` | `payout` | Tritt auf, wenn [eine Auszahlung fehlschlägt](https://docs.stripe.com/connect/payouts-connected-accounts.md#webhooks). Wenn eine Auszahlung fehlschlägt, wird das betroffene externe Konto deaktiviert. Bis dieses externe Konto aktualisiert wird, können dann keine automatischen oder manuellen Auszahlungen mehr verarbeitet werden. | | `person.updated` | `person` | Tritt auf, wenn eine dem `Account` zugeordnete `Person` aktualisiert wird. Wenn Sie [die Persons API zur Verarbeitung von Anforderungen verwenden](https://docs.stripe.com/connect/handling-api-verification.md#verification-process), überwachen Sie dieses Ereignis, um Änderungen an den Anforderungen und Statusänderungen für Einzelpersonen zu überwachen. Verfügbar für verbundene Konten, die von Ihrer Plattform gesteuert werden, einschließlich Custom- und Express- sowie Standard-Konten mit aktivierten [Plattformkontrollen](https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts.md). | #### Ereignis - account.application.deauthorized #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # 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('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.application.deauthorized' application = event['data']['object'] connected_account_id = event['account'] handle_deauthorization(connected_account_id, application) end status 200 end def handle_deauthorization(connected_account_id, application) # Clean up account state. puts 'Connected account ID: ' + connected_account_id puts application.to_s end ``` #### Ereignis - account.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # 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('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.updated' account = event['data']['object'] handle_account_update(account) end status 200 end def handle_account_update(account) # Collect more required information puts account.to_s end ``` #### Ereignis - person.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # 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('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'person.updated' person = event['data']['object'] connected_account_id = event['account'] handle_person_update(connected_account_id, person) end status 200 end def handle_person_update(connected_account_id, person) # Collect more required information puts 'Connected account ID: ' + connected_account_id puts person.to_s end ``` #### Ereignis - payment_intent.succeeded, Direct Charge #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # 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('<>') # If you are testing your webhook locally with the Stripe CLI you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payment_intent.succeeded' payment_intent = event['data']['object'] connected_account_id = event['account'] handle_successful_payment_intent(connected_account_id, payment_intent) end status 200 end def handle_successful_payment_intent(connected_account_id, payment_intent) # Fulfill the purchase puts 'Connected account ID: ' + connected_account_id puts payment_intent.to_s end ``` #### Ereignis - payment_intent.succeeded, keine Direct Charge #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # 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('<>') # If you are testing your webhook locally with the Stripe CLI you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payment_intent.succeeded' payment_intent = event['data']['object'] handle_successful_payment_intent(payment_intent) end status 200 end def handle_successful_payment_intent(payment_intent) # Fulfill the purchase puts payment_intent.to_s end ``` #### Ereignis - balance.available #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # 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('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'balance.available' balance = event['data']['object'] handle_available_balance(balance) end status 200 end def handle_available_balance(balance) # Transfer funds to a connected account puts balance.to_s end ``` #### Ereignis - account.external_account.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # 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('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.external_account.updated' external_account = event['data']['object'] connected_account_id = event['account'] handle_external_account_update(connected_account_id, external_account) end status 200 end def handle_external_account_update(connected_account_id, external_account) # Transfer funds to a connected account puts 'Connected account ID: ' + connected_account_id puts external_account.to_s end ``` #### Ereignis - payout.failed #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # 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('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payout.failed' payout = event['data']['object'] connected_account_id = event['account'] handle_failed_payout(connected_account_id, payout) end status 200 end def handle_failed_payout(connected_account_id, payout) # Re-collect bank account required information puts 'Connected account ID: ' + connected_account_id puts payout.to_s end ``` ## Webhooks lokal testen So testen Sie Ereignis-Webhooks lokal mit der Stripe-CLI: 1. Falls noch nicht geschehen, [installieren Sie die Stripe CLI](https://docs.stripe.com/stripe-cli/install.md) auf Ihrem Computer. 1. Melden Sie sich in Ihrem Stripe-Konto an und richten Sie die CLI ein, indem Sie in der Befehlszeile `stripe login` ausführen. 1. Geben Sie Ihrem lokalen Host die Möglichkeit, ein simuliertes Ereignis zu empfangen, indem Sie je nach Umfang des Ereignisses den Befehl [stripe listen](https://docs.stripe.com/cli/listen) ausführen: - **Verbundene Konten**: `stripe listen --forward-connect-to localhost:{{PORT}}/{{CONNECT_WEBHOOK_ENDPOINT}}` - **Ihr Konto**: `stripe listen --forward-to localhost:{{PORT}}/{{WEBHOOK_ENDPOINT}}` 1. Lösen Sie in einem anderen Terminalfenster ein simuliertes Ereignis aus, indem Sie je nach Geltungsbereich des Ereignisses den Befehl [stripe trigger](https://docs.stripe.com/cli/trigger) ausführen: - **Verbundene Konten**: `stripe trigger --stripe-account {{CONNECTED_ACCOUNT_ID}} {{EVENT_NAME}}` - **Ihr Konto**: `stripe trigger {{EVENT_NAME}}` ## See also - [Webhook-Dokumentation](https://docs.stripe.com/webhooks.md) - [Objektreferenz zu Ereignissen](https://docs.stripe.com/api.md#events)