Desenvolvedores

Webhooks

Quando uma fatura muda de estado, a CryBit envia uma requisição POST assinada, com corpo JSON, para a URL de webhook do seu merchant.

Configuração

Defina a URL do webhook e marque os eventos nas configurações do merchant, na aba de integração: paid, expired, refunded, cancelled. A URL deve ser um endereço HTTP ou HTTPS público na porta 80, 443, 8080 ou 8443; redirecionamentos não são seguidos. Ela é definida no merchant, não na requisição da fatura.

Cabeçalhos

CabeçalhoValor
X-CryBit-EventO nome do evento, por exemplo payment.paid.
X-CryBit-Signaturet=<unix time>,v1=<hex>: HMAC-SHA256 de "<t>.<raw body>" com o seu segredo de assinatura.

Verifique a assinatura

O segredo de assinatura aparece nas configurações do merchant, ao lado da URL do webhook. Calcule a assinatura sobre o corpo bruto, compare em tempo constante e rejeite requisições com mais de cinco minutos.

PHP

$secret = getenv('CRYBIT_WEBHOOK_SECRET');
$body   = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_CRYBIT_SIGNATURE'] ?? '';

parse_str(str_replace(',', '&', $header), $p);   // t=…&v1=…
$t = (int) ($p['t'] ?? 0);
$expected = hash_hmac('sha256', $t . '.' . $body, $secret);

if (abs(time() - $t) > 300 || !hash_equals($expected, $p['v1'] ?? '')) {
    http_response_code(400);
    exit;
}
// the request is genuine: store the event, answer 200, do the rest later
http_response_code(200);

Node.js

import crypto from 'node:crypto'

export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map((kv) => kv.split('=')))
  const t = Number(parts.t)
  const expected = crypto.createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex')
  const ok = parts.v1 && parts.v1.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected))
  return ok && Math.abs(Date.now() / 1000 - t) <= 300
}

Entrega e novas tentativas

  • Responda rapidamente com um status 2xx: a CryBit espera cerca de doze segundos.
  • Se você não responder, a CryBit tenta de novo após 15 segundos, 1 minuto, 5, 15 e 30 minutos, depois 2, 6 e 24 horas.
  • Uma resposta 4xx, exceto 429, interrompe as novas tentativas.
  • O mesmo evento pode chegar mais de uma vez: trate-o de forma idempotente, usando order_id ou o uuid da fatura como chave.
  • Se você perdeu um webhook, consulte o status com GET /api/v1/payments/{uuid}: ele é sempre a fonte da verdade.

FAQ

Posso ver o que foi entregue?

Sim. A página de logs da API na conta do lojista lista as requisições e as entregas de webhook com o código de status e o corpo.

Mais

Obter uma chave de API