# Webhooks do Connect Saiba como usar webhooks com o Connect para receber notificações de atividades da Stripe. A Stripe usa *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) para notificar os aplicativos quando um evento ocorre em sua conta. Todas as integrações do *Connect* (Connect is Stripe's solution for multi-party businesses, such as marketplace or software platforms, to route payments between sellers, customers, and other recipients) devem estabelecer um [endpoint de webhook](https://dashboard.stripe.com/account/webhooks) para ouvir eventos do Connect. ## Webhooks conectados Os webhooks para usuários do Connect monitoram eventos em diferentes escopos, dependendo da origem do evento: - **Sua conta**: a maioria dos eventos acionados por recursos existentes na sua conta. Isso inclui a maioria das solicitações feitas com suas chaves da API e sem [autenticar como outra conta Stripe](https://docs.stripe.com/connect/authentication.md), como: - Eventos `v2.core.account.*` para `Accounts` v2 na sua conta - Eventos para `Clientes` na sua conta - Eventos para direct charges na sua conta - Eventos para *cobranças indiretas* (A charge type where customers transact directly with your platform instead of with a connected account. Indirect charges include destination charges and separate charges and transfers) na sua conta relacionados às suas contas conectadas - **Contas conectadas**: eventos acionados por recursos existentes nas contas conectadas e alguns recursos existentes na sua conta, como: - Eventos `v2.core.account.*` para `Accounts` v2 que representam clientes e destinatários das suas contas conectadas - Eventos `account.updated` tanto para `Accounts` v1 quanto v2 que representam clientes e destinatários das suas contas conectadas - *Direct charges* (A charge type where customers transact directly with a connected account, which is always the merchant of record. With each payment, the connected account pays fees to Stripe and, optionally, to your platform) para clientes das suas contas conectadas > #### Escopos de eventos para Accounts v2 que representam contas conectadas > > Os objetos da `Account` v2 acionam tanto `Eventos` v1 quanto v2, que podem ter escopos diferentes. Para eventos acionados por contas conectadas, os `Events` v2 usam o escopo **Sua conta**, enquanto os `Events` v1 usam o escopo **Contas conectadas**, mesmo quando acionados pela mesma `Account` v2. Ao criar um Webhook no [Workbench](https://dashboard.stripe.com/workbench/webhooks), atribua o escopo definindo **Eventos de** como **Sua conta** ou **Contas conectadas**. Ao criar um Webhook usando a API, atribua o escopo definindo o parâmetro [connect](https://docs.stripe.com/api/webhook_endpoints/create.md#create_webhook_endpoint-connect) como falso (para **Sua conta**) ou verdadeiro (para **Contas conectadas**). Para webhooks do Connect, os URLs de webhook de desenvolvimento recebem apenas webhooks de teste, mas os URLs de webhook de produção recebem webhooks de produção e de teste. Isso ocorre porque você pode realizar transações de produção e de teste em um aplicativo de produção. Recomendamos que você verifique o valor de `livemode` ao receber um evento de webhook para determinar se os usuários precisam realizar uma ação. Você deve definir endpoints Webhook separados para suas contas de [área restrita](https://docs.stripe.com/sandboxes.md) receberem eventos dessas contas. Cada evento de conta conectada contém uma propriedade `account` de nível superior que identifica a conta conectada. Como a conta conectada é proprietária [do objeto que acionou o evento](https://docs.stripe.com/api/events/object.md#event_object-data-object), você precisa fazer solicitações de API para esse objeto [como a conta conectada](https://docs.stripe.com/connect/authentication.md). ```json { "id": ""{{EVENT_ID}}"", "livemode": true, "object": "event", "type": "customer.created", "account": ""{{CONNECTED_ACCOUNT_ID}}"", "pending_webhooks": 2, "created": 1349654313, "data": {...} } ``` A tabela a seguir descreve alguns dos eventos mais comuns e importantes relacionados a contas conectadas: | Evento | tipo data.object | Descrição | | ---------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `account.application.deauthorized` | `application` | Ocorre quando uma conta conectada se desconecta da sua plataforma. Você pode usá-lo para acionar a limpeza em seu servidor. Disponível para contas conectadas com acesso ao Stripe Dashboard, que inclui [contas Standard](https://docs.stripe.com/connect/standard-accounts.md). | | `account.external_account.updated` | Uma conta externa, como `card` ou `bank_account` | Ocorre quando [uma conta bancária ou cartão de débito vinculado a uma conta conectada é atualizado](https://docs.stripe.com/connect/payouts-bank-accounts.md), o que pode afetar os repasses. Disponível para contas conectadas controladas pela sua plataforma, o que inclui contas Custom e Express, e contas Standard com [controles de plataforma](https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts.md) habilitados. | | `account.updated` | `account` | Permite monitorar alterações nos requisitos e mudanças de status das contas conectadas. Disponível para todas as contas conectadas. | | `balance.available` | `balance` | Ocorre quando o seu saldo da Stripe é atualizado. Por exemplo, quando [fundos que você adicionou da sua conta bancária](https://docs.stripe.com/connect/top-ups.md) ficam disponíveis para repasse à sua conta conectada. | | `payment_intent.succeeded` | `payment_intent` | Ocorre quando uma intenção de pagamento resulta em uma cobrança bem-sucedida. Disponível para todos os pagamentos, incluindo cobranças de [destino](https://docs.stripe.com/connect/destination-charges.md) e [diretas](https://docs.stripe.com/connect/direct-charges.md). | | `payout.failed` | `payout` | Ocorre quando [um repasse falha](https://docs.stripe.com/connect/payouts-connected-accounts.md#webhooks). Quando um repasse falha, a conta externa envolvida é desativada e nenhum repasse automático ou manual é processado até que ela seja atualizada. | | `person.updated` | `person` | Ocorre quando uma `Person` associada à `Account` é atualizada. Se você [usa a API Persons para gerenciar requisitos](https://docs.stripe.com/connect/handling-api-verification.md#verification-process), escute esse evento para monitorar alterações de requisitos e status de indivíduos. Disponível para contas conectadas controladas pela sua plataforma, o que inclui contas Custom e Express, e contas Standard com [controles de plataforma](https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts.md) habilitados. | #### Evento - account.application.deauthorized #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.application.deauthorized' application = event['data']['object'] connected_account_id = event['account'] handle_deauthorization(connected_account_id, application) end status 200 end def handle_deauthorization(connected_account_id, application) # Clean up account state. puts 'Connected account ID: ' + connected_account_id puts application.to_s end ``` #### Evento - account.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.updated' account = event['data']['object'] handle_account_update(account) end status 200 end def handle_account_update(account) # Collect more required information puts account.to_s end ``` #### Evento - person.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'person.updated' person = event['data']['object'] connected_account_id = event['account'] handle_person_update(connected_account_id, person) end status 200 end def handle_person_update(connected_account_id, person) # Collect more required information puts 'Connected account ID: ' + connected_account_id puts person.to_s end ``` #### Evento - payment_intent.succeeded, cobrança direta #### Rubi ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you are testing your webhook locally with the Stripe CLI you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payment_intent.succeeded' payment_intent = event['data']['object'] connected_account_id = event['account'] handle_successful_payment_intent(connected_account_id, payment_intent) end status 200 end def handle_successful_payment_intent(connected_account_id, payment_intent) # Fulfill the purchase puts 'Connected account ID: ' + connected_account_id puts payment_intent.to_s end ``` #### Evento - payment_intent.succeeded, cobrança não direta #### Rubi ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you are testing your webhook locally with the Stripe CLI you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payment_intent.succeeded' payment_intent = event['data']['object'] handle_successful_payment_intent(payment_intent) end status 200 end def handle_successful_payment_intent(payment_intent) # Fulfill the purchase puts payment_intent.to_s end ``` #### Evento - balance.available #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'balance.available' balance = event['data']['object'] handle_available_balance(balance) end status 200 end def handle_available_balance(balance) # Transfer funds to a connected account puts balance.to_s end ``` #### Evento - account.external_account.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.external_account.updated' external_account = event['data']['object'] connected_account_id = event['account'] handle_external_account_update(connected_account_id, external_account) end status 200 end def handle_external_account_update(connected_account_id, external_account) # Transfer funds to a connected account puts 'Connected account ID: ' + connected_account_id puts external_account.to_s end ``` #### Evento - payout.failed #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payout.failed' payout = event['data']['object'] connected_account_id = event['account'] handle_failed_payout(connected_account_id, payout) end status 200 end def handle_failed_payout(connected_account_id, payout) # Re-collect bank account required information puts 'Connected account ID: ' + connected_account_id puts payout.to_s end ``` ## Testar webhook localmente Para testar Webhooks de eventos localmente com o Stripe CLI: 1. Se ainda não tiver instalado, [instale o Stripe CLI](https://docs.stripe.com/stripe-cli/install.md) na sua máquina. 1. Acesse sua conta Stripe e configure a CLI executando `stripe login` na linha de comando. 1. Permita que seu host local receba um evento simulado executando [stripe listen](https://docs.stripe.com/cli/listen), dependendo do escopo do evento: - **Contas conectadas**: `stripe listen --forward-connect-to localhost:{{PORT}}/{{CONNECT_WEBHOOK_ENDPOINT}}` - **Sua conta**: `stripe listen --forward-to localhost:{{PORT}}/{{WEBHOOK_ENDPOINT}}` 1. Em outra janela do terminal, acione um evento simulado executando [stripe trigger](https://docs.stripe.com/cli/trigger), dependendo do escopo do evento: - **Contas conectadas**: `stripe trigger --stripe-account {{CONNECTED_ACCOUNT_ID}} {{EVENT_NAME}}` - **Sua conta**: `stripe trigger {{EVENT_NAME}}` ## See also - [Documentação do webhook](https://docs.stripe.com/webhooks.md) - [Referência do objeto Event](https://docs.stripe.com/api.md#events)