# Webhooks Connect Découvrez comment utiliser les webhooks avec Connect pour recevoir des notifications liées à l'activité Stripe. Stripe utilise des *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) pour informer votre application qu’un événement s’est produit sur votre compte. Toutes les intégrations *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) doivent créer un [endpoint de webhook](https://dashboard.stripe.com/account/webhooks) chargé d’écouter les événements Connect. ## Webhooks Connect Les webhooks pour les utilisateurs de Connect écoutent les événements dans différentes portées, selon la source de l’événement : - **Votre compte** : la plupart des événements déclenchés par des ressources qui existent dans votre compte. Cela inclut la plupart des requêtes effectuées avec vos clés API et sans [s’authentifier en tant qu’autre compte Stripe](https://docs.stripe.com/connect/authentication.md), telles que : - Événements `v2.core.account.*` pour les `Accounts` v2 de votre compte - Événements pour les `Customers` de votre compte - Événements pour les paiements directs sur votre compte - Événements pour les *paiements indirects* (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) sur votre compte pour vos comptes connectés - **Comptes connectés** : événements déclenchés par des ressources qui existent dans des comptes connectés et certaines ressources qui existent dans votre compte, tels que : - Événements `v2.core.account.*` pour les `Accounts` v2 représentant les clients et bénéficiaires de vos comptes connectés - Événements v1 `account.updated` pour les `Accounts` v1 et v2 représentant les clients et bénéficiaires de vos comptes connectés - *Paiements directs* (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) pour les clients de vos comptes connectés > #### Portées des événements pour les comptes v2 représentant des comptes connectés > > Les objets `Account` v2 déclenchent à la fois des `Events` v1 et v2, dont la portée peut différer. Pour les événements déclenchés par des comptes connectés, les `Events` v2 utilisent la portée **Votre compte**, tandis que les `Events` v1 utilisent la portée **Comptes connectés**, même lorsqu’ils sont déclenchés par le même `Account` v2. Lorsque vous créez un webhook dans [Workbench](https://dashboard.stripe.com/workbench/webhooks), assignez la portée en définissant **Événements provenant de** sur **Votre compte** ou **Comptes connectés**. Lorsque vous créez un webhook via l’API, assignez la portée en définissant le paramètre [connect](https://docs.stripe.com/api/webhook_endpoints/create.md#create_webhook_endpoint-connect) sur false (pour **Votre compte**) ou true (pour **Comptes connectés**). Pour les webhooks Connect, les URL de vos webhooks de développement ne reçoivent que des webhooks de test, tandis que vos URL de webhooks de production reçoivent à la fois des webhooks en mode production et des webhooks de test. En effet, vous pouvez effectuer des transactions en mode production et en mode test depuis une application en production. Nous vous recommandons de vérifier la valeur `livemode` lorsque vous recevez un webhook d’événement pour déterminer si les utilisateurs doivent effectuer une action. Vous devez définir des endpoints de webhook distincts pour vos comptes en [environnement de test](https://docs.stripe.com/sandboxes.md) afin de recevoir les événements associés à ces comptes. Chaque événement d’un compte connecté contient une propriété `account` de niveau supérieur qui identifie le compte connecté. Étant donné que le compte connecté est propriétaire de [l’objet qui a déclenché l’événement](https://docs.stripe.com/api/events/object.md#event_object-data-object), vous devez effectuer des requêtes API pour cet objet [en tant que compte connecté](https://docs.stripe.com/connect/authentication.md). ```json { "id": ""{{EVENT_ID}}"", "livemode": true, "object": "event", "type": "customer.created", "account": ""{{CONNECTED_ACCOUNT_ID}}"", "pending_webhooks": 2, "created": 1349654313, "data": {...} } ``` Le tableau suivant décrit certains des événements les plus courants et les plus importants liés aux comptes connectés : | Événement | Type de data.object | Description | | ---------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `account.application.deauthorized` | `application` | Se produit lorsqu’un compte connecté se déconnecte de votre plateforme. Vous pouvez l’utiliser pour déclencher un nettoyage sur votre serveur. Disponible pour les comptes connectés ayant accès au Dashboard Stripe, ce qui inclut les [comptes Standard](https://docs.stripe.com/connect/standard-accounts.md). | | `account.external_account.updated` | Un compte externe, tel que `card` ou `bank_account` | Se produit lorsqu’[un compte bancaire associé ou une carte de débit associée à un compte connecté est modifié(e)](https://docs.stripe.com/connect/payouts-bank-accounts.md), ce qui peut avoir des conséquences sur les virements. Disponible pour les comptes connectés contrôlés par votre plateforme, comptes Custom et Express compris, et pour les comptes Standard dont les [contrôles de la plateforme](https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts.md) sont activés. | | `account.updated` | `account` | Permet de surveiller les évolutions des exigences relatives aux comptes connectés et les changements d’état. Disponible pour tous les comptes connectés. | | `balance.available` | `balance` | Se produit lorsque votre solde Stripe est mis à jour. Par exemple, lorsque les [fonds rechargés depuis votre compte bancaire](https://docs.stripe.com/connect/top-ups.md) sont disponibles pour un virement vers votre compte connecté. | | `payment_intent.succeeded` | `payment_intent` | Se produit lorsqu’un Payment Intent aboutit à un paiement réussi. Disponible pour tous les paiements, y compris les paiements de [destination](https://docs.stripe.com/connect/destination-charges.md) et [directs](https://docs.stripe.com/connect/direct-charges.md). | | `payout.failed` | `payout` | Se produit quand [un virement échoue](https://docs.stripe.com/connect/payouts-connected-accounts.md#webhooks). Lorsqu’un virement échoue, le compte externe concerné est désactivé. Aucun virement automatique ou manuel ne peut être traité tant que le compte externe n’a pas été mis à jour. | | `person.updated` | `person` | Se produit lorsqu’une `Person` associé au `Account` est modifiée. Si vous [utilisez l’API Persons pour gérer les exigences](https://docs.stripe.com/connect/handling-api-verification.md#verification-process), écoutez cet événement pour surveiller les évolutions des exigences et les changements d’état des personnes. Disponible pour les comptes connectés contrôlés par votre plateforme, comptes Custom et Express compris, et pour les comptes Standard dont les [contrôles de la plateforme](https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts.md) sont activés. | #### Événement - 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 ``` #### Événement - 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 ``` #### Événement - 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 ``` #### Événement - 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 ``` #### Événement - payment_intent.succeeded, non-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 ``` #### Événement - 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 ``` #### Événement - 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 ``` #### Événement - 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 ``` ## Tester des webhooks en local Pour tester les webhooks d’événements en local avec la CLI Stripe : 1. Si ce n’est pas déjà fait, [installez la Stripe CLI](https://docs.stripe.com/stripe-cli/install.md) sur votre machine. 1. Connectez-vous à votre compte Stripe et configurez l’interface de ligne de commande en exécutant la commande `stripe login`. 1. Autorisez votre hôte local à recevoir un événement simulé en exécutant [stripe listen](https://docs.stripe.com/cli/listen), selon la portée de l’événement : - **Comptes connectés** : `stripe listen --forward-connect-to localhost:{{PORT}}/{{CONNECT_WEBHOOK_ENDPOINT}}` - **Votre compte** : `stripe listen --forward-to localhost:{{PORT}}/{{WEBHOOK_ENDPOINT}}` 1. Dans une autre fenêtre de terminal, déclenchez un événement simulé en exécutant [stripe trigger](https://docs.stripe.com/cli/trigger), selon la portée de l’événement : - **Comptes connectés** : `stripe trigger --stripe-account {{CONNECTED_ACCOUNT_ID}} {{EVENT_NAME}}` - **Votre compte** : `stripe trigger {{EVENT_NAME}}` ## See also - [Documentation relative aux webhooks](https://docs.stripe.com/webhooks.md) - [Documentation relative à l’objet Event](https://docs.stripe.com/api.md#events)