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

# Configuração de Webhook

> Implemente e configure endpoints de webhook

## Configuração Passo a Passo

<Steps>
  <Step title="Criar Endpoint">
    Construa endpoint POST para receber webhooks

    ```javascript theme={null}
    app.post('/webhooks/killb', async (req, res) => {
      // Lidar com webhook
      res.status(200).json({ received: true });
    });
    ```
  </Step>

  <Step title="Verificar Assinaturas">
    Implemente verificação HMAC

    ```javascript theme={null}
    const crypto = require('crypto');

    const verifySignature = (payload, signature, secret) => {
      const expected = crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');
      return signature === expected;
    };
    ```
  </Step>

  <Step title="Registrar Webhook">
    Configure na KillB

    ```bash theme={null}
    POST /api/v2/webhooks
    {
      "url": "https://api.seuapp.com/webhooks/killb",
      "secret": "sua-chave-secreta",
      "events": ["RAMP", "USER"]
    }
    ```
  </Step>

  <Step title="Testar">
    Crie ramp de teste e verifique recebimento de webhook
  </Step>
</Steps>

## Implementação Completa

<CodeGroup>
  ```javascript Express.js theme={null}
  const express = require('express');
  const crypto = require('crypto');

  const app = express();

  // IMPORTANTE: Use corpo bruto para verificação de assinatura
  app.use('/webhooks/killb', express.raw({type: 'application/json'}));

  app.post('/webhooks/killb', async (req, res) => {
    try {
      // 1. Verificar assinatura
      const signature = req.headers['x-signature-sha256'];
      const payload = req.body.toString();
      
      const expectedSignature = crypto
        .createHmac('sha256', process.env.WEBHOOK_SECRET)
        .update(payload)
        .digest('hex');
      
      if (signature !== expectedSignature) {
        console.error('Assinatura inválida');
        return res.status(401).json({ error: 'Assinatura inválida' });
      }
      
      // 2. Reconhecer imediatamente
      res.status(200).json({ received: true });
      
      // 3. Processar assincronamente
      const event = JSON.parse(payload);
      processWebhookAsync(event).catch(console.error);
      
    } catch (error) {
      console.error('Erro de webhook:', error);
      res.status(500).json({ error: 'Processamento falhou' });
    }
  });

  app.listen(3000);
  ```

  ```python FastAPI theme={null}
  from fastapi import FastAPI, Header, HTTPException, Request
  import hmac
  import hashlib
  from typing import Optional

  app = FastAPI()

  @app.post("/webhooks/killb")
  async def webhook_handler(
      request: Request,
      x_webhook_signature: Optional[str] = Header(None)
  ):
      # Obter corpo bruto
      body = await request.body()
      
      # Verificar assinatura
      expected_signature = hmac.new(
          WEBHOOK_SECRET.encode(),
          body,
          hashlib.sha256
      ).hexdigest()
      
      if not hmac.compare_digest(x_webhook_signature or '', expected_signature):
          raise HTTPException(status_code=401, detail="Assinatura inválida")
      
      # Analisar evento
      event = await request.json()
      
      # Processar assincronamente
      from fastapi import BackgroundTasks
      background_tasks = BackgroundTasks()
      background_tasks.add_task(process_webhook, event)
      
      return {"received": True}
  ```
</CodeGroup>

## Testando Localmente

Use ngrok para testes locais:

```bash theme={null}
# Iniciar servidor local
npm start

# Expor via ngrok
ngrok http 3000

# Usar URL ngrok
# https://abc123.ngrok.io/webhooks/killb
```

## Próximos Passos

<CardGroup cols={2}>
  <Card title="Referência de Eventos" icon="list" href="/pt/guides/webhooks/events">
    Todos os tipos de evento de webhook
  </Card>

  <Card title="Segurança" icon="shield" href="/pt/guides/webhooks/security">
    Proteja seus webhooks
  </Card>
</CardGroup>
