Skip to content
Last updated

Validação HMAC-SHA256 — Webhooks

Os webhooks entregues a Parceiros são assinados com HMAC-SHA256. Valide a assinatura antes de processar qualquer payload para garantir que a requisição veio da Movvia.

Como funciona

A cada entrega de webhook, a Movvia inclui o header X-Movvia-Signature com o HMAC calculado sobre o corpo bruto da requisição usando o segredo compartilhado negociado no onboarding.

X-Movvia-Signature: sha256={hex_do_hmac}

Algoritmo de validação

  1. Leia o corpo da requisição como bytes brutos (não faça parse de JSON antes).
  2. Calcule HMAC-SHA256(corpo_bytes, segredo).
  3. Compare o resultado (em hex) com o valor de X-Movvia-Signature após o prefixo sha256=.
  4. Use comparação em tempo constante (hmac.compare_digest ou equivalente) para evitar timing attacks.
  5. Se os valores coincidirem, processe o evento. Caso contrário, retorne 401 e descarte.

Exemplos de validação

import crypto from 'crypto';

function validarAssinatura(
  corpo: Buffer,
  headerAssinatura: string,
  segredo: string,
): boolean {
  const esperado = 'sha256=' + crypto
    .createHmac('sha256', segredo)
    .update(corpo)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(headerAssinatura),
    Buffer.from(esperado),
  );
}
import hmac
import hashlib

def validar_assinatura(corpo: bytes, header_assinatura: str, segredo: str) -> bool:
    esperado = 'sha256=' + hmac.new(
        segredo.encode(),
        corpo,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(header_assinatura, esperado)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;

public boolean validarAssinatura(byte[] corpo, String headerAssinatura, String segredo) throws Exception {
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(segredo.getBytes(), "HmacSHA256"));
    String esperado = "sha256=" + bytesToHex(mac.doFinal(corpo));
    return MessageDigest.isEqual(headerAssinatura.getBytes(), esperado.getBytes());
}

Catálogo de eventos

Os eventos seguem o padrão pe.<modulo>.<evento>. Exemplos:

EventoDescrição
pe.transacao.recebidaNova passagem detectada para uma placa cadastrada.
pe.pedidos.confirmadoPedido confirmado pelo parceiro.
pe.pedidos.canceladoPedido cancelado.

O catálogo completo está na Referência da API de Parceiros.

Retry e entrega garantida

A Movvia retentar a entrega com backoff exponencial por até 24 horas em caso de falha (timeouts ou respostas 5xx). Implemente idempotência no seu receptor para lidar com entregas duplicadas em caso de retentativa.

Veja: Idempotência

Endpoint de recepção

Seu endpoint de webhook deve responder com 200 OK dentro de 5 segundos. Processe o evento de forma assíncrona se necessário.