# 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 Uma plataforma Connect usa dois tipos de webhooks: - Os webhooks de *Account* são usados para atividades da sua própria conta (por exemplo, a maioria das solicitações que usam suas chaves de API sem [autenticar-se como outra conta Stripe](https://docs.stripe.com/connect/authentication.md)). Incluem todos os tipos de cobrança, exceto as realizadas diretamente em uma conta conectada. - Os webhooks do *Connect* são para atividades de qualquer conta conectada. Enviamos todos os eventos na conta conectada (incluindo atualizações da conta e cobranças diretas) para os webhooks do Connect. Ao criar um webhook do Connect, você precisa configurá-lo para receber eventos de webhook do Connect. Ao criá-lo no [Dashboard](https://dashboard.stripe.com/test/webhooks), em **Escutar**, selecione **Eventos em contas conectadas**. Ao criá-lo usando a API, defina o [parâmetro connect](https://docs.stripe.com/api/webhook_endpoints/create.md#create_webhook_endpoint-connect) como true. ![Configurações de webhook no Stripe Dashboard](https://b.stripecdn.com/docs-statics-srv/assets/webhooks.ac3d6c19a5281fbbd2b85a335cd887b3.png) 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 separados do webook para suas contas da [área restrita](https://docs.stripe.com/sandboxes.md) para receber 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. Stripe.api_key = '<>' # 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. Stripe.api_key = '<>' # 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. Stripe.api_key = '<>' # 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. Stripe.api_key = '<>' # 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. Stripe.api_key = '<>' # 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. Stripe.api_key = '<>' # 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. Stripe.api_key = '<>' # 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. Stripe.api_key = '<>' # 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 Você pode testar webhooks localmente com a 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 o host local receba um evento simulado em sua conta conectada executando `stripe listen --forward-to localhost:{PORT}/webhook` em uma janela de terminal e `stripe trigger {{EVENT_NAME}}` em outra. > Para webhooks do Connect, use [–forward-connect-to](https://docs.stripe.com/cli/listen#listen-forward-connect-to) com `stripe listen` e [–stripe-account](https://docs.stripe.com/cli/trigger#trigger-stripe_account) com `stripe trigger`. ## See also - [Documentação do webhook](https://docs.stripe.com/webhooks.md) - [Referência do objeto Event](https://docs.stripe.com/api.md#events)