Visão geral

Para: Dev — Conferido em 2026-10-18.

O Dracma avisa cada mudança de estado de um depósito ou saque com um POST assinado na URL de webhook da sua operação. O webhook só avisa: quem decide se o dinheiro se move é o estado que a API devolve quando você consulta o objeto. Esta página resume o que o Dracma garante, o que ele não garante e como as páginas desta seção se encaixam.

O que é

Um webhook é uma requisição POST do Dracma para o seu servidor, com um envelope JSON que descreve uma transição de estado (deposit.paid, withdrawal.failed e assim por diante). Você cadastra uma URL por operação; os eventos de uma operação de teste vão só para a URL da operação de teste, e os da operação real só para a URL da real.

As garantias de entrega são estas:

  • Pelo menos uma vez (at-least-once). O mesmo evento pode chegar mais de uma vez, sempre com o mesmo Dracma-Event-Id e os mesmos bytes de corpo. A deduplicação por esse id é obrigação do seu receptor.
  • O Dracma grava antes de tentar. O evento é registrado de forma durável antes da primeira tentativa de envio, e uma tentativa que falha é repetida pelo cronograma de Retentativas, skipped e DLQ. Uma indisponibilidade momentânea do Dracma não perde o evento.
  • Sucesso é uma resposta 2xx em até 10 s. Qualquer outra coisa (4xx, 5xx, timeout, redirect, erro de rede ou de TLS) conta como falha e gera nova tentativa por até 72 h.
  • Todo evento fica disponível em GET /events, com o mesmo envelope, mesmo que o webhook nunca tenha chegado. Veja Recuperação com GET /events.

Quando usar

Use webhooks como o gatilho rápido da sua integração: eles dizem que algo mudou e qual objeto consultar. Eles não substituem a consulta à API, o job de recuperação nem a reconciliação diária. A integração completa tem três camadas:

Camada Para que serve Página
Webhook Reagir em segundos a cada mudança de estado. Esta seção
Job de GET /events a cada 5 minutos Fechar lacunas: webhook perdido, DLQ, queda do seu receptor, eventos não assinados. Recuperação com GET /events
Reconciliação diária Provar que o seu livro e o do Dracma fecham. Reconciliar com o seu livro

O que o Dracma não garante

  • Ordem. Cada transição gera um webhook próprio, e as entregas de eventos diferentes competem entre si. Um deposit.paid pode chegar antes de um deposit.pending atrasado. O contador object_version, que só cresce, resolve a ordem de um mesmo objeto.
  • Estado atual no corpo. O data.object é o estado no momento da transição, congelado. Uma reentrega feita horas depois leva o objeto antigo.
  • Um webhook por mudança, sem junção. O Dracma não junta transições rápidas em um único webhook. Cada transição tem o seu evento; o que pode parecer "junção" é só a chegada fora de ordem.

Como funciona

sequenceDiagram participant P as Dracma (API) participant W as Dracma (webhooks) participant R as Seu receptor P->>P: Transição de estado (grava o evento junto) P->>W: Evento novo W->>W: Grava a entrega (corpo congelado) W->>R: POST assinado (Dracma-Event-Id, Dracma-Signature) R->>R: Verifica assinatura, deduplica R->>P: GET /v1/deposits/{object_id} (sua credencial) P-->>R: Estado atual R->>R: Aplica o efeito, idempotente pelo external_id R-->>W: 200
  1. A transição do objeto grava o evento na mesma transação que muda o estado. Por isso GET /events nunca perde uma transição.
  2. O Dracma registra a entrega com o corpo já montado e assinado a cada tentativa.
  3. O seu receptor verifica a assinatura sobre os bytes crus, deduplica pelo Dracma-Event-Id e consulta o objeto na API com a sua credencial (o fetch-back).
  4. O receptor aplica o efeito pelo estado devolvido pela consulta e responde 2xx.

Um webhook forjado não cria dinheiro

Se o seu segredo de webhook vazar, alguém consegue montar um deposit.paid com assinatura válida. Como o seu receptor não credita pelo corpo e sim pelo GET feito com a sua credencial de API, o webhook forjado vira uma consulta inútil: o depósito segue no estado que o Dracma realmente tem. É por isso que o fetch-back é obrigatório e não uma otimização. A suíte de conformidade testa exatamente isto: um webhook forjado com assinatura válida não pode gerar crédito.

Glossário

Termo Significado
Entrega O registro de um evento a enviar para a URL da operação. Há uma entrega por evento.
Tentativa Um POST dessa entrega. Uma entrega tem até 15 ou 16 tentativas por ciclo.
Estados da entrega pending (aguarda a primeira tentativa ou a próxima), delivered (recebeu 2xx), dlq (esgotou as tentativas) e skipped (nada foi enviado).
DLQ Fila das entregas que esgotaram as 72 h sem 2xx. O evento não se perde: continua em GET /events e pode ser reentregue pelo painel.
skipped Entrega registrada, mas não enviada: sem URL cadastrada, ambiente diferente ou tipo não assinado.
Fetch-back A consulta à API que o receptor faz com a própria credencial para confirmar o estado antes de agir.

Exemplos

Um caminho feliz de depósito, do ponto de vista do receptor:

Passo O que acontece
1 Chega deposit.pending (object_version 2). Você exibe o QR Code.
2 Chega deposit.paid (object_version 3). Você consulta GET /v1/deposits/{object_id}, confere external_id, amount e player_ref e credita o jogador uma única vez.
3 O Dracma repete deposit.paid por falha de rede do seu lado. O Dracma-Event-Id já foi processado: você responde 200 sem efeito.

O código completo de cada passo está em Receptor passo a passo.

Erros e casos de borda

  • Nunca receber nada. Confira se a URL está cadastrada e efetiva (a alteração tem aprovação e espera), se o tipo está assinado e se o ambiente da URL é o da operação. Veja Problemas comuns.
  • Receber duplicado. É esperado; responda 200 sem efeito.
  • Receber fora de ordem. É esperado; ordene por object_version e aja pelo estado da consulta.
  • Responder erro de propósito. Responder 4xx ou 5xx não "cancela" o evento: o Dracma repete por até 72 h. Para um evento que você não quer tratar, responda 200.

Veja também