Pular para o conteúdo principal

Assinatura

O algoritmo é HmacSHA256. A chave é o segredo completo em UTF-8, inclusive o prefixo whsec_. O segredo não é decodificado como hexadecimal.

O payload assinado é a concatenação timestamp + "." + corpo cru, também em UTF-8. timestamp é o inteiro positivo do cabeçalho, em segundos Unix. O valor do cabeçalho é exatamente:

t=<timestamp>,v1=<64 hex minúsculos>

A expressão regular aceita ^t=([0-9]+),v1=([0-9a-f]{64})$. Cabeçalho vazio, maior que 512 caracteres, timestamp 0 ou hex fora desse formato é inválido. A comparação é do cabeçalho inteiro, em tempo constante (MessageDigest.isEqual), não só do trecho v1.

X-Gateway-Timestamp repete o mesmo epoch. X-Gateway-Event-Id repete o id. X-Gateway-Signature repete MuPag-Signature; o alias é temporário.

Tolerância​

Quem verifica escolhe toleranceSeconds. A janela é simétrica: now ± tolerance. O emissor não grava uma tolerância de produção. Os testes unitários passam 300. Trate 300 segundos como exemplo de teste, não como constante do remetente.

Exemplo​

O corpo abaixo precisa ser o bytes crus recebidos. whsec_example é um placeholder, não um segredo real.

import { createHmac, timingSafeEqual } from "node:crypto";

const secret = "whsec_example";
const toleranceSeconds = 300;
const header = request.headers["mupag-signature"] ?? "";
const match = /^t=([0-9]+),v1=([0-9a-f]{64})$/.exec(header);
if (!match || header.length > 512) {
throw new Error("invalid signature");
}
const timestamp = Number(match[1]);
const now = Math.floor(Date.now() / 1000);
if (!Number.isSafeInteger(timestamp) || timestamp <= 0 || Math.abs(now - timestamp) > toleranceSeconds) {
throw new Error("stale signature");
}
const expected =
"t=" +
timestamp +
",v1=" +
createHmac("sha256", secret).update(timestamp + "." + rawBody).digest("hex");
const valid =
expected.length === header.length &&
timingSafeEqual(Buffer.from(expected), Buffer.from(header));

Registre id e type. Não registre o segredo nem o cabeçalho completo.

Esta página liberou seu próximo passo?

O feedback permanece no fluxo da documentação e nunca deve incluir dados de clientes ou cartões.

mupag / suporte

Como podemos ajudar?

Respostas rápidas, IA e nossa equipe.

Perguntas frequentes

Como começar a integrar?

Siga o início rápido, configure o ambiente de QA e faça sua primeira cobrança de teste.

Ler documentação
Meu PIX ainda está pendente. E agora?

A confirmação é assíncrona. Confira o status da cobrança e os eventos de webhook antes de liberar o pedido.

Ler documentação
Como receber notificações de pagamento?

Cadastre um endpoint de webhook, valide a assinatura e processe eventos repetidos com segurança.

Ler documentação
Como funcionam as assinaturas?

Consulte o guia de assinaturas para configurar recorrência e acompanhar o ciclo das cobranças.

Ler documentação
Onde encontro ajuda com autenticação?

Veja como usar as credenciais do ambiente na documentação. Nunca compartilhe sua chave no chat.

Ler documentação