# Receba eventos da Stripe no seu endpoint de webhook

Fique atento aos eventos da Stripe no seu endpoint do Webhook para que sua integração possa acionar reações automaticamente.

Você pode criar um endpoint de webhook HTTPS para receber eventos. Após registrar um endpoint de webhook, a Stripe envia dados em tempo real para ele quando [eventos](https://docs.stripe.com/event-destinations.md#events-overview) ocorrem em sua conta Stripe. A Stripe utiliza HTTPS para enviar eventos de webhook para seu aplicativo como um payload JSON que inclui informações sobre o evento.

Receber eventos de webhook ajuda você a responder a eventos assíncronos, como quando o banco de um cliente confirma um pagamento, um cliente contesta uma cobrança ou um pagamento recorrente é realizado.

Você também pode consumir eventos da Stripe em sua infraestrutura AWS ou Azure enviando eventos diretamente para o [Amazon EventBridge](https://docs.stripe.com/event-destinations/eventbridge.md) ou para o [Azure Event Grid](https://docs.stripe.com/event-destinations/eventgrid.md).

Conclua as etapas abaixo para começar a receber eventos de webhook em seu aplicativo. Você pode registrar e criar um único endpoint para processar diversos tipos de eventos simultaneamente ou configurar endpoints individuais para eventos específicos.

## Configure seu endpoint

Utilize a [API](https://docs.stripe.com/api/v2/event-destinations.md) ou a guia [Webhooks](https://dashboard.stripe.com/webhooks) no Workbench para registrar a URL acessível do seu endpoint de webhook, para que a Stripe saiba onde entregar os eventos. Você pode registrar até 16 endpoints de webhook na Stripe. Os endpoints de webhook registrados devem ser URLs HTTPS publicamente acessíveis.

- Se você possui um servidor localhost, mas não dispõe de uma URL HTTPS publicamente acessível, pode utilizar uma ferramenta de tunelamento como o [ngrok](https://ngrok.com/) para gerar uma URL HTTPS pública temporária para fins de teste.
- Como alternativa, você pode [testar localmente usando o Stripe CLI](https://docs.stripe.com/webhooks.md#local-listener) antes de registrar uma URL HTTPS publicamente acessível.

### Formato de URL de webhook

O formato de URL para registrar um endpoint de webhook é:

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

Por exemplo, se seu domínio for `https://mycompanysite.com` e a rota para seu endpoint de webhook for `@app.route('/stripe_webhooks', methods=['POST'])`, especifique `https://mycompanysite.com/stripe_webhooks` como a URL do endpoint.

### Crie um destino de evento para seu endpoint de webhook

#### Dashboard

Para criar um novo endpoint de webhook no Dashboard:

1. Abra a guia [Webhooks](https://dashboard.stripe.com/webhooks) no Workbench.
2. Clique em **Criar um destino de evento**.
3. Selecione **Sua conta** para escutar eventos da sua própria conta.
4. Selecione a versão da API para o [objeto de eventos](https://docs.stripe.com/api/events.md) que deseja consumir.
5. Selecione os [tipos de eventos](https://docs.stripe.com/api/events/types.md) que deseja enviar para um endpoint de webhook.
6. Selecione **Continuar** e, em seguida, selecione **Endpoint de webhook** como o tipo de destino.
7. Clique em **Continuar**, depois forneça a **URL do endpoint** e uma descrição opcional para o webhook.
8. Na página de configurações do webhook, aparece um segredo de assinatura iniciado por `whsec_`. Clique em **Revelar segredo** e copie o valor para utilizar ao [criar um manipulador](https://docs.stripe.com/webhooks.md#webhook-endpoint-def).

> O [Workbench](https://docs.stripe.com/workbench.md) substitui o atual [Dashboard de Desenvolvedores](https://docs.stripe.com/development/dashboard.md). Você ainda pode [criar um novo endpoint de webhook](https://docs.stripe.com/development/dashboard/webhooks.md) no Dashboard de Desenvolvedores, embora recomendemos o uso do Workbench.

#### API

Utilize o endpoint [/v2/core/event_destinations](https://docs.stripe.com/api/v2/event-destinations.md) para registrar um novo endpoint.

#### Eventos de instantâneos

Para escutar [eventos de snapshot](https://docs.stripe.com/api/events/types.md) de sua própria conta, defina o valor [event_payload](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-event_payload) como `snapshot` e o valor [enabled_events](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-enabled_events) como os tipos de eventos que deseja enviar para o endpoint de webhook:

```curl
curl -X POST https://api.stripe.com/v2/core/event_destinations \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-08-26.preview" \
  --json '{
    "name": "My event destination",
    "type": "webhook_endpoint",
    "events_from": [
        "@self"
    ],
    "event_payload": "snapshot",
    "enabled_events": [
        "payment_intent.succeeded",
        "payment_intent.payment_failed"
    ],
    "webhook_endpoint": {
        "url": "https://mycompanysite.com/webhook"
    },
    "include": [
        "webhook_endpoint.signing_secret"
    ]
  }'
```

A saída contém um valor `webhook_endpoint.signing_secret` que começa com `whsec_`. Copie esse valor para utilizar ao [criar um manipulador](https://docs.stripe.com/webhooks.md#webhook-endpoint-def).

#### Eventos thin

Se você estiver utilizando [eventos thin](https://docs.stripe.com/api/v2/core/events/event-types.md), será necessário registrar um endpoint de webhook separado. Saiba mais sobre [as diferenças entre eventos thin e snapshot](https://docs.stripe.com/event-destinations.md#events-overview).

Para escutar [eventos thin](https://docs.stripe.com/api/v2/core/events/event-types.md) a partir da sua própria conta, defina o valor de [event_payload](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-event_payload) como `thin` e o valor de [enabled_events](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-enabled_events) para os tipos de evento que deseja enviar ao endpoint de webhook:

```curl
curl -X POST https://api.stripe.com/v2/core/event_destinations \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-08-26.preview" \
  --json '{
    "name": "My event destination",
    "type": "webhook_endpoint",
    "events_from": [
        "@self"
    ],
    "event_payload": "thin",
    "enabled_events": [
        "v1.billing.meter.error_report_triggered"
    ],
    "webhook_endpoint": {
        "url": "https://mycompanysite.com/webhook"
    },
    "include": [
        "webhook_endpoint.signing_secret"
    ]
  }'
```

A saída contém um valor `webhook_endpoint.signing_secret` que começa com `whsec_`. Copie esse valor para utilizar ao [criar um manipulador](https://docs.stripe.com/webhooks.md#webhook-endpoint-def).

### Testar localmente sem uma URL registrada

Se você não possui uma URL HTTPS registrada e acessível publicamente, é possível testar webhooks localmente utilizando a Stripe CLI para [encaminhar eventos ao seu endpoint local](https://docs.stripe.com/cli/use-cli#forward-events-to-your-local-webhook-endpoint):

1. Se ainda não fez isso, [instale a Stripe CLI](https://docs.stripe.com/cli/install) em sua máquina.

2. Acesse sua conta Stripe e configure a CLI executando `stripe login` na linha de comando.

3. Permita que seu host local receba um evento simulado executando [stripe listen](https://docs.stripe.com/cli/listen), conforme o escopo e o tipo de evento:

   #### Encaminhar eventos de instantâneo

   Utilize o seguinte comando para encaminhar [eventos snapshot](https://docs.stripe.com/event-destinations.md#events-overview) da sua conta para seu listener local.

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

   #### Encaminhar eventos mínimos

   Utilize o seguinte comando para encaminhar [eventos thin](https://docs.stripe.com/event-destinations.md#events-overview) da sua conta para seu listener local.

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

   Este comando pressupõe que você possui um site em localhost na porta 4242 com um endpoint `POST /webhook`, que pode ser configurado ao [criar um handler](https://docs.stripe.com/webhooks.md#webhook-endpoint-def).

4. O comando `stripe listen` exibe o `{{WEBHOOK_SIGNING_SECRET}}`. Copie este valor para utilizar ao [criar um handler](https://docs.stripe.com/webhooks.md#webhook-endpoint-def).

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

> Para utilizar o argumento `--forward-to` com o `stripe listen`, é necessário executar o comando com a [Stripe CLI](https://docs.stripe.com/cli.md) em um terminal. Este comando não pode ser executado no [Workbench Shell](https://docs.stripe.com/workbench/shell.md), pois ele não oferece suporte ao argumento `--forward-to`.

## Crie um gerenciador

Configure uma função de HTTP ou HTTPS que aceite solicitações de webhooks com um método POST. Se você ainda está desenvolvendo a função de endpoint em uma máquina local, pode ser HTTP. Quando o endpoint for público, terá de ser HTTPS.

Utilize a referência da API da Stripe para identificar os [objetos de evento thin](https://docs.stripe.com/api/v2/core/events/event-types.md) ou [objetos de evento snapshot](https://docs.stripe.com/api/events/types.md) que o handler do seu webhook precisa processar.

Configure sua função de endpoint para que:

- Processa solicitações POST com um payload JSON que inclui informações do evento.
- Verifica se a solicitação do webhook foi gerada pela Stripe utilizando o payload JSON, o header `Stripe-Signature` e o segredo de assinatura do webhook `whsec_` da etapa anterior. Se a verificação falhar, será exibido um erro.
- Retorna rapidamente um código de status bem-sucedido (`2xx`) antes de qualquer lógica complexa que possa causar timeout. Por exemplo, é necessário retornar uma resposta `200` antes de atualizar a fatura de um cliente como paga em seu sistema contábil.

> #### Não manipule o corpo bruto da solicitação
> 
> A Stripe exige o corpo bruto da solicitação para realizar a verificação de assinatura. Se estiver usando uma estrutura, assegure-se de que ela não manipule o corpo bruto. Qualquer manipulação no corpo bruto da solicitação causa falha na verificação.
> 
> Saiba como [solucionar erros de verificação de assinatura](https://docs.stripe.com/webhooks/signature.md).

#### Exemplo de endpoint

Este snippet de código é uma função de webhook configurada para verificar eventos recebidos de uma conta Stripe, gerenciar os eventos e retornar respostas `200`. Faça referência ao gerenciador de eventos de [instantâneo](https://docs.stripe.com/event-destinations.md#events-overview) quando usar recursos da API v1 e faça referência ao gerenciador de eventos [mínimos](https://docs.stripe.com/event-destinations.md#events-overview) quando usar recursos da API v2.

#### Gerenciador de eventos de instantâneo

Ao criar um gerenciador de eventos de instantâneo, use a definição do objeto da API no momento do evento da sua lógica acessando os campos `data.object` do evento. Você também pode recuperar o recurso de API na API da Stripe para acessar a definição de objeto mais recente e atualizada.

#### 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
```

#### Manipulador de eventos finos (Clover+)

Ao criar um manipulador de eventos thin, use o método `fetchRelatedObject()` para recuperar a versão mais recente do objeto associado ao evento. Os eventos podem conter [dados adicionais](https://docs.stripe.com/event-destinations.md#fetch-data) que só podem ser recuperados por meio do método da instância `.fetchEvent()` em `EventNotification`. A forma exata desses dados depende do `type` do evento.

Os tipos de eventos devem estar disponíveis no momento do lançamento para gerar classes nessa versão do SDK. Para lidar com eventos para os quais o SDK não tem classes, use a 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
```

## Testar seu gerenciador

Antes de lançar a função do endpoint de webhook, recomendamos testar a integração da sua aplicação disparando eventos em uma área restrita ou enviando eventos de teste com a [Stripe CLI](https://docs.stripe.com/cli.md).

### Disparar eventos de teste

Para enviar eventos de teste, acione um tipo de evento no qual seu destino de evento seja assinante ao criar manualmente um objeto no Stripe Dashboard. Saiba como acionar eventos com o [Stripe for VS Code](https://docs.stripe.com/stripe-vscode.md).

#### Acionar um evento de instantâneo

Você pode usar o seguinte comando no [Stripe Shell](https://docs.stripe.com/workbench/shell.md) ou na [Stripe CLI](https://docs.stripe.com/cli.md). Este exemplo aciona um evento `payment_intent.succeeded`:

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

#### Acionar um evento mínimo

Você pode usar o comando a seguir no [Stripe CLI](https://docs.stripe.com/cli.md). Este exemplo aciona um evento `v1.billing.meter.error_report_triggered`:

```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.
```

## Optional: Crie um destino de eventos para o Connect

Ao [criar um destino de eventos](https://docs.stripe.com/webhooks.md#create-webhook-endpoint) como uma plataforma Connect, você escolhe qual escopo ele irá escutar:

#### Dashboard

- **Sua conta**: eventos provenientes de recursos na sua conta.
- **Contas conectadas**: eventos provenientes de recursos que pertencem às suas contas conectadas.

#### API

- [events_from=[“@self”]](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-events_from): eventos provenientes de recursos na sua conta.
- [events_from=[“@accounts”]](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-events_from): eventos provenientes de recursos que pertencem às suas contas conectadas.

Registre um destino de eventos para **Contas conectadas** para receber eventos de recursos que pertencem às suas contas conectadas. Exemplos incluem [direct charges](https://docs.stripe.com/connect/direct-charges.md), clientes e das formas de pagamento das contas conectadas, falhas de repasse e atualizações legadas do ciclo de vida das contas conectadas, como onboarding, verificação, alterações de conta e desconexão de contas. Para o Accounts v2, esse escopo recebe apenas eventos snapshot para objetos Account que representam suas contas conectadas.

Dependendo da sua integração com o Connect, pode ser necessário também registrar um destino de eventos para **Sua conta**. Os motivos incluem:

- Processamento de eventos de recursos na conta da sua plataforma, incluindo clientes da plataforma, cobranças de propriedade da plataforma, [destination charges](https://docs.stripe.com/connect/destination-charges.md) e [cobranças e transferências separadas](https://docs.stripe.com/connect/separate-charges-and-transfers.md).
- Processamento de thin events referentes a objetos do Accounts v2 que representam contas conectadas.

Consulte [webhooks do Connect](https://docs.stripe.com/connect/webhooks.md?accounts-namespace=v2) para mais detalhes.

### Teste o Connect localmente sem uma URL registrada

#### Eventos de instantâneos

Use o comando a seguir para encaminhar [eventos snapshot](https://docs.stripe.com/event-destinations.md#events-overview) de contas conectadas para o seu listener local.

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

#### Eventos thin

Use o comando a seguir para encaminhar [thin events](https://docs.stripe.com/event-destinations.md#events-overview) de contas conectadas para o seu listener local.

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

## Optional: Crie um destino de eventos para Organizações

Ao [criar um destino de eventos](https://docs.stripe.com/webhooks.md#create-webhook-endpoint) como uma Organização, você escolhe qual escopo ele irá escutar:

#### Dashboard

- **Contas na sua organização**: eventos provenientes de recursos nas contas da sua organização.
- **Contas conectadas**: eventos provenientes de recursos dentro das contas conectadas da sua organização.

#### API

- [events_from=[“@organization_members”]](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-events_from): eventos provenientes de recursos nas contas da sua organização.
- [events_from=[“@organization_members/@accounts”]](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-events_from): eventos provenientes de recursos dentro das contas conectadas da sua organização.

### Comportamentos de tipo de evento não aceitos para destinos de evento da organização

A Stripe envia a maioria dos tipos de evento de forma assíncrona, mas aguarda uma resposta para alguns tipos de evento. Nesses casos, a Stripe se comporta de maneira diferente dependendo se o destino do evento responde.

Se o destino do seu evento receber eventos da [Organização](https://docs.stripe.com/get-started/account/orgs.md), os que precisam de uma resposta têm as seguintes limitações:

- Não é possível assinar `issuing_authorization.request` para destinos de organização. Configure um [endpoint de webhook](https://docs.stripe.com/webhooks.md#example-endpoint) em uma conta Stripe dentro da organização para assinar esse tipo de evento. Use `issuing_authorization.request` para autorizar solicitações de compra em tempo real.
- Os destinos da organização que recebem `checkout_sessions.completed` não conseguem [lidar com o comportamento de redirecionamento](https://docs.stripe.com/checkout/fulfillment.md#redirect-hosted-checkout) quando você incorpora o [Checkout](https://docs.stripe.com/payments/checkout.md) diretamente no seu site ou redireciona clientes para uma página de pagamento hospedada na Stripe. Para influenciar o comportamento de redirecionamento do Checkout, processe esse tipo de evento com um [endpoint de webhook](https://docs.stripe.com/webhooks.md#example-endpoint) configurado em uma conta Stripe na organização.
- Destinos da organização que não respondem com sucesso a um evento `invoice.created` não podem influenciar a [finalização automática da fatura ao usar a cobrança automática](https://docs.stripe.com/billing/subscriptions/webhooks.md#understand). Você deve processar esse tipo de evento com um [endpoint de webhook](https://docs.stripe.com/webhooks.md#example-endpoint) configurado em uma conta Stripe na organização para acionar a finalização automática da fatura.

#### Usando `context`

#### Eventos de instantâneos

Este snippet de código é uma função de webhook configurada para verificar eventos recebidos, detectar a conta de origem, se aplicável, gerenciar o evento e retornar uma resposta `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
```

#### Manipulador de eventos finos (Clover+)

Use a propriedade `context` do `EventNotification`para identificar a conta para eventos em sua [organização](https://docs.stripe.com/get-started/account/orgs.md). Você deve definir o [cabeçalho Stripe-Context](https://docs.stripe.com/context.md) manualmente para todas as chamadas API, exceto `.fetchRelatedObject()` e `.fetchEvent()`, que fazem isso automaticamente.

#### 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)
```

## Depurar integrações de webhooks

Vários tipos de problemas podem ocorrer na entrega de eventos ao endpoint de webhook:

- A Stripe pode não conseguir entregar um evento ao endpoint de webhook.
- O endpoint de webhook pode ter um problema de SSL.
- A conectividade de rede é intermitente.
- O endpoint de webhook não está recebendo os eventos que você espera receber.

### Ver entregas de eventos

Para ver as entregas de eventos, abra o [Workbench](https://docs.stripe.com/workbench.md), selecione o endpoint de webhook em **Webhooks**, selecione a aba **Entregas de eventos**. A aba **Entregas de Eventos** exibe uma lista de eventos e se eles estão `Delivered`, `Pending` ou `Failed`. Clique em um evento para visualizar os metadados, incluindo o código de status HTTP da tentativa de entrega e o horário das entregas futuras pendentes.

Você também pode usar a [CLI da Stripe](https://docs.stripe.com/cli.md) para [ouvir eventos](https://docs.stripe.com/webhooks.md#test-webhook) diretamente no seu terminal.

### Corrigir códigos de status HTTP

Quando um evento exibe um código de status `200`, isso indica uma entrega bem-sucedida ao endpoint do webhook. Você também pode receber um código de status diferente de `200`. Veja na tabela abaixo uma lista de códigos de status HTTP comuns e as soluções recomendadas.

| Status do webhook pendente | Descrição | Correção |
| --- | --- | --- |
| ERRO (Não foi possível conectar) | Não conseguimos estabelecer uma conexão com o servidor de destino. | Verifique se o domínio do host pode ser acessado pelo público da internet. |
| ERRO (`302`) (ou outro status `3xx`) | O servidor de destino tentou redirecionar a solicitação para outro local. Consideramos as respostas de redirecionamento a solicitações de webhook como falhas. | Defina o destino do endpoint do webhook como o URL resolvido pelo redirecionamento. |
| ERRO (`400`) (ou outro status `4xx`) | O servidor de destino não pode ou não quer processar a solicitação. Isso pode ocorrer quando o servidor detecta um erro (`400`), quando o URL de destino tem restrições de acesso (`401`, `403`, `405`) ou o URL de destino não existe (`404`). | Verifique se o seu endpoint pode ser acessado pelo público da internet e que aceite um método POST HTTP. |
| ERRO (`500`) (ou outro status `5xx`) | O servidor de destino encontrou um erro ao processar a solicitação. | Revise os logs do aplicativo para entender por que ele está retornando um erro `500`. |
| ERRO (Erro de TLS) | Não foi possível estabelecer uma conexão segura com o servidor de destino. Problemas com o certificado SSL/TLS ou um certificado intermediário na cadeia de certificados do servidor de destino geralmente causam esses erros. A Stripe exige o *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) versão `v1.2` ou superior. | Execute um [teste de servidor SSL](https://www.ssllabs.com/ssltest/) para encontrar problemas que possam causar esse erro. |
| ERRO (Tempo esgotado) | O servidor de destino demorou muito para responder à solicitação do webhook. | Verifique se o código de tratamento do webhook adia o processamento de lógica complexa e retorna imediatamente uma resposta bem-sucedida. |

## Comportamentos de entrega de eventos

Esta seção ajuda a entender os diferentes comportamentos esperados em relação ao modo como a Stripe envia eventos ao endpoint de webhook.

### Novas tentativas automáticas

A Stripe tenta entregar eventos ao seu destino por até três dias com um atraso exponencial no modo de produção. Veja quando ocorrerá a próxima tentativa, se for o caso, na guia **Entregas de evento** do destino do evento. Fazemos novas tentativas de entrega de eventos criados em uma área restrita três vezes em poucas horas. Se seu destino tiver sido desativado ou excluído quando fizermos uma nova tentativa, impediremos futuras tentativas desse evento. No entanto, se você desativar e reativar o destino do evento antes de podermos fazer uma nova tentativa, você ainda verá novas tentativas futuras.

### Novas tentativas manuais

Há duas maneiras de repetir eventos manualmente:

- No Stripe Dashboard, clique em **Reenviar** quando visualizar um evento específico. Isso funciona por até 15 dias após a criação do evento.
- Com o [Stripe CLI](https://docs.stripe.com/cli/events/resend), execute o comando `stripe events resend <event_id> --webhook-endpoint=<endpoint_id>`. Isso funciona por até 30 dias após a criação do evento.

O reenvio manual de um evento com falhas de entrega anteriores para um endpoint de webhook não dispensa o [comportamento automático de novas tentativas](https://docs.stripe.com/webhooks.md#automatic-retries) da Stripe, mesmo que resulte em um código de status `2xx`. Saiba como [processar eventos de webhook não entregues](https://docs.stripe.com/webhooks/process-undelivered-events.md) para interromper novas tentativas futuras.

### Ordem de eventos

A Stripe não garante a entrega dos eventos na ordem em que foram gerados. Por exemplo, a criação de uma assinatura pode gerar os seguintes eventos:

- `customer.subscription.created`
- `invoice.created`
- `invoice.paid`
- `charge.created` (se houver cobrança)

Certifique-se de que o destino dos seus eventos não dependa do recebimento de eventos em um pedido específico. Os eventos de snapshot registram `created` em segundos; portanto, eventos distintos podem compartilhar um registro de data/hora. Não use `created` para determinar o pedido dos eventos ou se você já processou um evento. Em vez disso, acompanhe os [IDs de evento](https://docs.stripe.com/api/events/object.md#event_object-id) para identificar entregas duplicadas. Você também pode usar a API para recuperar eventuais objetos ausentes. Por exemplo, você poderá recuperar os objetos de fatura, cobrança e assinatura com as informações de `invoice.paid` se receber esse evento primeiro.

### Controle de versões da API

A versão de API nas configurações da sua conta quando o evento ocorre determina a versão de API e, portanto, a estrutura de um [Event](https://docs.stripe.com/api/events.md) enviado ao seu destino. Por exemplo, se sua conta estiver definida para uma versão de API mais antiga, como 2015-02-16, e você alterar a versão de API de uma solicitação específica com [controle de versão](https://docs.stripe.com/api.md#versioning), o objeto [Event](https://docs.stripe.com/api/events.md) gerado e enviado ao seu destino ainda estará baseado na versão de API 2015-02-16. Não é possível alterar objetos [Event](https://docs.stripe.com/api/events.md) após a criação. Por exemplo, se você atualizar uma cobrança, o evento de cobrança original permanecerá inalterado. Portanto, atualizações subsequentes na versão de API da sua conta não alteram retroativamente os objetos [Event](https://docs.stripe.com/api/events.md) existentes. Recuperar um [Event](https://docs.stripe.com/api/events.md) mais antigo chamando `/v1/events` usando uma versão mais recente da API também não afeta a estrutura do evento recebido. Você pode definir destinos de eventos de teste para a versão padrão ou mais recente da API. O objeto [Event](https://docs.stripe.com/api/events.md) enviado ao destino é estruturado para a versão especificada do destino do evento.

## Práticas recomendadas para uso de webhooks

Revise essas práticas recomendadas para garantir que seus endpoints de webhook permaneçam seguros e funcionem bem com sua integração.

### Gerenciar eventos duplicados

Ocasionalmente, os endpoints de webhook podem receber o mesmo evento mais de uma vez. Para se proteger contra o recebimento de eventos duplicados, registre os [IDs de evento](https://docs.stripe.com/api/events/object.md#event_object-id) que você processou e não processe eventos já registrados.

Em alguns casos, dois objetos Event são gerados e enviados. Para identificar essas duplicatas, use o ID do objeto em `data.object` junto com o `event.type`.

### Escutar apenas os tipos de eventos exigidos pela sua integração

Configure seus endpoints de webhook para receber somente os tipos de eventos exigidos por sua integração. Escutar eventos adicionais (ou todos os eventos) sobrecarrega seu servidor e não é recomendável.

Você pode [alterar os eventos](https://docs.stripe.com/api/webhook_endpoints/update.md#update_webhook_endpoint-enabled_events) que um endpoint de webhook recebe no Dashboard ou com a API.

### Gerenciar eventos de forma assíncrona

Configure seu gerenciador para processar eventos de entrada com uma fila assíncrona. Você pode encontrar problemas de escalabilidade se optar por processar eventos de forma síncrona. Qualquer grande pico nas entregas de webhooks (por exemplo, durante o início do mês, quando todas as assinaturas são renovadas) pode sobrecarregar seus hosts de endpoint.

As filas assíncronas permitem que você processe os eventos simultâneos em uma taxa que seu sistema possa aceitar.

### Rota de webhook isenta de proteção contra CSRF

Se estiver usando Rails, Django ou outra estrutura da web, seu site pode verificar automaticamente se cada solicitação POST contém um *token CSRF*. Esse é um importante recurso de segurança que ajuda a proteger você e seus usuários contra tentativas de [falsificação de solicitações entre sites](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_\(CSRF\)). No entanto, essa medida de segurança também pode evitar que seu site processe eventos legítimos. Se for o caso, você pode precisar isentar a rota dos webhooks da proteção contra 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
```

### Receber eventos com um servidor HTTPS

Se você usa um URL HTTPS para seu endpoint de webhook (obrigatório no modo de produção), a Stripe valida a segurança da conexão com seu servidor antes de enviar os dados do webhook. Para que isso funcione, seu servidor precisa estar configurado corretamente para aceitar HTTPS com um certificado de servidor válido. Os webhooks da Stripe aceitam apenas as versões v1.2 e v1.3 do *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).

### Substituir periodicamente segredos de assinatura de endpoints

O segredo utilizado para verificar se os eventos são provenientes da Stripe pode ser modificado na guia [Webhooks](https://dashboard.stripe.com/webhooks) no Workbench. Para mantê-los seguros, recomendamos que você altere (modifique) os segredos periodicamente ou sempre que suspeitar que um segredo foi comprometido.

Para substituir um segredo:

1. Clique em cada endpoint na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench para o qual deseja alterar o segredo.
2. Acesse o menu de navegação (⋯) e clique em **Substituir segredo**. Você pode optar pela expiração imediata do segredo atual ou atrasar a expiração para até 24 horas para ter tempo de atualizar o código de verificação no seu servidor. Durante esse período, várias chaves secretas ficam ativas para o endpoint. A Stripe gera uma assinatura por segredo até a expiração.

### Verificar se eventos são enviados da Stripe

Sem verificação, um invasor poderia enviar eventos de Webhook falsos para o seu endpoint a fim de acionar ações como executar pedidos, conceder acesso à conta ou modificar registros. Sempre verifique se os eventos de Webhook se originam da Stripe antes de agir.

Use ambas as proteções:

- **Lista de permissões de IP:** A Stripe envia eventos de Webhook a partir de uma lista específica de [endereços de IP](https://docs.stripe.com/ips.md). Configure seu servidor ou firewall para aceitar solicitações de Webhook somente desses endereços.
- **Verificação de assinatura**: a Stripe assina todos os eventos de webhook incluindo uma assinatura no cabeçalho `Stripe-Signature`. Verifique essa assinatura usando nossas [bibliotecas oficiais](https://docs.stripe.com/webhooks.md#verify-signature) ou siga as [etapas de verificação manual](https://docs.stripe.com/webhooks.md?verify=verify-manually#verify-signature) para confirmar se o evento não foi enviado ou modificado por terceiros.

A seção a seguir descreve como verificar assinaturas de webhook:

1. Recupere o segredo do endpoint.
2. Verifique a assinatura.

#### Recuperar o segredo do endpoint

Utilize o Workbench e acesse a guia [Webhooks](https://dashboard.stripe.com/webhooks) para visualizar todos os seus endpoints. Selecione um endpoint para o qual deseja obter o segredo e, em seguida, clique em **Clique para exibir**.

A Stripe gera uma chave secreta única para cada endpoint. Se você usar o mesmo endpoint para [chaves de API do modo de teste e do modo de produção](https://docs.stripe.com/keys.md#test-live-modes), os segredos serão diferentes uns dos outros. Além disso, se usar vários endpoints, você precisa obter um segredo para cada endpoint em que deseja verificar assinaturas. Após essa configuração, a Stripe começa a assinar cada webhook que envia ao endpoint.

#### Verifique a assinatura

#### Verificar com bibliotecas oficiais (recomendado)

### Verifique assinaturas de webhook com bibliotecas oficiais

Recomendamos usar nossas bibliotecas oficiais para verificar assinaturas. Para fazer a verificação, forneça o conteúdo do evento, o cabeçalho `Stripe-Signature` e a chave secreta do endpoint. Se a verificação falhar, você receberá um erro.

Se você receber um erro de verificação de assinatura, leia nosso guia sobre [solução de problemas](https://docs.stripe.com/webhooks/signature.md).

> A Stripe exige o corpo bruto da solicitação para realizar a verificação de assinatura. Se estiver usando uma estrutura, assegure-se de que ela não manipule o corpo bruto. Qualquer manipulação no corpo bruto da solicitação causa falha na verificação.

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

# Using the Sinatra framework
set :port, 4242

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

  begin
    event = 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
```

#### Verificar manualmente

### Verificar assinaturas de webhook manualmente

Recomendamos usar nossas bibliotecas oficiais para verificar assinaturas de eventos de webhook, mas você pode criar uma solução personalizada seguindo esta seção.

O cabeçalho `Stripe-Signature` incluído em cada evento assinado contém um carimbo de data e hora e uma ou mais assinaturas que você precisa verificar. O carimbo de data e hora tem um prefixo `t=` e cada assinatura tem um prefixo *esquema*. Os esquemas começam com `v`, seguidos por um número inteiro. Atualmente, o único esquema de assinatura em modo de produção válido é `v1`. Para ajudar com os testes, a Stripe envia uma assinatura adicional com um esquema `v0` falso para eventos de teste.

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

> Fornecemos novas linhas para maior clareza, mas um cabeçalho `Stripe-Signature` real está em uma única linha.

A Stripe gera assinaturas usando um código de autenticação de mensagem baseado em hash ([HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code)) com [SHA-256](https://en.wikipedia.org/wiki/SHA-2). Para evitar [ataques de downgrade](https://en.wikipedia.org/wiki/Downgrade_attack), ignore todos os esquemas que não forem `v1`.

Você pode ter várias assinaturas com o mesmo par de esquema-segredo ao [rolar um segredo de endpoint](https://docs.stripe.com/webhooks.md#roll-endpoint-secrets), mantendo o segredo anterior ativo por até 24 horas. Durante esse período, seu endpoint tem vários segredos ativos e a Stripe gera uma assinatura para cada segredo.

Para criar uma solução manual de verificação de assinaturas, você precisa concluir as seguintes etapas:

#### Etapa 1: extraia o carimbo de data e hora e as assinaturas do cabeçalho

Divida o cabeçalho usando o caractere `,` como separador para obter uma lista de elementos. Em seguida, divida cada elemento usando o caractere `=` como separador para obter um par de prefixo e valor.

O valor para o prefixo `t` corresponde ao carimbo de data e hora e `v1` corresponde à assinatura (ou assinaturas). Você pode descartar todos os demais elementos.

#### Etapa 2: prepare a string `signed_payload`

A string `signed_payload` é criada concatenando:

- O carimbo de data e hora (como string)
- O caractere `.`
- O conteúdo JSON real (ou seja, o corpo da solicitação)

#### Etapa 3: determine a assinatura esperada

Calcule um HMAC com a função de hash SHA256. Use o segredo de assinatura do endpoint como chave e use a string `signed_payload` como mensagem.

#### Etapa 4: compare as assinaturas

Compare a assinatura (ou assinaturas) no cabeçalho com a assinatura esperada. Para uma correspondência de igualdade, calcule a diferença entre o carimbo de data e hora atual e o carimbo de data e hora recebido e decida se a diferença está dentro da tolerância.

Para se proteger contra ataques de temporização, use uma comparação de strings de tempo constante para comparar a assinatura esperada com cada uma das assinaturas recebidas.

### Evitar ataques de repetição

Um [ataque de repetição](https://en.wikipedia.org/wiki/Replay_attack) ocorre quando um invasor intercepta e retransmite um conteúdo válido e sua assinatura. Para mitigar esses ataques, a Stripe inclui um carimbo de data e hora no cabeçalho `Stripe-Signature`. Como esse carimbo de data e hora faz parte do conteúdo assinado, ele também é verificado pela assinatura, de forma que um invasor não pode alterar o carimbo de data e hora sem invalidar a assinatura. Se a assinatura for válida, mas o carimbo de data e hora for muito antigo, seu aplicativo pode recusar o conteúdo.

Nossas bibliotecas têm uma tolerância padrão de cinco minutos entre o carimbo de data e hora e a hora atual. Você pode alterar essa tolerância fornecendo um parâmetro adicional quando verificar assinaturas. Use o Network Time Protocol ([NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol)) para assegurar que o relógio do seu servidor esteja preciso e sincroniza com a hora nos servidores da Stripe.

> Não use um valor de tolerância de `0`. O uso de um valor de tolerância de `0` desativa totalmente a verificação de recenticidade.

A Stripe gera o carimbo de data e hora e a assinatura sempre que envia um evento ao seu endpoint. Se a Stripe tentar novamente um evento (por exemplo, seu endpoint respondeu anteriormente com um código de status diferente de `2xx`), serão gerados uma nova assinatura e um novo carimbo de data e hora para a nova tentativa de entrega.

### Retornar rapidamente uma resposta 2xx

Seu [endpoint](https://docs.stripe.com/webhooks.md#example-endpoint) deve retornar rapidamente um código de status bem-sucedido (`2xx`) antes de executar qualquer lógica complexa que possa causar um timeout. Por exemplo, é necessário retornar uma resposta `200` antes de atualizar uma Fatura de cliente como paga em seu sistema contábil.

## See also

- [Envie eventos ao Amazon EventBdge](https://docs.stripe.com/event-destinations/eventbridge.md)
- [Enviar eventos para o Azure Event Grid](https://docs.stripe.com/event-destinations/eventgrid.md)
- [Lista de tipos de eventos mínimos](https://docs.stripe.com/api/v2/core/events/event-types.md)
- [Lista de tipos de evento de instantâneo](https://docs.stripe.com/api/events/.md)
- [Criador interativo de endpoints de webhook](https://docs.stripe.com/webhooks/quickstart.md)
