Avisos ao seu sistema (webhooks)
Receba cobranca.paga e cobranca.devolvida no seu sistema com avisos assinados (HMAC-SHA256), novas tentativas automáticas e exemplos de verificação.
Quando uma cobrança é paga (ou uma devolução termina), a SinapsePay envia um POST JSON para a URL que você cadastrou no painel, em Contas → Avisos ao seu sistema. A URL é por conta bancária; o segredo da assinatura (whsec_…) aparece só ao configurar e ao trocar.
Eventos
evento |
Quando |
|---|---|
cobranca.paga |
O pagamento chegou e a cobrança ficou paga |
cobranca.devolvida |
Uma devolução foi concluída (total ou parcial) |
cobranca.devolucao_recusada |
O banco recusou uma devolução |
O que chega
POST /seu/endpoint
Content-Type: application/json
User-Agent: SinapsePay-Webhook/1
X-SinapsePay-Evento: cobranca.paga
X-SinapsePay-Entrega: 27708324-70d6-469b-a3fc-73304e527493
X-SinapsePay-Assinatura: t=1791251108,v1=87e8f770150cad1ad168c0fe3b26009da473749717181896884a1203e353caee
{
"id": "27708324-70d6-469b-a3fc-73304e527493",
"evento": "cobranca.paga",
"criadoEm": "2026-10-06T01:45:08.381715Z",
"cobranca": {
"id": "4ec2604f-97c2-4715-9642-c6e59cb7bef8",
"idExterno": "pedido-1042",
"produto": "pix",
"status": "paga",
"valor": 12000,
"pagoEm": "2026-10-06T01:45:08.334Z",
"pagamentos": [
{
"valorPago": 12000,
"pagoEm": "2026-10-06T01:45:08.334Z",
"endToEndId": "E75691000179125110833465113",
"txid": "4ec2604f97c247159642c6e59cb7bef8",
"pagoPorNome": "Maria Souza",
"pagoPorDocumento": "52998224725"
}
]
}
}
Nos eventos de devolução, cobranca.devolucoes traz a lista com a situação de cada uma.
Conferir a assinatura
- Separe
tev1do cabeçalhoX-SinapsePay-Assinatura. - Calcule
HMAC-SHA256(segredo, t + "." + corpo)em hexadecimal, com o corpo exatamente como chegou (antes de converter o JSON). - Compare com
v1em tempo constante e recusetcom mais de 5 minutos de diferença do seu relógio.
// Node.js
import { createHmac, timingSafeEqual } from 'node:crypto'
export function avisoValido(corpoCru, cabecalho, segredo) {
const { t, v1 } = Object.fromEntries(cabecalho.split(',').map((parte) => parte.split('=')))
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false
const esperado = createHmac('sha256', segredo).update(`${t}.${corpoCru}`).digest('hex')
return v1?.length === esperado.length && timingSafeEqual(Buffer.from(v1), Buffer.from(esperado))
}
# Python
import hashlib, hmac, time
def aviso_valido(corpo_cru: bytes, cabecalho: str, segredo: str) -> bool:
partes = dict(p.split("=", 1) for p in cabecalho.split(","))
if abs(time.time() - int(partes["t"])) > 300:
return False
esperado = hmac.new(segredo.encode(), f'{partes["t"]}.'.encode() + corpo_cru, hashlib.sha256).hexdigest()
return hmac.compare_digest(esperado, partes.get("v1", ""))
Responda rápido e ignore repetidos
- Responda 2xx em até 10 segundos e processe depois, se precisar. Redirecionamentos não são seguidos.
- Sem 2xx, a SinapsePay tenta de novo em 30 s, 2 min, 10 min, 30 min, 1 h, 3 h, 6 h e 12 h (cerca de 22 horas) e depois desiste. O histórico de entregas fica no painel.
- O mesmo aviso pode chegar mais de uma vez: use
X-SinapsePay-Entrega(igual aoiddo corpo, o mesmo em todas as tentativas) para ignorar repetidos. - A URL precisa ser
httpse apontar para a internet: endereços de rede interna são recusados.
Perdeu um aviso? Consulte a cobrança: a consulta pergunta ao banco e responde atualizada.