Herramienta gratis · Mercado Pago
Validar la firma de un webhook
de Mercado Pago (x-signature)
Pegá lo que te mandó Mercado Pago y mirá si la firma coincide, qué manifest se firmó y el hash esperado al lado del recibido. Pensado para cuando tu handler de webhooks responde 401 y no sabés por qué.
Todo se calcula en tu navegador. La firma se calcula en esta página con la Web Crypto API. Nada de lo que escribís se envía a ningún servidor y el secreto no sale de esta página.
Cómo firma Mercado Pago un webhook
Cada notificación de webhook trae una firma HMAC-SHA256 para que puedas comprobar que viene de Mercado Pago y que no es un replay. Verificarla lleva cinco pasos.
- 01
Separá el header x-signature
El header se ve así: x-signature: ts=1704908010,v1=618c8534…. Cortalo por las comas y después por el primer signo igual de cada parte. ts es el timestamp de la firma (el ejemplo oficial tiene 10 dígitos, es decir segundos; aceptá segundos o milisegundos) y v1 es el hash.
- 02
Juntá las tres entradas
data.id sale del query string de la URL de la notificación (?data.id=123456), x-request-id es un header del request y ts viene del paso uno.
- 03
Armá el manifest
Concatená id:<data.id>;request-id:<x-request-id>;ts:<ts>; exactamente así, con el punto y coma final. Si falta data.id o x-request-id, omití ese segmento completo. El SDK de Go pasa data.id a minúsculas antes de usarlo.
- 04
Calculá el HMAC-SHA256
Firmá el manifest usando como clave el secreto de webhook de tu aplicación y tomá el digest en hexadecimal minúscula.
- 05
Compará y después revisá el timestamp
Comparé tu digest con v1 en tiempo constante y rechazá el request si ts es demasiado viejo. Una ventana de cinco minutos es una elección habitual.
La misma verificación en Node.js
Una implementación sin dependencias de los cinco pasos, con node:crypto. Ponela en una ruta de Express o Next.js y llamala con los headers del request, el parámetro data.id y tu secreto.
1 import { createHmac, timingSafeEqual } from 'node:crypto';
2
3 export function verifyMercadoPagoWebhook(req, secret: string): boolean {
4 const xSignature = req.header('x-signature') ?? '';
5 const xRequestId = req.header('x-request-id') ?? '';
6 const dataId = String(req.query['data.id'] ?? '').toLowerCase();
7
8 const parts = Object.fromEntries(
9 xSignature.split(',').map((p) => p.trim().split('=')),
10 );
11 const { ts, v1 } = parts;
12 if (!ts || !v1) return false;
13
14 let manifest = '';
15 if (dataId) manifest += `id:${dataId};`;
16 if (xRequestId) manifest += `request-id:${xRequestId};`;
17 manifest += `ts:${ts};`;
18
19 const expected = createHmac('sha256', secret).update(manifest).digest('hex');
20 const a = Buffer.from(expected);
21 const b = Buffer.from(v1);
22 if (a.length !== b.length || !timingSafeEqual(a, b)) return false;
23
24 // Replay protection: reject a signed timestamp older than 5 minutes.
25 // Mercado Pago's example ts has 10 digits (seconds); accept seconds or milliseconds.
26 const tsMs = Number(ts) < 1e12 ? Number(ts) * 1000 : Number(ts);
27 return Math.abs(Date.now() - tsMs) <= 5 * 60 * 1000;
28 }
¿Por qué mi firma de Mercado Pago es inválida?
¿Por qué no coincide la firma de mi webhook de Mercado Pago?+
¿data.id tiene que ir en minúsculas?+
¿De dónde sale data.id?+
¿Puedo usar el secreto de otra aplicación?+
La firma es válida acá pero mi servidor la rechaza. ¿Por qué?+
¿Es seguro pegar mi secreto de webhook acá?+
¿Qué notificaciones traen el header x-signature?+
Seguí leyendo
Webhooks de Mercado Pago: validar x-signature
La guía completa en Node.js: manifest de x-signature, HMAC-SHA256, comparación en tiempo constante, anti-replay e idempotencia.
Integración de MercadoPago en useDeploy
Checkout Pro con esta verificación de firma, protección contra replay y un port de billing tipado ya cableado.
| Precio | Founder $99 o Lifetime $199, pago único (sin suscripción) |
|---|---|
| Licencia | Código fuente completo, uso comercial, proyectos ilimitados. Founder es una versión congelada; Lifetime incluye todas las versiones futuras. |
| Stack | Frontend en Next.js, API en Express, runtime Bun, Prisma, BetterAuth |
| Autenticación | BetterAuth: sesiones, 2FA, magic links, reseteo de contraseña |
| Multi-tenancy y RBAC | Organizaciones con miembros, invitaciones, roles y permisos |
| Pagos | Polar: facturación completa (checkout, portal de cliente, webhooks, sincronización de planes). MercadoPago: pagos únicos con Checkout Pro y webhooks firmados; las suscripciones todavía no están soportadas. Stripe: scaffold de adapter, todavía no cobra. |
| Guardrails para agentes de IA | Capas de arquitectura forzadas con ESLint, hooks de Claude Code y un AGENTS.md |
| Reembolso | 14 días |
| Probalo: cuenta gratis | Registrate gratis y explorá el dashboard: organizaciones, roles, facturación, registro de auditoría. La licencia se compra desde adentro. https://usedeploy.dev/register |
| Docs | Documentación en inglés, con traducciones al español y al portugués de las guías principales |