> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scanify.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Verificação de webhook

> Como autenticar callbacks do Scanify e tratar entregas duplicadas

Os callbacks são disparados pelos servidores do Scanify para o `callbackUrl` que você informou. Garantir que a requisição realmente veio do Scanify é responsabilidade da sua aplicação.

## Mecanismos disponíveis

As duas opções podem ser combinadas.

### `callbackAuthToken` (recomendado)

Se você informar `callbackAuthToken` na requisição original, o Scanify envia esse valor no header `Authorization` do callback:

```
Authorization: Bearer <callbackAuthToken>
```

Defina um valor secreto e único por endpoint, guarde-o em uma variável de ambiente do seu servidor e compare no recebimento.

```ts theme={"dark"}
import express from 'express';

const app = express();
app.use(express.json());

app.post('/webhooks/scanify', (req, res) => {
  const auth = req.header('authorization');
  const expected = `Bearer ${process.env.SCANIFY_WEBHOOK_TOKEN}`;

  if (auth !== expected) {
    return res.status(401).end();
  }

  res.status(200).end();
});
```

### `signature`

Se você informar `signature` na requisição original, o Scanify reenvia a mesma string, **sem modificação**, no header:

```
x-scanify-signature: <signature>
```

É útil para correlacionar o callback com a requisição que o originou (ex: codifique aí um id interno).

<Warning>
  Este NÃO é um HMAC calculado pelo Scanify. É apenas um eco do valor que você enviou. Não use como assinatura criptográfica.
</Warning>

## Idempotência

O Scanify reenvia o callback em caso de falha: até **3 tentativas** com backoff exponencial. Sua aplicação deve tratar entregas duplicadas como normais.

Use `request_id` como chave única de deduplicação:

```ts theme={"dark"}
if (await db.webhookEvents.exists(payload.request_id)) {
  return res.status(200).end();
}

await db.webhookEvents.create({ request_id: payload.request_id });
// ... processar
```

## Boas práticas

* Responda 2xx rapidamente. Processamento pesado deve ir para uma fila no seu lado.
* Restrinja o endpoint por IP ou região se a sua infraestrutura permitir.
* Nunca logue o `callbackAuthToken` em texto claro.
* Habilite HTTPS no endpoint. HTTP simples é aceito mas não é recomendado.

***

<Info>
  Para o formato do corpo enviado no callback, veja [Callback URL](/callback-url) e [Payload de resposta](/response-payload).
</Info>
