Pular para o conteúdo
sinapsepay

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

  1. Separe t e v1 do cabeçalho X-SinapsePay-Assinatura.
  2. Calcule HMAC-SHA256(segredo, t + "." + corpo) em hexadecimal, com o corpo exatamente como chegou (antes de converter o JSON).
  3. Compare com v1 em tempo constante e recuse t com 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 ao id do corpo, o mesmo em todas as tentativas) para ignorar repetidos.
  • A URL precisa ser https e 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.