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

# Webhooks

> Receba notificações automáticas da Alpa sempre que algo importante acontecer — como um pagamento confirmado ou um saque concluído.

Pense nos webhooks como **"mensagens enviadas pela Alpa para o seu sistema"**, sem que você precise ficar consultando a API o tempo todo.

***

## Por que usar webhooks?

Sem webhooks, sua aplicação teria que **perguntar para a API a cada segundo** se uma transação já foi confirmada. Isso é lento e ineficiente.

Com webhooks, a Alpa avisa você **imediatamente** quando o pagamento é confirmado, entregando os dados do evento. Assim você pode atualizar o status de um pedido, liberar acesso a um produto, enviar e-mails de confirmação ou registrar movimentações financeiras — de forma automática.

***

## Ambientes (Desenvolvimento vs Produção)

<Card title="Ambientes da Alpa" horizontal>
  * Webhooks criados com chaves de **Desenvolvimento** recebem eventos simulados
  * Webhooks criados com chaves de **Produção** recebem eventos reais
</Card>

***

## Formato do payload

Todos os eventos compartilham o mesmo envelope:

```json theme={null}
{
  "id": "f7c1b2a0-...",
  "type": "transaction.completed",
  "data": { },
  "timestamp": "2026-05-25T14:30:00.000Z",
  "subscription": {
    "id": "sub_abc123",
    "url": "https://meusite.com/webhooks/alpa"
  }
}
```

O campo **`type`** identifica o evento. O campo **`data`** carrega os dados do objeto afetado.

### Exemplo: `transaction.completed`

```json theme={null}
{
  "id": "f7c1b2a0-...",
  "type": "transaction.completed",
  "timestamp": "2026-05-25T14:30:00.000Z",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "PAID",
    "amountCents": 9900,
    "paymentMethod": "PIX",
    "clientEmail": "joao@example.com",
    "createdAt": "2026-05-25T14:29:00.000Z",
    "paidAt": "2026-05-25T14:30:00.000Z"
  }
}
```

<Info>
  **Dados sensíveis:** documentos (CPF/CNPJ) são mascarados nos payloads. Para cartão, apenas os últimos 4 dígitos e a bandeira são enviados.
</Info>

***

## Eventos suportados

| Evento (`type`)                                                       | Quando é disparado                              |
| --------------------------------------------------------------------- | ----------------------------------------------- |
| `transaction.created`                                                 | Nova transação criada (status `PENDING`)        |
| `transaction.updated`                                                 | Status da transação alterado                    |
| `transaction.completed`                                               | Pagamento confirmado e saldo creditado (`PAID`) |
| `transaction.failed`                                                  | Pagamento falhou (`FAILED`)                     |
| `transaction.refunded`                                                | Reembolso concluído                             |
| `payment_link.created`                                                | Novo link de pagamento criado                   |
| `payment_link.updated`                                                | Link de pagamento atualizado                    |
| `balance.updated`                                                     | Saldo da carteira atualizado                    |
| `subscription.cancelled`                                              | Assinatura cancelada                            |
| `kyc.submitted` / `kyc.approved` / `kyc.rejected`                     | Mudanças no status de KYC                       |
| `advance.created` / `advance.approved` / `advance.rejected`           | Antecipações                                    |
| `withdrawal.requested` / `withdrawal.completed` / `withdrawal.failed` | Saques                                          |

***

## Segurança: assinatura HMAC

Cada webhook enviado pela Alpa inclui uma assinatura no header `X-Webhook-Signature`, gerada com **HMAC-SHA256** sobre o corpo bruto da requisição e codificada em **hexadecimal** (prefixada por `sha256=`).

Seu backend deve recalcular a assinatura e comparar com a recebida usando comparação em tempo constante.

```typescript theme={null}
import crypto from "node:crypto";

export function verifyAlpaSignature(
  rawBody: string,
  signatureFromHeader: string, // valor do header X-Webhook-Signature
  secret: string
): boolean {
  const received = signatureFromHeader.replace(/^sha256=/, "");
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody, "utf8")
    .digest("hex");

  const a = Buffer.from(expected);
  const b = Buffer.from(received);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```

<Warning>
  Use o **corpo bruto** (raw body) para validar — não o JSON re-serializado. Sempre valide a assinatura antes de processar o evento.
</Warning>

> Usando um dos SDKs oficiais? Eles já trazem `verifyWebhookSignature(payload, signature, secret)` pronto.

***

## Criando uma assinatura de webhook

<Steps>
  <Step title="Defina seu endpoint">
    Crie um endpoint HTTPS público que receberá as notificações.

    <Card title="Requisitos do endpoint" horizontal>
      * Deve ser **HTTPS** (HTTP não é aceito)
      * Deve responder **200 OK** dentro de 10 segundos
      * Deve aceitar requisições `POST` com body JSON
    </Card>
  </Step>

  <Step title="Crie a assinatura via API">
    ```bash theme={null}
    curl -X POST "https://alpa-sistema-api.onrender.com/api/v1/webhooks/subscriptions" \
      -H "Authorization: Bearer SUA_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "url": "https://meusite.com/webhooks/alpa",
        "events": ["transaction.completed", "withdrawal.completed"]
      }'
    ```

    A resposta inclui o `secret` da assinatura **apenas na criação** — guarde-o com segurança.
  </Step>

  <Step title="Valide os eventos recebidos">
    Implemente a validação HMAC no seu endpoint para garantir que os eventos são legítimos.
  </Step>
</Steps>

***

## Boas práticas

<Card title="Recomendações importantes" horizontal>
  * Use **HTTPS** em todos os webhooks
  * Valide a **assinatura HMAC** em cada requisição recebida
  * Processe cada evento **uma única vez** (idempotência via campo `id`)
  * Responda **200 OK** somente após concluir o processamento
  * **Não valide o payload inteiro** com schemas rígidos — novos campos podem ser adicionados sem aviso prévio
</Card>

***

<Card title="Precisa de ajuda?" icon="headset" color="#FF3D02">
  Nossa equipe pode te ajudar. Contate-nos: <Icon icon="envelope" type="solid" /> [suporte@usealpa.com](mailto:suporte@usealpa.com)
</Card>
