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

# Webhooks

> Receba notificações em tempo real quando faturas são pagas, reembolsadas ou recusadas.

Webhooks são a forma do Simplo te avisar **quando algo acontece** — sem você precisar ficar consultando a API em loop.

Você configura uma URL pública na sua conta. Quando um evento ocorre, o Simplo envia um `POST` com JSON para essa URL.

## Configurar

<Steps>
  <Step title="Crie um endpoint no seu app">
    Uma rota HTTP pública que aceita `POST` com JSON. Pode ser em qualquer linguagem ou framework.
  </Step>

  <Step title="Cadastre a URL no painel">
    No Simplo, vá em **Configurações → Webhooks** e cole a URL (`https://`, não `http://`).
  </Step>

  <Step title="Escolha os eventos">
    Marque quais tipos você quer receber (ou marque todos).
  </Step>
</Steps>

## Eventos disponíveis

| Evento            | Quando dispara                                   |
| ----------------- | ------------------------------------------------ |
| `invoice.created` | Fatura foi gerada (ainda não paga)               |
| `invoice.paid`    | Fatura recebeu pagamento confirmado              |
| `invoice.voided`  | Fatura foi cancelada                             |
| `charge.created`  | Cobrança foi tentada (boleto/cartão/Pix gerado)  |
| `charge.refunded` | Cobrança foi reembolsada (total ou parcialmente) |
| `charge.rejected` | Cobrança foi recusada (cartão negado, etc.)      |

A lista completa, com schema de cada payload, está na [referência da API](/api-reference/introducao).

## Estrutura do payload

Todo webhook tem o mesmo envelope:

```json theme={null}
{
  "event": {
    "id": "nevt_01h455vb4pex5vsknk084sn02e",
    "type": "invoice.paid",
    "created_at": 1741541400,
    "data": {
      "invoice": {
        "id": "in_01h455vb4pex5vsknk084sn02q",
        "status": "paid",
        "amount": 2990,
        "paid_at": 1741541400
      },
      "customer": {
        "id": "cus_01h455vb4pex5vsknk084sn02p"
      },
      "subscription": {
        "id": "sub_01h455vb4pex5vsknk084sn02s"
      }
    }
  }
}
```

* `event.id` — identificador único do evento. **Use para deduplicação** no seu lado (veja abaixo).
* `event.type` — qual evento aconteceu.
* `event.created_at` — timestamp Unix em segundos.
* `event.data` — os recursos relacionados.

## Boas práticas

### 1. Responda rápido (timeout de 15s)

O Simplo aguarda até **15 segundos** pela resposta (com timeout de conexão de 5 segundos). Se passar disso, a entrega é marcada como falha e o evento **não é reentregue automaticamente**.

A regra de ouro: **valide e enfileire**. Não processe o evento direto na request — armazene o payload, retorne `200` rápido, e processe em job de background.

```ruby theme={null}
# Rails — controller do webhook
class WebhooksController < ApplicationController
  skip_before_action :verify_authenticity_token

  def create
    event = SimploEvent.create!(payload: request.raw_post)
    ProcessSimploEventJob.perform_later(event.id)
    head :ok
  end
end
```

### 2. Deduplique pelo `event.id`

Mesmo que o Simplo entregue cada evento uma única vez hoje, é recomendável deduplicar pelo `event.id` no seu lado — isso te protege contra reprocessamento acidental do seu próprio sistema (re-deploy, replay manual de fila, etc.):

```ruby theme={null}
def perform(event_id)
  return if ProcessedEvent.exists?(event_id: event_id)

  # ... processa o evento ...

  ProcessedEvent.create!(event_id: event_id)
end
```

### 3. Sempre retorne 2xx no sucesso

Códigos `200`, `201`, `204` são todos válidos. Qualquer 4xx ou 5xx é tratado como falha.

### 4. Cada evento é entregue uma única vez

Hoje o Simplo **não faz retry automático** de webhooks com falha. Cada evento é entregue **uma única vez** — se sua URL retornar erro ou estourar o timeout de 15 segundos, o evento fica marcado como falho e não é reentregue.

Por isso vale extra cuidado:

* Sempre retorne `2xx` rapidamente, mesmo que o processamento ainda não tenha acontecido (use jobs de background).
* Logue o `event.id` em todas as falhas — você pode precisar reprocessar manualmente.
* Monitore a saúde do seu endpoint. Toda entrega (sucesso ou falha) fica registrada no painel.

### 5. Saúde do webhook e desativação automática

Para proteger sua integração contra endpoints quebrados, o Simplo monitora falhas consecutivas:

* A cada falha, um contador de **falhas consecutivas** incrementa.
* A cada sucesso, o contador volta a zero.
* Após **5 falhas consecutivas**, o webhook é marcado como `unhealthy` e **as próximas entregas são pausadas**.
* O dono da conta recebe uma notificação avisando da pausa.

Para reativar, conserte seu endpoint e vá em **Configurações → Webhooks** no painel para retomar as entregas.

<Warning>
  Como não há retry automático, todo evento perdido durante o período de falha precisa ser reprocessado manualmente — geralmente consultando a API para reconstruir o estado.
</Warning>

## Testar localmente

Use ferramentas como [ngrok](https://ngrok.com) ou [cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) para expor seu servidor local:

```bash theme={null}
ngrok http 3000
# Cole a URL https://xxxx.ngrok.io/webhooks/simplo no painel
```

Para ver eventos reais, gere uma cobrança no ambiente de sandbox — a fatura paga dispara `invoice.paid` para sua URL.
