Eventos assíncronos
Webhooks
Configure uma URL no painel para receber mudanças de status das cobranças. Valide a assinatura antes de processar o corpo e use eventId para impedir efeitos duplicados.
Leia o evento recebidoLink direto para a seção Leia o evento recebido
Os valores monetários em amount são enviados em centavos: 14990 representa R$ 149,90. paymentRequestId é o identificador devolvido na criação da cobrança e provider indica a origem do aviso. Os horários vêm em ISO 8601 no horário de Brasília (UTC−03:00), como 2026-09-30T11:32:00.000-03:00: é o mesmo instante de antes, e quem lê com um parser ISO não precisa mudar nada.
payment_intent/completed (conta Sicoob)
{
"event": "payment_intent/completed",
"eventId": "5c3f2a1e-8d4b-5f6a-9e7c-2b1d0a9f8e7d",
"paymentRequestId": "550e8400-e29b-41d4-a716-446655440098",
"provider": "sicoob",
"status": "completed",
"amount": 14990,
"paidAt": "2026-09-30T11:32:00.000-03:00",
"endToEndId": "E75608532202609301432Ab12Cd34Ef5"
}manual_pix/receipt_received
{
"event": "manual_pix/receipt_received",
"eventId": "7d2e4f60-9a1b-5c3d-9e8f-0a1b2c3d4e5f",
"paymentRequestId": "550e8400-e29b-41d4-a716-446655440000",
"provider": "manual",
"amount": 2500,
"receiptReceivedAt": "2026-09-30T11:40:00.000-03:00"
}Comprovante não é pagamento
Eventos públicosLink direto para a seção Eventos públicos
PIX pela conta Sicoob
payment_intent/completedCobrança paga, confirmada pelo banco (provider: sicoob).
payment_request/updatedCobrança expirada (EXPIRED), cancelada (CANCELED) ou com erro (ERROR).
| Evento | Quando usar |
|---|---|
| payment_intent/completed | Cobrança paga, confirmada pelo banco (provider: sicoob). |
| payment_request/updated | Cobrança expirada (EXPIRED), cancelada (CANCELED) ou com erro (ERROR). |
PIX manual (link com comprovante)
manual_pix/receipt_receivedO pagador enviou um comprovante. Não confirma o pagamento.
manual_pix/receipt_removedA equipe removeu o comprovante e reabriu o envio.
| Evento | Quando usar |
|---|---|
| manual_pix/receipt_received | O pagador enviou um comprovante. Não confirma o pagamento. |
| manual_pix/receipt_removed | A equipe removeu o comprovante e reabriu o envio. |
Estados, ordem e comprovantesLink direto para a seção Estados, ordem e comprovantes
paymentRequestIdé o identificador devolvido na criação:payment_iddo PIX pela conta Sicoob,iddo link de PIX manual epayment_request_iddo Open Finance.providerindica a origem do aviso:sicoob,manualoupluggy(Open Finance). Campos novos podem ser acrescentados; ignore os que não conhecer.- Valores em
amountsão centavos inteiros (14990representa R$ 149,90). - Horários seguem ISO 8601 no horário de Brasília (UTC−03:00), por exemplo
2026-09-30T11:32:00.000-03:00. É o mesmo instante de antes: quem lê com um parser ISO não precisa mudar nada. Datas sem hora (AAAA-MM-DD, comodateno PIX Automático) são o dia em Brasília. - A assinatura é calculada sobre o corpo exatamente como é enviado, já com os horários em
-03:00: valide sobre o corpo bruto, sem reescrevê-lo.X-Webhook-Timestampe ot=da assinatura continuam em segundos Unix, sem fuso, e oeventIdnão muda. - No PIX pela conta Sicoob,
payment_request/updatedusastatusEXPIRED,CANCELEDouERROR;GET /api/payments/{payment_id}/statusmostraexpired,canceledoufailed. Uma cobrança paga depois de expirar gera os dois avisos, e o pagamento vale. Falha ao criar a cobrança volta na resposta da criação e não gera aviso. Devolução não gera aviso. - No PIX manual, os avisos tratam do comprovante, não do pagamento: o PIX manual continua sem confirmação bancária. Confira o crédito no extrato antes de liberar o pedido.
- Os avisos saem em até alguns minutos e podem chegar repetidos ou fora de ordem: use
eventIdpara processar cada um uma vez e consulte o status quando precisar do estado atual.
payment_request/updated (conta Sicoob)
{
"event": "payment_request/updated",
"eventId": "0b7e9a44-2c1d-5e3f-8a6b-4c5d6e7f8091",
"paymentRequestId": "550e8400-e29b-41d4-a716-446655440098",
"provider": "sicoob",
"status": "EXPIRED",
"amount": 14990
}manual_pix/receipt_removed
{
"event": "manual_pix/receipt_removed",
"eventId": "2f8c6d4b-7e5a-5b3c-a1d2-e3f405162738",
"paymentRequestId": "550e8400-e29b-41d4-a716-446655440000",
"provider": "manual",
"amount": 2500,
"receiptReceivedAt": "2026-09-30T11:40:00.000-03:00",
"receiptRemovedAt": "2026-09-30T11:55:00.000-03:00"
}Valide a assinatura HMACLink direto para a seção Valide a assinatura HMAC
Quando um segredo está configurado, cada entrega traz a assinatura com carimbo de tempo X-Webhook-Signature-V2, no formato t=<segundos>,v1=<hmac>, e o carimbo também em X-Webhook-Timestamp. O HMAC-SHA256 é calculado sobre <segundos>.<corpo bruto>. Valide a assinatura e recuse entregas com carimbo mais antigo que 5 minutos: assim uma entrega capturada não pode ser reenviada depois. Cada tentativa de entrega leva um carimbo novo. O carimbo é em segundos Unix, sem fuso, e a assinatura cobre o corpo exatamente como é enviado, com os horários em -03:00: não reescreva o corpo antes de validar.
Node.js (recomendado)
import { createHmac, timingSafeEqual } from "node:crypto";
const TOLERANCE_SECONDS = 5 * 60;
function isValidCasePayWebhook(rawBody, signatureV2, secret) {
const parts = Object.fromEntries(
String(signatureV2 ?? "")
.split(",")
.map((part) => part.split("=", 2)),
);
const timestamp = Number(parts.t);
const received = parts.v1 ?? "";
if (!Number.isInteger(timestamp) || !/^[a-f0-9]{64}$/i.test(received)) {
return false;
}
if (Math.abs(Date.now() / 1000 - timestamp) > TOLERANCE_SECONDS) {
return false;
}
const expected = createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
const receivedBuffer = Buffer.from(received, "hex");
const expectedBuffer = Buffer.from(expected, "hex");
return (
receivedBuffer.length === expectedBuffer.length &&
timingSafeEqual(receivedBuffer, expectedBuffer)
);
}O cabeçalho X-Webhook-Signature: sha256=<hmac> continua sendo enviado, calculado só sobre o corpo bruto, para quem ainda valida a versão anterior. Ele não protege contra reenvio: prefira a assinatura com carimbo de tempo.
Cabeçalhos de cada entrega
X-Webhook-Event (tipo do evento), X-Webhook-Event-Id (o mesmo eventId do corpo), X-Webhook-Delivery-Id (identifica a entrega; as novas tentativas repetem o valor), X-Webhook-Timestamp e as assinaturas acima. Responda com um código 2xx para confirmar; redirecionamentos (3xx) não são seguidos e contam como falha. Entregas com falha são repetidas com intervalo crescente.Processe cada evento uma vezLink direto para a seção Processe cada evento uma vez
Grave o eventId antes de executar efeitos externos. Se o ID já tiver sido processado, responda sem repetir a operação. Use os endpoints de consulta como fonte de reconciliação quando precisar confirmar o estado atual.