# Recevez des événements Stripe dans votre point de terminaison de webhook

Écoutez les événements transmis par Stripe sur votre point de terminaison HTTPS afin que votre intégration puisse déclencher automatiquement les actions appropriées.

## Commencez ici&nbsp;: Installer les compétences d’agents

Stripe recommande d’utiliser les compétences officielles pour intégrer l’API en utilisant les bonnes pratiques. Suivez les instructions ci-dessous pour en savoir plus.

**Astuce&nbsp;: utilisez curl au lieu des outils Fetch.** Les compétences sont des fichiers markdown de&nbsp;10 à 20&nbsp;KB. Les outils de récupération les résument. `curl -sL` assure que le contenu est complet.

**Utilisation des `compétences npx`**&nbsp;: vérifiez si `npx` est installé sur le système. Si `npx` est disponible, exécutez `npx skills add https://docs.stripe.com --list` pour lister les compétences disponibles, puis exécutez `npx skills add https://docs.stripe.com --yes --skill <skill-name> <--skill other-skills>` pour installer des compétences individuelles.

**Si les `compétences npx` ne sont pas disponibles**&nbsp;: vous pouvez utiliser curl pour récupérer l’index des compétences disponibles, ce qu’elles font, et leurs fichiers à partir de `https://docs.stripe.com/.well-known/skills/index.json`. Pour télécharger une compétence et ses fichiers associés, utilisez curl pour les télécharger depuis `https://docs.stripe.com/.well-known/skills/<filepath>`.

Pour cet article, nous vous recommandons d’utiliser les compétences suivantes&nbsp;: `stripe-best-practices`

> #### Envoyer des événements à votre compte AWS ou abonnement Azure
> 
> Vous pouvez envoyer des événements directement à [Amazon EventBridge](https://docs.stripe.com/event-destinations/eventbridge.md) ou [Azure Event Grid](https://docs.stripe.com/event-destinations/eventgrid.md) en tant que destinations d’événements.

Créez une destination d’événement pour recevoir des événements au niveau d’un point de terminaison webhook HTTPS. Après avoir enregistré un point de terminaison webhook, Stripe peut transmettre des données d’événements en temps réel au point de terminaison webhook de votre application lorsque des [événements](https://docs.stripe.com/event-destinations.md#events-overview) se produisent dans votre compte Stripe. Stripe utilise HTTPS pour envoyer des événements webhook à votre application sous forme de charge utile JSON qui comprend un [objet Event](https://docs.stripe.com/api/events.md).

La réception d’événements avec webhooks vous permet de répondre aux événements asynchrones tels que la confirmation d’un paiement par l’institution financière du client, la contestation d’un paiement par le client ou l’aboutissement d’un paiement récurrent.

## Premiers pas

Pour commencer à recevoir des événements webhook dans votre application&nbsp;:

1. Créez un gestionnaire de point de terminaison de webhook pour recevoir des requêtes POST de données d’événement.
1. Testez votre gestionnaire de point de terminaison de webhook localement à l’aide de l’interface de ligne de commande Stripe.
1. Créez une [destination d’événement](https://docs.stripe.com/event-destinations.md) pour votre point de terminaison de webhook.
1. Sécurisez votre point de terminaison de webhook.

Vous pouvez enregistrer et créer un point de terminaison pour gérer plusieurs types d’événements simultanément, ou configurer des points de terminaison individuels pour des événements particuliers.

## Comportements de types d’événement non pris en charge pour les destinations des événements d’organisation

Stripe envoie la plupart des types d’événements de manière asynchrone, mais attend une réponse pour certains types d’événements. Dans ces cas, Stripe se comporte différemment selon que la destination de l’événement répond ou non.

Si votre destination d’événement reçoit des événements [Organisation](https://docs.stripe.com/get-started/account/orgs.md), ceux qui nécessitent une réponse sont soumis aux restrictions suivantes&nbsp;:

- Vous ne pouvez pas vous abonner à `issuing_authorization.request` pour les destinations d’organisation. Configurez plutôt un [point de terminaison de webhook](https://docs.stripe.com/webhooks.md#example-endpoint) dans un compte Stripe au sein de l’organisation pour vous abonner à ce type d’événement. Utilisez `issuing_authorization.request` pour autoriser les demandes d’achat en temps réel.
- Les organisations destinataires de `checkout_sessions.completed` ne peuvent pas [gérer le comportement de redirection](https://docs.stripe.com/checkout/fulfillment.md#redirect-hosted-checkout) lorsque vous intégrez [Checkout](https://docs.stripe.com/payments/checkout.md) directement dans votre site web ou redirigez les clients vers une page de paiement hébergée par Stripe. Pour influencer le comportement de redirection de Checkout, traitez ce type d’événement avec un [point de terminaison webhook](https://docs.stripe.com/webhooks.md#example-endpoint) configuré dans un compte Stripe au sein de l’organisation.
- Les organisations qui répondent sans succès à un événement `invoice.created` ne peuvent pas influencer la [finalisation automatique des factures lorsqu’elles utilisent le prélèvement automatique](https://docs.stripe.com/billing/subscriptions/webhooks.md#understand). Vous devez traiter ce type d’événement avec un [point de terminaison webhook](https://docs.stripe.com/webhooks.md#example-endpoint) configuré dans un compte Stripe au sein de l’organisation pour déclencher la finalisation automatique des factures.

## Créer un gestionnaire

Configurez une fonction de point de terminaison HTTP ou HTTPS qui peut accepter les requêtes de webhook avec une méthode POST. Si vous développez toujours votre fonction de point de terminaison sur votre appareil local, elle peut utiliser HTTP. Une fois qu’elle est accessible au public, votre fonction de point de terminaison de webhook doit utiliser HTTPS.

Configurez votre fonction de point de terminaison de manière à ce qu’elle&nbsp;:

- Gère les requêtes POST avec une charge utile JSON constituée d’un [objet d’événement](https://docs.stripe.com/api/events/object.md).
- Pour les gestionnaires d’événements de [organization](https://docs.stripe.com/get-started/account/orgs.md), il inspecte la valeur de `context` afin de déterminer quel compte au sein d’une organisation a généré l’événement, puis définit l’en-tête `Stripe-Context` correspondant à la valeur de `context`.
- Renvoie rapidement un code d’état réussi (`2xx`) avant toute logique complexe qui pourrait provoquer un délai d’expiration. Par exemple, vous devez renvoyer une réponse `200` avant de mettre à jour la facture d’un client telle comme étant payée dans votre système comptable.

> - Utilisez notre [outil interactif pour la création de point de terminaison de webhook](https://docs.stripe.com/webhooks/quickstart.md) pour créer une fonction de point de terminaison de webhook dans votre langage de programmation.
- Utilisez la documentation sur les API Stripe pour identifier les [objets d’événements légers](https://docs.stripe.com/api/v2/core/events/event-types.md) ou les [objets d’événements instantanés](https://docs.stripe.com/api/events/object.md) que votre gestionnaire de lien de rappel HTTP doit traiter.

#### Exemple de point de terminaison

Cet extrait de code est une fonction webhook configurée pour vérifier les événements reçus depuis un compte Stripe, gérer les événements et renvoyer des réponses `200`. Référencez le gestionnaire d’événements [instantanés](https://docs.stripe.com/event-destinations.md#events-overview) lorsque vous utilisez des ressources d’API v1, et référencez le gestionnaire d’événements [légers](https://docs.stripe.com/event-destinations.md#events-overview) lorsque vous utilisez des ressources d’API v2.

#### Gestionnaire d’événements instantanés

Lorsque vous créez un gestionnaire d’événements instantanés, utilisez pour votre logique la définition d’objet d’API au moment de l’événement en accédant aux champs `data.object` de l’événement. Vous pouvez également récupérer la ressource d’API à partir de l’API Stripe pour accéder à la définition d’objet la plus récente et à jour.

#### Ruby

```ruby
require 'json'
require 'stripe'

client = Stripe::StripeClient.new(ENV.fetch('STRIPE_API_KEY'))

# Replace this endpoint secret with your unique endpoint secret key
# If you're testing with the CLI, run 'stripe listen' to find the secret key
# If you defined your endpoint using the API or the Dashboard, check your webhook settings for your endpoint secret: https://dashboard.stripe.com/webhooks
endpoint_secret = 'whsec_...';

# 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

  # Check that you have configured webhook signing
  if endpoint_secret
    # Retrieve the event by verifying the signature using the raw body and the endpoint secret
    signature = request.env['HTTP_STRIPE_SIGNATURE'];
    begin
      event = Stripe::Webhook.construct_event(
        payload, signature, endpoint_secret
      )
    rescue Stripe::SignatureVerificationError => e
      puts "⚠️  Webhook signature verification failed. #{e.message}"
      status 400
    end
  end

  # Handle the event
  case event.type
  when 'payment_intent.succeeded'
    payment_intent = event.data.object # contains a Stripe::PaymentIntent
    # Then define and call a method to handle the successful payment intent.
    # handle_payment_intent_succeeded(payment_intent)
  when 'payment_method.attached'
    payment_method = event.data.object # contains a Stripe::PaymentMethod
    # Then define and call a method to handle the successful attachment of a PaymentMethod.
    # handle_payment_method_attached(payment_method)
  # ... handle other event types
  else
    puts "Unhandled event type: #{event.type}"
  end

  status 200
end
```

#### Gestionnaire d’événements fins (Clover+)

Lorsque vous créez un gestionnaire d’événement fin, utilisez la méthode `fetchRelatedObject()` pour récupérer la dernière version de l’objet associé à l’événement. Les événements peuvent contenir [des données supplémentaires](https://docs.stripe.com/event-destinations.md#fetch-data) que vous ne pouvez récupérer qu’au moyen de la méthode d’instance `.fetchEvent()` sur `EventNotification`. La forme exacte de ces données dépend du `type` de l’événement.

Les types d’événements doivent être disponibles au moment de la publication pour générer des classes dans cette version du SDK. Pour gérer les événements pour lesquels le SDK ne dispose pas de classes, utilisez la classe `UnknownEventNotification`.

#### Python

```python
import os
from stripe import StripeClient
from stripe.events import UnknownEventNotification

from flask import Flask, request, jsonify

app = Flask(__name__)
api_key = os.environ.get("STRIPE_API_KEY", "")
webhook_secret = os.environ.get("WEBHOOK_SECRET", "")

client = StripeClient(api_key)

@app.route("/webhook", methods=["POST"])
def webhook():
    webhook_body = request.data
    sig_header = request.headers.get("Stripe-Signature")

    try:
        event_notif = client.parse_event_notification(
            webhook_body, sig_header, webhook_secret
        )

        # type checkers will narrow the type based on the `type` property
        if event_notif.type == "v1.billing.meter.error_report_triggered":
            # in this block, event_notification is typed as
            # a V1BillingMeterErrorReportTriggeredEventNotification

            # there's basic info about the related object in the notification
            print(f"Meter w/ id {event_notif.related_object.id} had a problem")

            # or you can fetch the full object form the API for more details
            meter = event_notif.fetch_related_object()
            print(
                f"Meter {meter.display_name} ({meter.id}) had a problem"
            )

            # And you can always fetch the full event:
            event = event_notif.fetch_event()
            print(f"More info: {event.data.developer_message_summary}")

        elif event_notif.type == "v1.billing.meter.no_meter_found":
            # in this block, event_notification is typed as
            # a V1BillingMeterNoMeterFoundEventNotification

            # that class doesn't define `fetch_related_object` because the event
            # has no related object.
            # so this line would correctly give a type error:
            # meter = event_notif.fetch_related_object()

            # but fetching the event always works:
            event = event_notif.fetch_event()
            print(
                f"Err! No meter found: {event.data.developer_message_summary}"
            )

        # Events that were introduced after this SDK version release are
        # represented as `UnknownEventNotification`s.
        # They're valid, the SDK just doesn't have corresponding classes for them.
        # You must match on the "type" property instead.
        elif isinstance(event_notif, UnknownEventNotification):
            # these lines are optional, but will give you more accurate typing in this block
            from typing import cast

            event_notif = cast(UnknownEventNotification, event_notif)

            # continue matching on the type property
            # from this point on, the `related_object` property _may_ be None
            # (depending on the event type)
            if event_notif.type == "some.new.event":
                # if this event type has a related object, you can fetch it
                obj = event_notif.fetch_related_object()
                # otherwise, `obj` will just be `None`
                print(f"Related object: {obj}")

                # you can still fetch the full event, but it will be untyped
                event = event_notif.fetch_event()
                print(f"New event: {event.data}")  # type: ignore

        return jsonify(success=True), 200
    except Exception as e:
        return jsonify(error=str(e)), 400
```

#### Gestionnaire d’événements fins (Acacia ou Basil)

Lorsque vous créez un gestionnaire d’événements légers, utilisez la méthode `fetchRelatedObject()` pour récupérer la dernière version de l’objet associé à l’événement. Les événements légers peuvent contenir des [données contextuelles supplémentaires](https://docs.stripe.com/event-destinations.md#fetch-data) que vous ne pouvez récupérer qu’avec l’API. Utilisez l’appel `retrieve()` avec l’ID d’événement léger pour accéder aux champs de données utiles supplémentaires.

#### Python

```python
import os
from stripe import StripeClient
from stripe.events import V1BillingMeterErrorReportTriggeredEvent

from flask import Flask, request, jsonify

app = Flask(__name__)
api_key = os.environ.get('STRIPE_API_KEY')
webhook_secret = os.environ.get('WEBHOOK_SECRET')

client = StripeClient(api_key)

@app.route('/webhook', methods=['POST'])
def webhook():
    webhook_body = request.data
    sig_header = request.headers.get('Stripe-Signature')

try:
    thin_event = client.parse_thin_event(webhook_body, sig_header, webhook_secret)

    # Fetch the event data to understand the failure
    event = client.v2.core.events.retrieve(thin_event.id)
    if isinstance(event, V1BillingMeterErrorReportTriggeredEvent):
        meter = event.fetch_related_object()
        meter_id = meter.id

        # Record the failures and alert your team
        # Add your logic here

    return jsonify(success=True), 200
except Exception as e:
    return jsonify(error=str(e)), 400

if __name__ == '__main__':
    app.run(port=4242)
```

#### Utilisation du `context`

#### Événements instantanés

Cet extrait de code est une fonction webhook configurée pour rechercher les événements reçus, détecter le compte d’origine le cas échéant, gérer l’événement et renvoyer une réponse `200`.

#### Ruby

```ruby
require 'json'

client = Stripe::StripeClient.new('sk_...')

# 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

  # Extract the context
  context = event.context

  # Define your API key variables (ideally loaded securely)
  ACCOUNT_123_API_KEY = "sk_test_123"
  ACCOUNT_456_API_KEY = "sk_test_456"

  account_api_keys = {
    "account_123" => ACCOUNT_123_API_KEY,
    "account_456" => ACCOUNT_456_API_KEY
  }

  api_key = account_api_keys[context]

  if api_key.nil?
    puts "No API key found for context: #{context}"
    status 400
    return
  end

  # Handle the event
  case event.type
  when 'customer.created'
    customer = event.data.object

    begin

      latest_customer = client.v1.customers.retrieve(customer.id, {api_key: api_key})
      handle_customer_created(latest_customer, context)
    rescue => e
      puts "Error retrieving customer: #{e.message}"
      status 500
      return
    end

  when 'payment_method.attached'
    payment_method = event.data.object

    begin
      latest_payment_method = client.v1.payment_methods.retrieve(payment_method.id, {api_key: api_key})
      handle_payment_method_attached(latest_payment_method, context)
    rescue => e
      puts "Error retrieving payment method: #{e.message}"
      status 500
      return
    end

  else
    puts "Unhandled event type: #{event.type}"
  end

  status 200
end
```

#### Gestionnaire d’événements fins (Clover+)

Utilisez la propriété `context` de `EventNotification`pour identifier le compte pour les événements au sein de votre [organisation](https://docs.stripe.com/get-started/account/orgs.md). Vous devez définir manuellement l’en-tête [Stripe-Context](https://docs.stripe.com/context.md) pour tous les appels à l’API, à l’exception de `.fetchRelatedObject()` et `.fetchEvent()`, qui le font automatiquement.

#### Python

```python
org_api_key = os.environ.get("STRIPE_API_KEY")
webhook_secret = os.environ.get("WEBHOOK_SECRET")
client = StripeClient(org_api_key)

# inside your webhook handler
event_notification = client.parse_event_notification(payload, sig_header, webhook_secret)

# uses `context` automatically
event_notification.fetch_event()

# pass context manually for other API requests
client.v1.invoices.list(stripe_context=event_notification.context)
```

#### Gestionnaire d’événements fins (Acacia ou Basil)

Cet extrait de code est une fonction webhook configurée pour recevoir des événements légers dans toute une organisation, vérifier la signature, déterminer le compte d’origine à l’aide du champ `context` et utiliser la clé API de ce compte pour les appels à l’API suivants.

#### Python

```python
import os
from flask import Flask, request, jsonify
from stripe import StripeClient
from stripe.events import V1BillingMeterErrorReportTriggeredEvent

app = Flask(__name__)

org_api_key = os.environ.get("STRIPE_API_KEY")
webhook_secret = os.environ.get("WEBHOOK_SECRET")
client = StripeClient(org_api_key)

account_api_keys = {
    "account_123": os.environ.get("ACCOUNT_123_API_KEY"),
    "account_456": os.environ.get("ACCOUNT_456_API_KEY"),
}

@app.route("/webhook", methods=["POST"])
def webhook():
    payload = request.data
    sig_header = request.headers.get("Stripe-Signature")

    try:
        thin_event = client.parse_thin_event(payload, sig_header, webhook_secret)

        # Retrieve the event using the org client to inspect context
        event = client.v2.core.events.retrieve(thin_event.id)

        context = getattr(event, "context", None)
        if not context:
            return jsonify(error="Missing context"), 400

        account_key = account_api_keys.get(context)
        if not account_key:
            return jsonify(error="Unknown context"), 400

        account_client = StripeClient(account_key)
        full_event = account_client.v2.core.events.retrieve(thin_event.id)

        if isinstance(full_event, V1BillingMeterErrorReportTriggeredEvent):
            meter = full_event.fetch_related_object()
            meter_id = meter.id
            # Record the failures and alert your team
            # Add your logic here

        return jsonify(success=True), 200
    except Exception as e:
        return jsonify(error=str(e)), 400

if __name__ == "__main__":
    app.run(port=4242)
```

## Testez votre gestionnaire

Avant de mettre en production votre fonction de point de terminaison de webhook, nous vous recommandons de tester l’intégration de votre application. Pour ce faire, vous pouvez configurer un écouteur local pour envoyer des événements à votre machine locale et envoyer des événements de test. Vous devez utiliser l’[interface de ligne de commande](https://docs.stripe.com/stripe-cli.md) pour effectuer ces tests.

#### Transférer des événements à un point de terminaison local

Pour transférer des événements vers votre point de terminaison local, exécutez la commande suivante avec l’[interface de ligne de commande](https://docs.stripe.com/stripe-cli.md) afin de configurer un écouteur local. L’indicateur `--forward-to` envoie tous les [événements Stripe](https://docs.stripe.com/cli/trigger#trigger-event) dans un [bac à sable](https://docs.stripe.com/sandboxes.md) à votre point de terminaison de webhook local. Utilisez les commandes d’interface de ligne de commande appropriées ci-dessous selon que vous utilisez des événements [légers](https://docs.stripe.com/event-destinations.md#events-overview) ou des événements instantanés.

#### Transférer les événements instantanés

Utilisez la commande suivante pour transférer les [événements instantanés](https://docs.stripe.com/event-destinations.md#events-overview) à votre écouteur local.

```bash
stripe listen --forward-to localhost:4242/webhook
```

#### Transférer les événements légers

Utilisez la commande suivante pour transférer les [événements légers](https://docs.stripe.com/event-destinations.md#events-overview) à votre écouteur local.

```bash
$ stripe listen --forward-thin-to localhost:4242/webhook --thin-events "*"
```

> Vous pouvez également exécuter `Stripe listen` pour voir les événements dans&nbsp;[Stripe&nbsp;Shell](https://docs.stripe.com/workbench/shell.md),mais vous ne pourrez pas transférer les événements du shell vers votre point de terminaison local.

Les configurations suivantes sont utiles pour vous aider à effectuer des tests avec votre écouteur local&nbsp;:

- Pour désactiver la vérification du certificat HTTPS, utilisez l’indicateur facultatif `--skip-verify`.
- Pour transférer uniquement des événements spécifiques, utilisez l’indicateur optionnel `--events` et passez à une liste d’événements séparés par une virgule.

#### Transférer les événements instantanés cibles

Utilisez la commande suivante pour transférer les événements instantanés cibles à votre écouteur local.

```bash
stripe listen --events payment_intent.created,customer.created,payment_intent.succeeded,checkout.session.completed,payment_intent.payment_failed \
  --forward-to localhost:4242/webhook
```

#### Transférer les événements légers cibles

Utilisez la commande suivante pour transférer les événements légers cibles à votre écouteur local.

```bash
stripe listen --thin-events v1.billing.meter.error_report_triggered,v1.billing.meter.no_meter_found \
  --forward-thin-to localhost:4242/webhook
```

- Pour transférer les évènements à votre point de terminaison de webhook local depuis votre point de terminaison de webhook public enregistré dans Stripe, utilisez l’indicateur facultatif `--load-from-webhooks-api`. Celui-ci charge votre point de terminaison enregistré, analyse le chemin et ses évènements enregistrés, et ajoute ensuite le chemin à votre point de terminaison de webhook local dans le chemin `--forward-to path`.

#### Transférer des événements instantanés à partir d’un point de terminaison de webhook public

Utilisez la commande suivante pour transférer les événements instantanés d’un point de terminaison de webhook public vers votre écouteur local.

```bash
stripe listen --load-from-webhooks-api --forward-to localhost:4242/webhook
```

#### Transférer les événements légers à partir d’un point de terminaison de webhook public

Utilisez la commande suivante pour transférer les événements légers d’un point de terminaison de webhook public vers votre écouteur local.

```bash
stripe listen --load-from-webhooks-api --forward-thin-to localhost:4242/webhook
```

- Pour vérifier les signatures de webhook, utilisez le `{{WEBHOOK_SIGNING_SECRET}}` à partir de la sortie initiale de la commande d’écoute.

```output
Ready! Your webhook signing secret is '{{WEBHOOK_SIGNING_SECRET}}' (^C to quit)
```

#### Déclenchement d’événements de test

Pour envoyer des événements de test, déclenchez un type d’événement auquel votre destination d’événement est abonnée en créant manuellement un objet dans le Dashboard Stripe. Découvrez comment déclencher des événements avec [Stripe pour VS&nbsp;Code](https://docs.stripe.com/stripe-vscode.md).

#### Déclencher un événement instantané

Vous pouvez utiliser la commande suivante dans&nbsp;[Stripe&nbsp;Shell](https://docs.stripe.com/workbench/shell.md) ou [l’interface de ligne de commande Stripe](https://docs.stripe.com/stripe-cli.md). Cet exemple déclenche un événement `payment_intent.succeeded`&nbsp;:

```bash
stripe trigger payment_intent.succeeded
Running fixture for: payment_intent
Trigger succeeded! Check dashboard for event details.
```

#### Déclencher un événement léger

Vous pouvez utiliser la commande suivante dans le [Stripe CLI](https://docs.stripe.com/stripe-cli.md). Cet exemple déclenche un `événement v1.billing.meter.error_report_triggered`&nbsp;:

```bash
stripe trigger v1.billing.meter.error_report_triggered
Setting up fixture for: list_billing_meters
Running fixture for: list_billing_meters
Setting up fixture for: billing_meter
Running fixture for: billing_meter
Setting up fixture for: list_billing_meters_after_creation
Running fixture for: list_billing_meters_after_creation
Setting up fixture for: billing_meter_event_session
Running fixture for: billing_meter_event_session
Setting up fixture for: create_billing_meter_event_stream
Running fixture for: create_billing_meter_event_stream
Trigger succeeded! Check dashboard for event details.
```

## Enregistrer votre point de terminaison

Après avoir testé la fonction de votre point de terminaison de webhook, utilisez l’[API](https://docs.stripe.com/api/v2/event-destinations.md) ou l’onglet **Webhooks** de Workbench pour enregistrer l’URL accessible de votre point de terminaison de webhook afin que Stripe sache où envoyer les événements. Vous pouvez enregistrer jusqu’à 16&nbsp;points de terminaison de webhook auprès de Stripe. Les points de terminaison de webhook enregistrés doivent être des URL **HTTPS** accessibles au public.

#### Format d’URL de webhook

Le format d’URL pour enregistrer un point de terminaison de webhook est le suivant&nbsp;:

```
https://<your-website>/<your-webhook-endpoint>
```

Par exemple, si votre domaine est `https://mycompanysite.com` et que le chemin vers votre point de terminaison de webhook est `@app.route('/stripe_webhooks', methods=['POST'])`, précisez `https://mycompanysite.com/stripe_webhooks` comme l’**URL du point de terminaison**.

#### Créer une destination d’événement pour votre point de terminaison de webhook

Créez une destination d’événement à l’aide de Workbench dans le Dashboard ou par voie programmatique à l’aide de l’[API](https://docs.stripe.com/api/v2/event-destinations.md). Vous pouvez inscrire jusqu’à 16&nbsp;destinations d’événements dans chaque compte Stripe.

#### Le Dashboard.

Pour créer un nouveau point de terminaison webhook dans le Dashboard&nbsp;:

1. Ouvrez l’onglet [Webhooks](https://dashboard.stripe.com/webhooks) dans Workbench.
1. Cliquez sur **Créer une destination d’événement**.
1. Sélectionnez l’endroit duquel vous souhaitez recevoir les événements. Stripe prend en charge deux types de configurations&nbsp;: **Votre compte** et [Comptes connectés](https://docs.stripe.com/connect.md). Sélectionnez **Compte** pour écouter les événements de votre propre compte. Si vous avez créé une [application Connect](https://docs.stripe.com/connect.md) et que vous souhaitez écouter les événements de vos comptes connectés, sélectionnez **Comptes connectés**.

> #### Écouter des événements à partir d’un point de terminaison de webhook d’organisation
> 
> Si vous créez un point de terminaison de webhook dans un [compte d’organisation](https://docs.stripe.com/get-started/account/orgs.md), sélectionnez **Comptes** pour écouter les événements des comptes de votre organisation. Si des [plateformes Connect](https://docs.stripe.com/connect.md) figurent parmi les membres de vos organisations et que vous souhaitez écouter les événements de tous les comptes connectés des plateformes, sélectionnez **Comptes connectés**.

1. Sélectionnez la version de l’API pour l’[objet d’événements](https://docs.stripe.com/api/events.md) que vous souhaitez utiliser.
1. Sélectionnez les [types d’événements](https://docs.stripe.com/api/events/types.md) que vous souhaitez envoyer à un point de terminaison de webhook.
1. Sélectionnez **Continuer**, puis sélectionnez le **point de terminaison webhook** comme type de destination.
1. Cliquez sur **Continuer**, puis indiquez l’**URL du point de terminaison** et une description facultative du webhook.

#### L'API

Vous pouvez créer une nouvelle destination d’événement qui vous avertit lorsqu’une erreur de validation [facturation à l’utilisation](https://docs.stripe.com/billing/subscriptions/usage-based.md) est déclenchée à l’aide de l’[API](https://docs.stripe.com/api/v2/event-destinations.md).

Si vous avez créé un [formulaire d’inscription Connect](https://docs.stripe.com/connect.md) et que vous souhaitez recevoir vos comptes connectés, utilisez le paramètre [events_from](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-events_from) et attribuez-lui la valeur `@accounts`. Pour les destinations d’événements de l’[organisation](https://docs.stripe.com/get-started/account/orgs.md), utilisez `@organization_members` pour les événements provenant de comptes de votre organisation, ou `@organization_members/@accounts` pour les événements provenant de comptes connectés de votre organisation.

```curl
curl -X POST https://api.stripe.com/v2/core/event_destinations \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-04-22.preview" \
  --json '{
    "name": "My event destination",
    "description": "This is my event destination, I like it a lot",
    "type": "webhook_endpoint",
    "event_payload": "thin",
    "enabled_events": [
        "v1.billing.meter.error_report_triggered"
    ],
    "webhook_endpoint": {
        "url": "https://example.com/my/webhook/endpoint"
    }
  }'
```

> [Workbench](https://docs.stripe.com/workbench.md) remplace le [Dashboard des développeurs](https://docs.stripe.com/development/dashboard.md) existant. Si vous utilisez toujours le Dashboard des développeurs, découvrez comment [créer un point de terminaison webhook](https://docs.stripe.com/development/dashboard/webhooks.md).

## Sécuriser votre point de terminaison

Après avoir confirmé que votre point de terminaison fonctionne comme prévu, sécurisez la connexion en mettant en œuvre les [meilleures pratiques d’utilisation de webhooks](https://docs.stripe.com/webhooks.md#best-practices).

Sécurisez votre intégration en vous assurant que votre gestionnaire vérifie que toutes les demandes de point d’ancrage Web sont générées par Stripe. Vous pouvez vérifier les signatures de point d’ancrage Web à l’aide de nos bibliothèques officielles ou les vérifier manuellement.

#### Vérifier avec les bibliothèques officielles (recommandé)

### Vérifier les signatures de webhook avec les bibliothèques officielles

Nous vous recommandons d’utiliser nos bibliothèques officielles pour vérifier les signatures. Vous effectuez la vérification en fournissant les données utiles de l’événement, l’en-tête `Stripe-Signature` et la clé secrète du point de terminaison. Si la vérification échoue, vous recevrez une erreur.

Si vous obtenez une erreur de vérification de signature, consultez notre guide sur [la résolution de problème à ce sujet](https://docs.stripe.com/webhooks/signature.md).

> Stripe nécessite le corps brut de la requête pour effectuer la vérification de la signature. Si vous utilisez un cadre, assurez-vous qu’il ne manipule pas le corps brut. Toute manipulation du corps brut de la requête entraîne l’échec de la vérification.

#### 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('<<YOUR_SECRET_KEY>>')

require 'stripe'
require 'sinatra'

# 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 Dashboardendpoint_secret = 'whsec_...'

# Using the Sinatra framework
set :port, 4242

post '/my/webhook/url' do
  payload = request.body.readsig_header = request.env['HTTP_STRIPE_SIGNATURE']
  event = nil

  beginevent = Stripe::Webhook.construct_event(
      payload, sig_header, endpoint_secret
    )
  rescue JSON::ParserError => e
    # Invalid payload
    puts "Error parsing payload: #{e.message}"
    status 400
    return
  rescue Stripe::SignatureVerificationError => e# Invalid signature
    puts "Error verifying webhook signature: #{e.message}"
    status 400
    return
  end

  # Handle the event
  case event.type
  when 'payment_intent.succeeded'
    payment_intent = event.data.object # contains a Stripe::PaymentIntent
    puts 'PaymentIntent was successful!'
  when 'payment_method.attached'
    payment_method = event.data.object # contains a Stripe::PaymentMethod
    puts 'PaymentMethod was attached to a Customer!'
  # ... handle other event types
  else
    puts "Unhandled event type: #{event.type}"
  end

  status 200
end
```

#### Vérifier manuellement

### Vérifier manuellement les signatures de webhook

Il est recommandé d’utiliser nos bibliothèques officielles pour vérifier les signatures d’un événement webhook, cependant vous pouvez créer une solution personnalisée en suivant les explications de cette section.

L’en-tête `Stripe-Signature` inclus dans chaque événement signé contient un horodatage et une ou plusieurs signatures que vous devez vérifier. L’horodatage a un préfixe `t=` et chaque signature a un préfixe *scheme*. Les schémas commencent par `v`, suivi d’un nombre entier. Actuellement, le seul schéma de signature valide en mode production est `v1`. Pour faciliter les tests, Stripe envoie une signature supplémentaire avec un faux schéma `v0` pour les événements en mode test.

```
Stripe-Signature:
t=1492774577,
v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd,
v0=6ffbb59b2300aae63f272406069a9788598b792a944a07aba816edb039989a39
```

> Nous fournissons des sauts de ligne pour plus de clarté, mais un véritable en-tête `Stripe-Signature` est sur une seule ligne.

Stripe génère des signatures en utilisant un code d’authentification de message ([HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code)) basé sur le hachage avec [SHA-256](https://en.wikipedia.org/wiki/SHA-2). Pour éviter les [attaques par repli](https://en.wikipedia.org/wiki/Downgrade_attack), ignorez tous les schémas autres que `v1`.

Vous pouvez avoir plusieurs signatures avec la même paire schéma-clé secrète. Cela peut se produire lorsque vous [échangez la clé secrète d’un point de terminaison](https://docs.stripe.com/webhooks.md#roll-endpoint-secrets) et que vous choisissez de garder la clé secrète précédente active pendant un maximum de 24&nbsp;heures. Pendant cette période, votre point de terminaison a plusieurs clés secrètes actives et Stripe génère une signature pour chacune d’elle.

Pour créer une solution manuelle de vérification des signatures, vous devez suivre les étapes suivantes&nbsp;:

#### Étape 1&nbsp;: Effectuez l’extraction de l’horodatage et des signatures de l’en-tête

Divisez l’en-tête, en utilisant le caractère `,` comme séparateur, pour obtenir une liste d’éléments. Divisez ensuite chaque élément, en utilisant le caractère `=` comme séparateur, pour obtenir un préfixe et une paire de valeurs.

La valeur pour le préfixe `t` correspond à l’horodatage, et celle de `v1` correspond à la signature (ou les signatures). Vous pouvez ignorer tous les autres éléments.

#### Étape 2&nbsp;: Préparez la chaîne `signed_payload`

La chaîne `signed_payload` est créée par la concaténation des éléments suivants&nbsp;:

- L’horodatage (sous forme de chaîne)
- Le caractère `.`
- La charge utile JSON réelle (c.-à-d. le contenu de la requête)

#### Étape 3&nbsp;: Déterminez la signature attendue

Calculez un HMAC avec la fonction de hachage SHA256. Utilisez la clé secrète de signature du point de terminaison comme clé, et utilisez la chaîne `signed_payload` comme message.

#### Étape 4&nbsp;: Comparez les signatures

Comparez la signature (ou les signatures) dans l’en-tête avec la signature attendue. En cas de correspondance, calculez la différence entre l’horodatage actuel et l’horodatage reçu, puis décidez si la différence se trouve dans les limites de votre tolérance.

En prévention des attaques temporelles, utilisez une comparaison de chaînes de temps constantes pour comparer la signature attendue à chacune des signatures reçues.

## Déboguer les intégrations de webhooks

Plusieurs types de problèmes peuvent survenir lors de l’envoi d’événements à votre point de terminaison de webhook&nbsp;:

- Il est possible que Stripe ne soit pas en mesure d’envoyer un événement à votre point de terminaison de webhook.
- Votre point de terminaison de webhook peut avoir un problème SSL.
- Votre connexion réseau est intermittente.
- Votre point de terminaison de webhook ne reçoit pas les événements que vous vous attendez à recevoir.

### Afficher les envois d’événements

Pour afficher les envois d’événements, sélectionnez le point de terminaison de point d’ancrage Web sous **points d’ancrage Web**, puis sélectionnez l’onglet **événements**. l’onglet **événements** fournit une liste d’événements et indique s’ils sont `envoyé`, `en attente` ou `échoué`. Cliquez sur un événement pour afficher les métadonnées, y compris le code d’état http de la tentative d’envoi et l’heure des envois futurs en attente.

Vous pouvez également utiliser [l’interface de ligne de commande Stripe](https://docs.stripe.com/stripe-cli.md) pour [écouter des événements](https://docs.stripe.com/webhooks.md#test-webhook) directement dans votre terminal.

### Corriger des codes d’état HTTP

Lorsqu’un événement affiche un code d’état de `200`, il indique qu’un envoi a été effectué au point de terminaison de webhook. Vous pourriez également recevoir un code d’état autre que `200`. Consultez le tableau ci-dessous pour obtenir une liste des codes d’état HTTP courants et des solutions recommandées.

| État du webhook en attente          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Corriger                                                                                                                                 |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| (Connexion impossible) ERR          | Nous ne parvenons pas à établir une connexion au serveur de destination.                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Assurez-vous que votre domaine hôte est accessible au public sur Internet.                                                               |
| (`302`) ERR (ou autre statut `3xx`) | Le serveur de destination a tenté de rediriger la requête vers un autre emplacement. Nous considérons les réponses aux requêtes webhook comme des échecs.                                                                                                                                                                                                                                                                                                                                                                                          | Définissez la destination du point de terminaison du webhook sur l’URL déterminée par la redirection.                                    |
| (`400`) ERR (ou autre état `4xx`)   | Le serveur de destination ne peut traiter ou ne traite pas la requête. Cela peut se produire lorsque le serveur détecte une erreur (`400`), lorsque l’adresse URL de destination comporte des restrictions d’accès (`401`, `403`), ou lorsque l’URL de destination n’existe pas (`404`).                                                                                                                                                                                                                                                           | Assurez-vous que votre point de terminaison est accessible publiquement sur Internet et qu’il accepte la méthode HTTP POST.              |
| (`500`) ERR (ou autre statut `5xx`) | Une erreur est survenue sur le serveur de destination lors du traitement de la requête.                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Passez en revue les journaux de votre application pour comprendre pourquoi elle renvoie une erreur `500`.                                |
| (erreur TLS) ERR                    | Nous n’avons pas pu établir de connexion sécurisée au serveur de destination. Les problèmes liés au certificat SSL/TLS ou à un certificat intermédiaire dans la chaîne de certificats du serveur de destination sont généralement à l’origine de ces erreurs. Stripe exige la version *TLS* (TLS refers to the process of securely transmitting data between the client—the app or browser that your customer is using—and your server. This was originally performed using the SSL (Secure Sockets Layer) protocol) version `v1.2` ou ultérieure. | Effectuez un [test de serveur SSL](https://www.ssllabs.com/ssltest/) pour détecter les problèmes susceptibles de provoquer cette erreur. |
| (Expiré) ERR                        | Le serveur de destination a mis trop de temps à répondre à la demande du webhook.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Assurez-vous de différer la logique complexe et à renvoyer immédiatement une réponse réussie dans votre code de gestion de webhook.      |

## Comportements d’envoi d’événements

Cette section vous aide à comprendre les différents comportements à attendre concernant la façon dont Stripe envoie les événements à votre point de terminaison de webhook.

### Relances automatiques

Stripe tente d’envoyer des événements à votre destination pendant un maximum de trois jours avec un délai exponentiel en mode production. Affichez la date de la prochaine tentative, le cas échéant, dans l’onglet **Événements envoyés** de votre destination d’événement. Nous tentons de renvoyer les événements créés dans un bac à sable trois fois au cours de quelques heures. Si votre destination a été désactivée ou supprimée lorsque nous effectuons une nouvelle tentative, nous empêcherons toute nouvelle tentative d’envoi de cet événement. Toutefois, si vous désactivez, puis réactivez la destination de l’événement avant que nous puissions réessayer, d’autres tentatives seront toujours possibles.

### Relances manuelles

Vous pouvez retenter manuellement l’envoi d’événements de deux manières différentes&nbsp;:

- Dans le Dashboard Stripe, cliquez sur **Renvoyer** lorsque vous consultez un événement spécifique. Cela fonctionne jusqu’à 15&nbsp;jours après la création de l’événement.
- À l’aide de l’[interface de ligne de commande de Stripe](https://docs.stripe.com/cli/events/resend), exécutez la commande `stripe events resend <event_id> --webhook-endpoint=<endpoint_id>`. Cela fonctionne jusqu’à 30&nbsp;jours après la création de l’événement.

Renvoyer manuellement un événement qui a connu des échecs de livraison à un point de terminaison d’ancrage n’annule pas le[comportement de relance automatique de Stripe](https://docs.stripe.com/webhooks.md#automatic-retries), même si cela donne un code d’état`2xx`. Découvrez comment [traiter les événements d’ancrage non transmis](https://docs.stripe.com/webhooks/process-undelivered-events.md) pour empêcher les futures relances.

### Commande d’événements

Stripe ne garantit pas que les événements sont envoyés dans l’ordre dans lequel ils ont été générés. Par exemple, la création d’un abonnement peut générer les événements suivants&nbsp;:

- `customer.subscription.created`
- `invoice.created`
- `invoice.paid`
- `charge.created` (si un paiement existe)

Assurez-vous que la destination de votre événement ne dépend pas de la réception d’événements dans un ordre particulier. Soyez prêt à gérer leur envoi de manière appropriée. Vous pouvez également utiliser l’API pour récupérer tout objet manquant. Par exemple, vous pourrez récupérer les objets relatifs à la facture, le paiement et l’abonnement avec les informations de `invoice.paid` si vous recevez cet événement en premier.

### Contrôle de version de l’API

La version de l’API, et par extension la structure d’un objet [Event](https://docs.stripe.com/api/events.md) envoyé à votre destination lorsque l’événement survient, dépend de la version indiquée dans les paramètres de votre compte. Par exemple, si votre compte utilise une ancienne version d’API, comme 2015-02-16, et que vous modifiez la version de l’API pour une requête particulière avec [le contrôle de version](https://docs.stripe.com/api.md#versioning), l’objet [Event](https://docs.stripe.com/api/events.md) généré et envoyé à votre destination est toujours fondé sur la version de l’API 2015-02-16. Vous ne pouvez pas modifier les objets [Event](https://docs.stripe.com/api/events.md) une fois qu’ils ont été créés. Par exemple, si vous mettez à jour un paiement, l’événement de paiement d’origine reste inchangé. Par conséquent, les mises à jour apportées par la suite à la version de l’API de votre compte ne modifient pas de manière rétroactive les objets [Event](https://docs.stripe.com/api/events.md) existants. La récupération d’un ancien [Event](https://docs.stripe.com/api/events.md) en appelant `/v1/events` à l’aide d’une version récente de l’API n’a pas non plus de conséquence sur la structure de l’événement reçu. Vous pouvez définir les destinations des événements de test en fonction de la version de votre API par défaut ou de la version la plus récente de l’API. L’objet [Event](https://docs.stripe.com/api/events.md) envoyé à la destination est structuré en fonction de la version précisée pour la destination de l’événement.

## Bonnes pratiques pour l’utilisation des webhooks

Vérifiez les bonnes pratiques suivantes pour vous assurer que vos points de terminaison de webhooks restent sécurisés et fonctionnent correctement au sein de votre intégration.

### Gérer les événements en double

Les points de terminaison Webhook peuvent parfois recevoir plusieurs fois le même événement. Vous pouvez vous prémunir contre ce phénomène en enregistrant les [ID d’événements](https://docs.stripe.com/api/events/object.md#event_object-id) que vous avez traités et en ne traitant pas les événements déjà enregistrés.

Dans certains cas, deux objets Event distincts sont générés et envoyés. Pour identifier ces doublons, utilisez l’ID de l’objet dans `data.object` avec `event.type`.

### Écoutez uniquement les types d’événements nécessaires à votre intégration

Configurez vos points de terminaison de webhook de sorte à ne recevoir que les types d’événements nécessaires à votre intégration. L’écoute d’événements supplémentaires (ou de tous les événements) alourdit inutilement la charge de votre serveur, c’est pourquoi nous ne le recommandons pas.

Vous pouvez [modifier les événements](https://docs.stripe.com/api/webhook_endpoints/update.md#update_webhook_endpoint-enabled_events) qu’un point de terminaison de webhook reçoit dans le Dashboard ou à l’aide de l’API.

### Gérer les événements de manière asynchrone

Configurez votre gestionnaire pour traiter les événements entrants avec une file d’attente asynchrone. Vous pouvez rencontrer des problèmes d’évolutivité si vous choisissez de traiter les événements de manière synchrone. Toute augmentation importante des envois de webhooks (par exemple, au début du mois, lorsque tous les abonnements sont renouvelés) pourrait submerger les hôtes de vos points de terminaison.

Les files d’attente asynchrones vous permettent de traiter les événements simultanés à un rythme que votre système peut prendre en charge.

### Chemin de webhook exempté de la protection CSRF

Si vous utilisez Rails, Django ou un autre cadre Web, votre site peut vérifier automatiquement que chaque requête POST contient un jeton *CSRF token*. Cette mesure de sécurité importante vous protège vous et vos utilisateurs des tentatives de [falsification de requête intersites](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_\(CSRF\)). Toutefois, elle peut également empêcher votre site de traiter des événements légitimes. Dans ce cas, vous devrez peut-être exempter le chemin des webhooks de cette protection CSRF.

#### Rails

```ruby
class StripeController < ApplicationController
  # If your controller accepts requests other than Stripe webhooks,
  # you'll probably want to use `protect_from_forgery` to add CSRF
  # protection for your application. But don't forget to exempt
  # your webhook route!
  protect_from_forgery except: :webhook

  def webhook
    # Process webhook data in `params`
  end
end
```

### Recevoir des événements avec un serveur HTTPS

Si vous utilisez une URL HTTPS pour votre point de terminaison de webhook (obligatoire en mode production), Stripe vérifiera que la connexion à votre serveur est sécurisée avant d’envoyer les données de votre webhook. Pour que ce processus fonctionne, votre serveur doit être configuré de sorte à prendre en charge le protocole HTTPS et disposer d’un certificat de serveur valide. Les webhooks de Stripe prennent en charge uniquement le protocole*TLS* (TLS refers to the process of securely transmitting data between the client—the app or browser that your customer is using—and your server. This was originally performed using the SSL (Secure Sockets Layer) protocol), versions v.1.2 et v1.3.

### Échangez périodiquement les clés secrètes de signature des points de terminaison

La clé secrète utilisée pour vérifier que les événements proviennent de Stripe est modifiable dans l’onglet **Webhooks** de Workbench. Pour assurer leur sécurité, nous vous recommandons d’échanger (ou de modifier) les clés secrètes périodiquement, ou lorsque vous soupçonnez que l’une d’entre elles est compromise.

Pour échanger une clé secrète&nbsp;:

1. Cliquez sur chaque point de terminaison dans l’onglet **Webhooks** de Workbench pour lequel vous souhaitez échanger la clé secrète.
1. Accédez au menu de débordement (⋯) et cliquez sur **Nouvelle clé secrète**. Vous pouvez choisir de faire expirer immédiatement la clé secrète actuelle ou de retarder son expiration jusqu’à 24&nbsp;heures pour vous donner le temps de mettre à jour le code de vérification sur votre serveur. Pendant ce temps, plusieurs clés secrètes sont actives pour le point de terminaison. Stripe génère une signature par clé secrète jusqu’à expiration.

### Vérifier que les événements sont envoyés par Stripe

Sans vérification, un pirate pourrait envoyer de faux événements de point d’ancrage Web à votre point de terminaison afin de déclencher des actions telles que l’exécution de commandes, l’octroi d’un accès à un compte ou la modification d’enregistrements. Vérifiez toujours que les événements de point d’ancrage Web proviennent bien de Stripe avant d’y donner suite.

Utilisez ces deux protections&nbsp;:

- **Liste d’autorisation d’adresses&nbsp;IP**&nbsp;: Stripe envoie des événements de point d’ancrage Web à partir d’une liste prédéfinie d’[adresses&nbsp;IP](https://docs.stripe.com/ips.md). Configurez votre serveur ou votre pare-feu pour qu’il n’accepte que les requêtes de point d’ancrage Web provenant de ces adresses.
- **Vérification de la signature**&nbsp;: Stripe signe chaque événement de point d’ancrage Web en incluant une signature dans l’en-tête `Stripe-Signature`. Vérifiez cette signature à l’aide de nos [bibliothèques officielles](https://docs.stripe.com/webhooks.md#verify-official-libraries) ou [manuellement](https://docs.stripe.com/webhooks.md#verify-manually) afin de confirmer que l’événement n’a pas été envoyé ou modifié par un tiers.

La section suivante décrit comment vérifier les signatures de webhook&nbsp;:

1. Récupérez la clé secrète de votre point de terminaison.
1. Vérifiez la signature.

#### Récupération de la clé secrète de votre point de terminaison

Utilisez Workbench et accédez à l’onglet **&nbsp;Points d’ancrage web&nbsp;** pour afficher tous vos points de terminaison. Sélectionnez un point de terminaison pour lequel vous souhaitez obtenir la clé secrète, puis cliquez sur **&nbsp;Cliquer pour révéler&nbsp;**.

Stripe génère une clé secrète unique pour chaque point de terminaison. Si vous utilisez le même point de terminaison pour les [clés API de test et de production](https://docs.stripe.com/keys.md#test-live-modes), la clé secrète sera différente pour chacun. De plus, si vous utilisez plusieurs points de terminaison, vous devrez obtenir une clé secrète pour chaque point de terminaison dont vous voulez vérifier les signatures. Après cette configuration, Stripe commencera à signer chaque webhook qu’il envoie au point de terminaison.

### Prévention des attaques par réinsertion

Une [attaque par réinsertion](https://en.wikipedia.org/wiki/Replay_attack) se produit lorsqu’un attaquant intercepte une charge utile valide et sa signature, puis les retransmet. Pour éviter ces attaques, Stripe inclut un horodatage dans l’en-tête `Stripe-Signature`. Étant donné que cet horodatage fait partie de la charge utile signée, il est également vérifié par la signature, de sorte qu’un attaquant ne peut pas modifier l’horodatage sans invalider la signature. Si la signature est valide, mais que l’horodatage est trop ancien, vous pouvez demander à votre application de rejeter la charge utile.

Nos bibliothèques ont une tolérance par défaut de cinq minutes entre l’horodatage et l’heure actuelle. Vous pouvez modifier cette tolérance en fournissant un paramètre supplémentaire lors de la vérification des signatures. Utilisez le protocole de synchronisation de réseau ([NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol)) pour vous assurer que l’horloge de votre serveur est précise et synchronisée avec l’heure des serveurs de Stripe.

> N’utilisez pas une valeur de tolérance de `0`. L’utilisation d’une valeur de tolérance de `0` désactive entièrement le contrôle de récence.

Stripe génère l’horodatage et la signature chaque fois que nous envoyons un événement à votre point de terminaison. Si Stripe tente à nouveau d’envoyer un événement (par exemple, si votre point de terminaison a précédemment répondu avec un code d’état autre que `2xx`), nous générerons une nouvelle signature et un nouvel horodatage pour la nouvelle tentative d’envoi.

### Renvoyer rapidement une réponse 2xx

Votre [point de terminaison](https://docs.stripe.com/webhooks.md#example-endpoint) doit renvoyer rapidement un code d’état réussi (`2xx`) avant toute logique complexe qui pourrait provoquer une expiration du délai imparti. Par exemple, vous devez renvoyer une réponse `200` avant de mettre à jour la facture d’un client comme étant payée dans votre système de comptabilité.

## See also

- [Envoyer des événements sur Amazon EventBridge](https://docs.stripe.com/event-destinations/eventbridge.md)
- [Envoyer des événements à Azure Event Grid](https://docs.stripe.com/event-destinations/eventgrid.md)
- [Liste des types d’événements légers](https://docs.stripe.com/api/v2/core/events/event-types.md)
- [Liste des types d’événements instantanés](https://docs.stripe.com/api/events/.md)
- [Outil interactif pour la création de point de terminaison de webhook](https://docs.stripe.com/webhooks/quickstart.md)
