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

## Comece aqui: instale skills de agente

A Stripe recomenda usar skills oficiais para integrar com a API seguindo práticas recomendadas. Siga as instruções abaixo para saber como.

**Dica: use curl em vez de ferramentas Fetch.** Skills são arquivos markdown detalhados de 10 KB a 20 KB. Ferramentas Fetch fazem um resumo deles. `curl -sL` garante o conteúdo completo.

**Usando `npx skills`**: verifique se `npx` está instalado no sistema. Se `npx` estiver disponível, execute `npx skills add https://docs.stripe.com --list` para listar os skills disponíveis e, depois, execute `npx skills add https://docs.stripe.com --yes --skill <skill-name> <--skill other-skills>` para instalar skills individuais.

**Se `npx skills` não estiver disponível**: é possível usar curl para buscar o índice de skills disponíveis, o que eles fazem e seus arquivos em `https://docs.stripe.com/.well-known/skills/index.json`. Para baixar um skill e os arquivos relacionados, use curl para baixá-los de `https://docs.stripe.com/.well-known/skills/<filepath>`.

Para este artigo, recomendamos usar estes skills: `stripe-best-practices`

> #### Enviar eventos para sua conta da AWS ou assinatura do Azure
> 
> Você pode enviar eventos diretamente para o [Amazon EventBridge](https://docs.stripe.com/event-destinations/eventbridge.md) ou [Azure Event Grid](https://docs.stripe.com/event-destinations/eventgrid.md) como destinos de evento.

Crie um destino de evento para receber eventos em um endpoint de webhook HTTPS. Depois que você registra um endpoint de webhook, a Stripe pode enviar dados de eventos em tempo real ao endpoint do webhook do aplicativo quando os [eventos](https://docs.stripe.com/event-destinations.md#events-overview) ocorrerem na sua conta Stripe. A Stripe usa HTTPS para enviar eventos de webhook ao seu aplicativo como um conteúdo JSON que inclui um [objeto Event](https://docs.stripe.com/api/events.md).

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.

## Comece já

Para começar a receber eventos de webhook no aplicativo:

1. Crie um gerenciador de endpoint de webhook para receber solicitações POST de dados de evento.
1. Teste o gerenciador de endpoint de webhook localmente usando o Stripe CLI.
1. Crie um novo [destino de evento](https://docs.stripe.com/event-destinations.md) para o seu endpoint de webhook.
1. Proteja seu endpoint de webhook.

Você pode registrar e criar um endpoint para gerenciar vários tipos de eventos ao mesmo tempo ou configurar endpoints individuais para eventos específicos.

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

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

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.

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

Configure sua função de endpoint para que:

- Processe solicitações POST com um conteúdo JSON que consiste em um [objeto de evento](https://docs.stripe.com/api/events/object.md).
- Para manipuladores de eventos [organization](https://docs.stripe.com/get-started/account/orgs.md), ela inspeciona o valor `context` para determinar qual conta em uma organização gerou o evento e, em seguida, define o cabeçalho `Stripe-Context` correspondente ao valor `context`.
- Retorne rapidamente um código de status de êxito (`2xx`) antes de qualquer lógica complexa que possa causar um tempo esgotado. Por exemplo, você precisa retornar uma resposta `200` antes de atualizar uma fatura do cliente como paga no sistema de contabilidade.

> - Use nosso [criador de endpoint de webhook interativo](https://docs.stripe.com/webhooks/quickstart.md) para criar uma função de endpoint de webhook na sua linguagem de programação.
- Use a referência da API da Stripe para identificar os [eventos mínimos](https://docs.stripe.com/api/v2/core/events/event-types.md) ou os [eventos em modo instantâneo](https://docs.stripe.com/api/events/object.md) que o seu manipulador de webhook precisa processar.

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

#### Manipulador de eventos finos (Acacia ou Basil)

Ao criar um gerenciador de eventos mínimos, use o método `fetchRelatedObject()` para recuperar a versão mais recente do objeto associado ao evento. Eventos mínimos podem conter [dados contextuais adicionais](https://docs.stripe.com/event-destinations.md#fetch-data) que você só pode recuperar com a API. Use a chamada `retrieve()` com o ID de evento mínimo para acessar esses campos de carga útil.

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

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

#### Manipulador de eventos finos (Acacia ou Basil)

Este trecho de código é uma função webhook configurada para receber eventos thin em toda a organização, verificar a assinatura, determinar a conta de origem com o campo `context` e usar a chave API dessa conta para chamadas API subsequentes.

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

## Testar seu gerenciador

Antes de implementar a função de endpoint de webhook no modo de produção, recomendamos testar a integração do aplicativo. Você pode fazer isso configurando um ouvinte local para enviar eventos à máquina local e enviando eventos de teste. Para testar, você precisa usar a [CLI](https://docs.stripe.com/stripe-cli.md).

#### Encaminhar eventos para um endpoint local

Para encaminhar eventos ao endpoint local, execute o comando a seguir com a [CLI](https://docs.stripe.com/stripe-cli.md) para configurar um ouvinte local. O sinalizador `--forward-to` envia todos os [eventos da Stripe](https://docs.stripe.com/cli/trigger#trigger-event) em uma [área restrita](https://docs.stripe.com/sandboxes.md) para o seu endpoint de webhook local. Use os comandos de CLI apropriados abaixo, dependendo se você usa eventos [mínimos](https://docs.stripe.com/event-destinations.md#events-overview) ou de instantâneo.

#### Encaminhar eventos de instantâneo

Use o comando a seguir para encaminhar [eventos de instantâneo](https://docs.stripe.com/event-destinations.md#events-overview) ao ouvinte local.

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

#### Encaminhar eventos mínimos

Use o comando a seguir para encaminhar [eventos mínimos](https://docs.stripe.com/event-destinations.md#events-overview) ao ouvinte local.

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

> Você também pode executar `stripe listen` para exibir eventos em [Stripe Shell](https://docs.stripe.com/workbench/shell.md), embora não seja possível encaminhar eventos da shell para seu endpoint local.

Estas são algumas configurações úteis para ajudar a testar o ouvinte local:

- Para desativar a verificação de certificados HTTPS, use o sinalizador opcional `--skip-verify`.
- Para encaminhar apenas eventos específicos, use o sinalizador opcional `--events` e passe uma lista de eventos separados por vírgulas.

#### Encaminhar eventos de instantâneo de destino

Use o comando a seguir para encaminhar eventos de instantâneo de destino ao ouvinte 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
```

#### Encaminhar eventos mínimos de destino

Use o comando a seguir para encaminhar eventos mínimos de destino ao ouvinte local.

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

- Para encaminhar eventos do endpoint de webhook público que você já registrou na Stripe para o endpoint de webhook local, use o sinalizador opcional `--load-from-webhooks-api`. Ele carrega o endpoint registrado, analisa o caminho e os eventos registrados e depois anexa o caminho ao endpoint de webhook local no `--forward-to path`.

#### Encaminhar eventos de instantâneo de um endpoint de webhook público

Use o comando a seguir para encaminhar eventos de instantâneo de um endpoint de webhook público para o ouvinte local.

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

#### Encaminhe eventos mínimos de um endpoint de webhook público

Use o comando a seguir para encaminhar eventos mínioms de um endpoint de webhook público para o ouvinte local.

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

- Para verificar as assinaturas do webhook, use o `{{WEBHOOK_SIGNING_SECRET}}` da saída inicial do comando listen.

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

#### Acionar 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/stripe-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/stripe-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.
```

## Registrar seu endpoint

Após testar a função do endpoint do webhook, use a [API](https://docs.stripe.com/api/v2/event-destinations.md) ou a guia **Webhooks** no Workbench para registrar o URL acessível do endpoint do webhook para que Stripe saiba onde entregar os eventos. Você pode registrar até 16 endpoints de webhook com a Stripe. Os endpoints de webhook registrados precisam ser URLs **HTTPS** com acesso público.

#### Formato de URL de webhook

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

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

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

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

Crie um destino de eventos usando o Workbench no Dashboard ou automaticamente com a [API](https://docs.stripe.com/api/v2/event-destinations.md). Você pode registrar até 16 destinos de evento em cada conta Stripe.

#### Dashboard

Para criar um novo endpoint de webhook no Dashboard:

1. Abra a guia [Webhooks](https://dashboard.stripe.com/webhooks) no Workbench.
1. Clique em **Criar um destino de evento**.
1. Selecione de onde você deseja receber eventos. A Stripe aceita dois tipos de configurações: **Sua conta** e [Contas conectadas](https://docs.stripe.com/connect.md). Selecione **Conta** para escutar eventos da sua própria conta. Se você criou um [aplicativo Connect](https://docs.stripe.com/connect.md) e quer escutar eventos das suas contas conectadas, selecione **Contas conectadas**.

> #### Ouvir eventos de um endpoint de webhook da organização
> 
> Se você criar um endpoint de webhook em uma [conta da organização](https://docs.stripe.com/get-started/account/orgs.md), selecione **Contas** para ouvir eventos das contas da sua organização. Se você tiver [plataformas Connect](https://docs.stripe.com/connect.md) como membros das suas organizações e quiser ouvir eventos das contas conectadas de todas as plataformas, selecione **Contas conectadas**.

1. Selecione a versão da API para o [objeto de eventos](https://docs.stripe.com/api/events.md) que você deseja consumir.
1. Selecione os [tipos de evento](https://docs.stripe.com/api/events/types.md) que você deseja enviar a um endpoint de webhook.
1. Selecione **Continuar** e depois **Endpoint do webhook** como o tipo de destino.
1. Clique em **Continuar** e informe o **URL do endpoint** e uma descrição opcional do webhook.

#### API

É possível criar um destino de evento que enviar uma notificação a você quando um erro de validação de [cobrança por uso](https://docs.stripe.com/billing/subscriptions/usage-based.md) é acionado usando a [API](https://docs.stripe.com/api/v2/event-destinations.md).

Se você criou uma [inscrição conectada](https://docs.stripe.com/connect.md) e deseja ouvir suas contas conectadas, use o parâmetro [events_from](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-events_from) e defina seu valor como `@accounts`. Para destinos de evento de [organização](https://docs.stripe.com/get-started/account/orgs.md), use `@organization_members` para eventos de contas em sua organização ou `@organization_members/@accounts` para eventos de contas conectadas em toda a organização.

```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"
    }
  }'
```

> O [Workbench](https://docs.stripe.com/workbench.md) substitui o [Dashboard dos desenvolvedores](https://docs.stripe.com/development/dashboard.md) existente. Se você ainda está usando o Dashboard dos desenvolvedores, veja como [criar um endpoint de webhook](https://docs.stripe.com/development/dashboard/webhooks.md).

## Proteja seu endpoint

Depois de confirmar que seu endpoint funciona como esperado, proteja-o implementando as [práticas recomendads de webhook](https://docs.stripe.com/webhooks.md#best-practices).

Proteja sua integração garantindo que seu responsável verifique se todas as requisições do Webhook foram geradas pela Stripe. Você pode verificar assinaturas de Webhook usando nossas bibliotecas oficiais ou verificá-las manualmente.

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

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

## 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 visualizar as entregas de eventos, selecione o endpoint de Webhook em **Webhooks** e, em seguida, acesse a aba **Events**. A aba **Events** exibe uma lista de eventos e indica se eles estão `Entregues`, `Pendentes`, ou `Falharam` . Clique em um evento para ver os metadados, incluindo o código de status HTTP da tentativa de entrega e o horário de entregas futuras pendentes.

Você também pode usar a [Stripe CLI](https://docs.stripe.com/stripe-cli.md) para [escutar eventos](https://docs.stripe.com/webhooks.md#test-webhook) diretamente no 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`), o URL de destino tem restrições de acesso (`401`, `403`) 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)

Verifique se o destino de eventos não depende de receber eventos em uma ordem específica. Esteja preparado para gerenciar a entrega de forma adequada. Você também pode usar a API para recuperar objetos ausentes. Por exemplo, você pode 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 usado para verificar a origem dos eventos da Stripe pode ser modificado na guia **Webhooks** no Workbench. Para mantê-los seguros, recomendamos que você substitua (altere) os segredos periodicamente ou quando suspeitar que um deles foi comprometido.

Para substituir um segredo:

1. Clique em cada endpoint na guia **Webhooks** do Workbench cujo segredo você deseja substituir.
1. 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 cada evento de Webhook incluindo uma assinatura no cabeçalho `Stripe-Signature`. Verifique essa assinatura usando nossas [bibliotecas oficiais](https://docs.stripe.com/webhooks.md#verify-official-libraries) ou [manualmente](https://docs.stripe.com/webhooks.md#verify-manually) para confirmar que o evento não foi enviado nem modificado por terceiros.

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

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

#### Recuperar o segredo do endpoint

Use o Workbench e vá para a guia **Webhooks** para ver todos os seus endpoints. Selecione um endpoint do qual você deseja obter o segredo e clique em **Clique para revelar**.

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.

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

O [endpoint](https://docs.stripe.com/webhooks.md#example-endpoint) precisa retornar rapidamente um código de status de êxito (`2xx`) antes de qualquer lógica complexa que possa esgotar um tempo limite. Por exemplo, você precisa retornar uma resposta `200` antes de atualizar uma fatura do cliente como paga no sistema de contabilidade.

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