Webhooks
Webhooks avisam o seu sistema quando algo acontece, como "pagamento recebido" ou "devolvido". Venha a venda de qual conta vier, o aviso tem sempre o mesmo formato.
Adicionar um endereço
Em Webhooks → Adicionar endereço, coloque a URL do seu sistema (precisa ser https://) e escolha os avisos que quer receber.
Os avisos
| Aviso | Quando |
|---|---|
payment.processing |
em análise (cartão), ainda sem resposta do banco |
payment.succeeded |
o cliente pagou |
payment.failed |
foi recusado |
payment.created |
a cobrança foi criada |
payment.canceled |
venceu ou você cancelou |
payment.refunded |
devolvido por completo |
payment.partially_refunded |
devolvido em parte |
refund.created |
uma devolução foi pedida, ou feita direto no painel da conta |
refund.updated |
a conta confirmou ou recusou uma devolução |
reconciliation.completed |
a conferência do dia terminou |
dispute.created |
o cliente contestou (MED ou chargeback) |
dispute.updated |
a contestação mudou, por exemplo, você respondeu |
dispute.closed |
a contestação terminou: ganha, perdida ou cancelada |
subscription.created |
um Pix Automático foi criado e espera o cliente |
subscription.activated |
o cliente aprovou o Pix Automático |
subscription.refused |
o cliente não aprovou, ou o banco não confirmou |
subscription.canceled |
o Pix Automático foi cancelado (por você ou pelo cliente) |
subscription.expired |
chegou a data de fim |
payout.created |
um saque foi pedido |
payout.updated |
o saque está a caminho, ou a conta ainda não confirmou (uncertain: true) |
payout.paid |
o dinheiro chegou ao destino |
payout.failed |
a conta recusou ou o banco devolveu; veja failure_reason |
payout.canceled |
o saque foi cancelado antes de sair |
subaccount.created |
uma subconta foi criada (pelo painel ou pela API). Se não reconhecer, confira em Subcontas |
subaccount.updated |
a situação de uma subconta mudou: aprovada, recusada, bloqueada |
payout_destination.created |
o dono salvou uma chave Pix para saques. Se não foi alguém da equipe, remova em Saques |
O que chega
{
"id": "evt_3Jd9...",
"type": "payment.succeeded",
"created": 1760000000,
"data": {
"object": { "id": "pay_...", "status": "succeeded", "amount": 4990, "fee": 49, "net": 4941 }
}
}
Responda com status 200 em até 8 segundos. Se o seu sistema não responder, a SuyPay tenta de novo depois de 1 min, 5 min, 30 min, 2 h, 6 h, 12 h e 24 h.
Confirmar que veio da SuyPay
Todo aviso traz o cabeçalho SuyPay-Signature. Confira com a chave de assinatura do endereço:
import crypto from 'node:crypto'
function veioDoSuyPay(corpo, cabecalho, chave) {
const { t, v1 } = Object.fromEntries(cabecalho.split(',').map((p) => p.split('=')))
const esperado = crypto.createHmac('sha256', chave).update(`${t}.${corpo}`).digest('hex')
const recente = Math.abs(Date.now() / 1000 - Number(t)) < 300
return recente && crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(v1))
}
Use o corpo exatamente como chegou, antes de transformar em JSON.