Skip to content

Webhooks

A Movvia entrega eventos em tempo real via HTTP POST no endpoint que você registrar. Todos os payloads são assinados com HMAC-SHA256.

Estrutura do evento

{
  "evento": "pe.transacao.recebida",
  "versao": "2",
  "id": "evt_8f3a1b2c",
  "timestamp": "2026-04-24T10:00:00Z",
  "parceiroId": "par_7f3a1b2c",
  "dados": {
    "transacaoId": "t_9f2c7e1a",
    "placa": "ABC1D23",
    "valor": 12.50,
    "praca": "KM 245 — Imigrantes",
    "criadoEm": "2026-04-24T09:58:00Z"
  }
}

Catálogo de eventos

EventoQuando ocorre
pe.transacao.recebidaNova passagem capturada para uma placa monitorada
pe.transacao.atualizadaValor ou status de uma passagem foi revisado
pe.transacao.canceladaPassagem cancelada pelo EC
pe.pedidos.confirmadoPedido confirmado com sucesso
pe.pedidos.canceladoPedido cancelado
pe.pedidos.expiradoPedido expirou sem confirmação (48h)

Verificar a assinatura HMAC-SHA256

O header x-movvia-signature contém a assinatura do payload. Sempre verifique antes de processar.

import crypto from 'crypto';

function verificarAssinatura(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// No seu handler:
app.post('/webhook', (req, res) => {
  const assinatura = req.headers['x-movvia-signature'] as string;
  const payload = JSON.stringify(req.body);

  if (!verificarAssinatura(payload, assinatura, process.env.MV_WEBHOOK_SECRET!)) {
    return res.status(401).send('Assinatura inválida');
  }

  // processar evento
  res.status(200).send('OK');
});
import hashlib, hmac, os

def verificar_assinatura(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), payload, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Tutorial completo em Validar HMAC.

Retentativas

A Movvia faz retry automático em caso de falha (status != 2xx ou timeout):

TentativaIntervalo
1ª (original)
1 min
5 min
30 min
2h
6h
24h

Após 7 tentativas sem sucesso, o evento é marcado como falha_definitiva e um alerta é enviado por email.

Requisitos do endpoint

  • Responder em até 5 segundos com status 2xx.
  • Processar de forma idempotente — o mesmo evento pode ser entregue mais de uma vez.
  • Aceitar Content-Type: application/json.
  • HTTPS obrigatório em produção.
Processar de forma assíncrona

Responda 200 imediatamente e processe o evento em background. Não faça operações lentas (banco, chamadas externas) dentro do handler síncrono.

Registrar o endpoint

O endpoint de webhook é configurado no onboarding. Para alterar, entre em contato com comercial@movvia.com.br.