Skip to main content
Webhooks de assinatura usam um envelope próprio. O event de topo é sempre subscription; o nome concreto do evento fica em data.event_type.

Exemplo de payload entregue

Eventos de falha usam os mesmos campos da assinatura e também podem trazer contexto de retentativa, como attempt_number e failure_reason.

Eventos emitidos hoje

  • subscription.created
  • subscription.started
  • subscription.renewed
  • subscription.updated
  • subscription.canceled
  • subscription.payment_failed
  • subscription.past_due
  • subscription.trial_will_end
  • subscription.chargeback_received

Sequência do Pix Automático

Assinaturas com Pix Automático usam o mesmo envelope e os mesmos nomes de evento. O que muda é quando cada evento chega:
  • Sem período de teste: nenhum evento na criação. subscription.started, com previous_status: "incomplete", chega quando o pagador autorizou e o primeiro débito foi pago.
  • Com período de teste: subscription.created chega quando o pagador aprova a autorização (status trialing, latest_transaction: null). subscription.trial_will_end chega 3 dias antes de trial_end se a assinatura já estiver trialing nesse momento, e subscription.started com o primeiro débito depois dele.
  • Autorização recusada ou, dependendo da configuração da conta, expirada: subscription.canceled, com failure_reason.
  • Ciclos seguintes: subscription.renewed a cada débito pago. Depois de um débito com falha, subscription.payment_failed, e também subscription.past_due quando a assinatura passa para past_due.
  • Cancelamento: subscription.canceled, nunca subscription.updated.
Nesses eventos, latest_transaction.method é "pix". As cobranças do Pix Automático não enviam webhooks transaction.*, e um débito com falha não cria transação, então nos eventos de falha latest_transaction é a transação mais recente da assinatura. A tabela completa está em Assinaturas com Pix Automático.

Troca de plano

A troca de plano vale só para assinaturas com cartão. Uma troca de plano não cria um tipo de evento novo. Ela chega como subscription.updated, e update_fields diz o que se moveu: ["product_id", "amount"] quando o novo plano já está sendo cobrado, ["pending_change"] quando uma troca foi agendada ou uma troca agendada foi cancelada. Quando o plano de fato se move — na hora, ou no momento em que é agendado — o payload traz também um bloco plan_change:
Numa troca agendada, effective_at é o fim do período atual; numa imediata, é o momento em que foi aplicada. Dois casos chegam sem plan_change de propósito, e é a ausência do bloco que os distingue dos anteriores:
  • Uma troca agendada foi cancelada. Você recebe subscription.updated com update_fields: ["pending_change"] e sem o bloco plan_change.
  • Uma troca agendada passou a valer na renovação. Nenhum subscription.updated é enviado por isso. Você recebe o subscription.renewed de sempre, já com o amount novo, e pendingChange fica null na leitura seguinte.

Guia de tratamento

  • Faça deduplicação pelo id do evento no topo.
  • Use data.event_type para encaminhar cada evento ao handler correto.
  • Use data.status para o estado atual da assinatura.
  • Use latest_transaction para a transação de cobrança ligada ao evento. Nos eventos de falha do Pix Automático, ela é a transação mais recente da assinatura.
  • Use o UUID em data.id como identificador da assinatura.
  • Reconcilie com GET /v2/subscriptions/{id} se a entrega ou o processamento for interrompido.

Leia a seguir