> For the complete documentation index, see [llms.txt](https://ereemby.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ereemby.gitbook.io/docs/desenvolvedores/webhooks.md).

# Webhooks

### Como criar um webhook de vendas na Ereemby

Webhooks são a forma mais simples de receber eventos em tempo real.\
Quando um pagamento for aprovado, a Ereemby envia um **POST** para a sua URL com um **JSON** contendo os dados do evento.

{% hint style="info" %}
Tenha um endpoint pronto para receber **POST** em `application/json`.\
Use HTTPS sempre que possível.
{% endhint %}

{% hint style="danger" %}
O **Secret** do webhook é confidencial. Trate como senha.\
Guarde em variável de ambiente e rotacione se vazar.
{% endhint %}

{% stepper %}
{% step %}

### Abra a sessão de Webhooks

No painel da Ereemby, vá em **Configurações** da sua loja.\
Encontre a seção **Webhooks**.
{% endstep %}

{% step %}

### Crie um novo webhook

Clique em **Criar** para adicionar um novo webhook.
{% endstep %}

{% step %}

### Informe a URL do seu endpoint

Cole a URL que vai receber os eventos, por exemplo:

* `https://seusite.com/webhooks/ereemby`
* `https://api.seusite.com/hooks/vendas`

Evite URLs com autenticação no querystring.
{% endstep %}

{% step %}

### Selecione os eventos

Marque os eventos que você quer receber.

#### Vendas

* `order_paid` (evento de pagamento aprovado)

Os detalhes desse payload estão em [Notificações de order\_paid](/docs/informacoes-gerais/notificacoes/notificacoes-de-vendas-proprio.md).

#### Chat (suporte)

* `chat_created`
* `chat_message`

Os detalhes desses payloads estão em [Bot de suporte](/docs/desenvolvedores/documentacao-api-publica/bot-de-suporte.md).
{% endstep %}

{% step %}

### Salve e copie o Secret

Após salvar, a Ereemby gera um **Secret** exclusivo desse webhook.\
Copie e guarde em um local seguro.

Você vai usar esse Secret para validar a assinatura das mensagens.
{% endstep %}
{% endstepper %}

### O que a Ereemby envia (payload)

Cada evento chega como **JSON** no body da requisição.\
Esse JSON inclui os dados do pedido e do pagamento.

{% hint style="info" %}
Processe o body recebido “como veio”.\
A validação da assinatura depende do conteúdo exato do body.
{% endhint %}

{% hint style="warning" %}
No dia **27/08/2026**, os eventos `cart` e `sale` serão descontinuados.\
Depois dessa data, apenas `order_paid` será enviado.
{% endhint %}

### Autenticação (assinatura HMAC)

Para evitar spoofing e alterações no payload, a Ereemby assina cada request.\
Você deve validar essa assinatura antes de processar o evento.

#### Header enviado

A assinatura vem neste header:

```
x-webhook-signature: <token-gerado>
```

#### Como validar

1. Leia o **body bruto** da requisição (raw body).
2. Gere um HMAC usando **SHA-256** com o **Secret** do webhook.
3. Use o **body bruto** como mensagem do HMAC.
4. Compare o resultado (hex) com o valor do `x-webhook-signature`.

Se bater, a request é legítima.\
Se não bater, responda `401/403` e não processe.

{% hint style="warning" %}
Evite validar usando `JSON.stringify(req.body)`.\
Diferenças de espaços, ordem de chaves ou encoding podem quebrar a assinatura.\
O mais seguro é validar com o **raw body**.
{% endhint %}

### Exemplo: recebendo eventos (Node.js + Express)

Esse exemplo:

* Recebe `POST` com `application/json`.
* Captura o **raw body**.
* Valida `x-webhook-signature` via HMAC SHA-256 (`crypto`).
* Loga o payload após validar.

{% hint style="info" %}
Para testar no seu PC usando URL pública, use **ngrok**.\
Você também encontra exemplos com ngrok em [Bot de suporte](/docs/desenvolvedores/documentacao-api-publica/bot-de-suporte.md) e [Notificações de order\_paid](/docs/informacoes-gerais/notificacoes/notificacoes-de-vendas-proprio.md).
{% endhint %}

#### Rodando local

1. Crie um projeto Node.
2. Instale o Express.

```bash
npm init -y
npm i express
```

3. Crie o arquivo abaixo e rode `node server.js`.

{% hint style="warning" %}
Não deixe o Secret hardcoded em produção.\
Use variável de ambiente (ex: `process.env.WEBHOOK_SECRET`).
{% endhint %}

{% code title="server.js" %}

```js
const express = require("express");
const crypto = require("crypto");

const app = express();

// Secret do webhook (ideal: process.env.WEBHOOK_SECRET)
const WEBHOOK_SECRET = "SEU_SECRET_AQUI";

if (!WEBHOOK_SECRET) throw new Error("Missing WEBHOOK_SECRET");

// Captura RAW BODY (necessário para validar a assinatura)
app.use(
  express.json({
    verify: (req, res, buf) => {
      req.rawBody = buf;
    },
  })
);

// Webhook na raiz /
app.post("/", (req, res) => {
  const signature = req.headers["x-webhook-signature"];

  if (!signature) {
    return res.status(401).send("Missing signature");
  }

  const expectedSignature = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(req.rawBody)
    .digest("hex");

  // Comparação segura (evita timing attacks)
  const sigOk =
    signature.length === expectedSignature.length &&
    crypto.timingSafeEqual(
      Buffer.from(signature, "hex"),
      Buffer.from(expectedSignature, "hex")
    );

  if (!sigOk) {
    return res.status(403).send("Invalid signature");
  }

  // Webhook válido, loga SOMENTE o payload
  console.log("Payload Ereemby:");
  console.log(JSON.stringify(req.body, null, 2));

  return res.status(200).send("OK");
});

app.listen(3000, () => {
  console.log("Webhook ouvindo em http://localhost:3000/");
});
```

{% endcode %}

#### Testando no PC com ngrok

1. Rode o servidor:

```bash
node server.js
```

2. Exponha a porta 3000:

```bash
ngrok http 3000
```

3. Copie a URL HTTPS gerada (ex: `https://<id>.ngrok-free.app/`).
4. Use essa URL ao criar o webhook no painel da Ereemby.

### Boas práticas (pra não dar dor de cabeça)

* Responda rápido com **HTTP 2xx** e processe em background.
* Trate webhooks como “pelo menos uma vez”. Pode haver reenvio.
* Logue `event`, `orderId` e horário de recebimento.
* Se o Secret vazar, gere outro e atualize sua aplicação.
