Skip to main content
Webhooks são como a Gravity Play avisa o seu sistema quando algo acontece — um pagamento confirmado, uma assinatura renovada, um estorno. Eles são a fonte da verdade: chegam mesmo que o cliente feche o navegador.

Duas formas de receber

Endpoints do painel

Cadastre URLs fixas em Integrações → Webhooks e escolha os eventos (e, se quiser, os produtos). Recebem todos os eventos que casarem.

postbackUrl da cobrança

Ao criar uma cobrança via API, informe um postbackUrl. Ele recebe os eventos daquela transação específica — somado aos endpoints do painel.

Eventos

Formato do payload

Toda entrega é um POST com corpo JSON neste formato:
Campos do data nos eventos payment.*:

O objeto customer

Todos os eventos payment.* e subscription.* trazem o objeto customer com os dados que o comprador preencheu no checkout. Campos não coletados naquele fluxo vêm como null. O address, quando presente, tem o formato:
Quando cada campo existe. O endereço é coletado no cartão (Asaas/Pagar.me) e no boleto — em pagamentos PIX o checkout pede só os dados pessoais, então customer.address vem null. O telefone é coletado no cartão (gateways BR) e no PIX Pagar.me. Pagamentos anteriores a esta versão não têm os campos novos preenchidos (null).
Para eventos de uma cobrança via API, o data.metadata traz a metadata que você enviou na criação — use o invoiceId (ou o que for) para dar baixa.

O objeto offer

Todo evento cujo data tenha um offerId — pagamentos de checkout de oferta e todos os eventos subscription.* — vem com o objeto offer completo embutido, para você reagir aos dados comerciais (nome, preço, ciclo) sem uma chamada extra à API.
Cobranças avulsas não têm oferta. Eventos de cobranças criadas via POST /v1/charges (sem uma oferta) não trazem o objeto offer — nesses casos offerId é null. Use o data.metadata e o chargeId para reconciliar.
Os eventos subscription.* usam um data menor (id, status, offerId, customerEmail, customer, currentPeriodEnd) — também com os objetos customer e offer embutidos:
E os headers:

Validando a assinatura

Cada entrega é assinada com HMAC-SHA256. O header tem o formato t=<unix>,v1=<hmac>, e o HMAC é calculado sobre `${t}.${body}` usando o secret.
Qual secret usar? - Endpoints do painel: o signing secret exibido ao criar o endpoint. - postbackUrl: o postbackSecret retornado na resposta do POST /v1/charges daquela cobrança. Cada cobrança tem o seu.
Use o corpo cru. Valide a assinatura sobre o corpo exatamente como recebido (raw). Se você re-serializar o JSON, a assinatura não vai bater.

postbackUrl

Quando você cria uma cobrança com postbackUrl, todos os eventos daquela transação (payment.paid, payment.failed, payment.refunded) são entregues também nessa URL — além dos endpoints do painel. É ideal para reconciliar uma fatura sem precisar manter um endpoint fixo. O postbackSecret que valida essas entregas vem uma única vez, na resposta da criação da cobrança. Guarde-o junto com o id da cobrança/fatura.

Idempotência

A mesma entrega pode chegar mais de uma vez (ex.: ao reprocessar). Use o X-GravityPay-Delivery (= id do payload) como chave de idempotência e ignore duplicatas.

Resposta e re-tentativas

Responda 2xx rapidamente (idealmente em até alguns segundos) para confirmar o recebimento. Qualquer outro status é tratado como falha. Entregas que falham ficam registradas no painel (Integrações → Webhooks → Entregas), de onde você pode reprocessar manualmente.