Pular para o conteúdo principal

Webhooks

🛂 Permissão: webhook.manage 🔒 Plano: requer webhooks_enabled no plano contratado. 📍 Caminho: Configurações → Webhooks

Webhooks permitem que sistemas externos sejam notificados em tempo real sobre eventos do tenant (pedido criado, cliente atualizado, entrega concluída etc.). É a melhor abordagem para integrações orientadas a eventos.

Eventos suportados

EventoQuando dispara
order.createdNovo pedido criado (canal qualquer).
order.status_changedPedido muda de status (Pending → In_Transit → Delivered → Canceled).
order.payment_confirmedPagamento confirmado (manual ou via gateway).
customer.createdCliente novo cadastrado.
customer.updatedCliente alterado.
product.createdNovo produto.
product.updatedProduto alterado.
product.deletedProduto excluído.
delivery.completedEntrega concluída.
delivery.failedEntrega falhou (com motivo).

Como cadastrar um endpoint

  1. Em Configurações → Webhooks, clique em Novo Webhook.
  2. Preencha:
    • URL — endpoint do seu sistema (HTTPS recomendado).
    • Descrição — identificação interna.
    • Eventos — selecione um ou mais (multi-checkbox).
    • Ativo — toggle.
  3. Salve.

A plataforma gera automaticamente um secret de 64 caracteres usado para assinar os payloads (HMAC).

Formato do payload

Cada entrega é um POST JSON:

POST https://seu-endpoint/365vendas HTTP/1.1
Content-Type: application/json
X-365Vendas-Event: order.created
X-365Vendas-Delivery-Id: 7f9c3a12-...
X-365Vendas-Signature: sha256=abc123...
X-365Vendas-Timestamp: 1745692800

{
"event_type": "order.created",
"event_id": "7f9c3a12-...",
"tenant_id": 42,
"occurred_at": "2026-04-26T12:00:00Z",
"data": {
"order_id": 1234,
"customer_id": 567,
"total": 199.90,
"status": "Pending",
"..."
}
}

Verificando a assinatura

No seu endpoint, valide o header X-365Vendas-Signature:

import hmac, hashlib

expected = hmac.new(
secret.encode(),
f"{timestamp}.{raw_body}".encode(),
hashlib.sha256
).hexdigest()

# header é "sha256=<hex>"
received = signature.split("=")[1]

if not hmac.compare_digest(expected, received):
return 401 # Rejeitar

Sempre valide a assinatura antes de processar. Sem isso, qualquer um pode forjar requests.

Retentativas

Quando o seu endpoint não responde 2xx, a plataforma tenta de novo:

  • Até 5 tentativas.
  • Backoff exponencial (1m, 5m, 15m, 1h, 6h).
  • Cada entrega gera um registro WebhookDelivery com:
    • status (PENDING, SUCCESS, FAILED, RETRYING)
    • response_status, response_body (truncado em 1KB)
    • attempt_number, next_retry_at, duration_ms

Após esgotar as tentativas, o registro fica em FAILED. Você pode reenviar manualmente pelo painel.

Reenviar entrega manualmente

Em Configurações → Webhooks → ver entregas:

  • Filtre por FAILED ou específico.
  • Clique em Reenviar para uma entrega individual.

Histórico de entregas

A aba Entregas lista todas as tentativas com:

  • Evento, status, código HTTP, duração.
  • Botão Ver payload (corpo enviado).
  • Botão Ver resposta (corpo recebido — útil para debugar).

Idempotência

Cada evento tem um event_id único (UUID). Se você receber o mesmo event_id mais de uma vez (por causa de retry), trate como idempotente — não duplique a operação.

Boas práticas

  • HTTPS sempre — nunca configure URL HTTP em produção.
  • Valide a assinatura — é o que garante autenticidade.
  • Responda rápido (< 5 segundos) com 2xx — coloque o processamento pesado em fila assíncrona.
  • Persista o event_id recebido — fonte de verdade para idempotência.
  • Use um endpoint dedicado por evento (ex.: /webhooks/365vendas/orders) ou faça roteamento pelo header X-365Vendas-Event.
  • Monitore o painel periodicamente para ver entregas em FAILED — sinal de degradação.

Limites e custos

  • Sem custo adicional dentro do plano.
  • Não há limite duro de eventos, mas eventos disparados em rajada podem ser entregues com pequeno atraso (worker assíncrono).