Los Webhooks salientes te permiten recibir notificaciones HTTP en tu servidor en tiempo real cada vez que ocurren cambios en tu espacio de trabajo.
Configurar un Webhook
- Ve a Ajustes > Webhooks en tu panel de control.
- Haz clic en Crear Webhook.
- Proporciona la URL de destino (debe ser
HTTPSen producción) y selecciona los eventos a escuchar (o*para todos). - Copia el Secret generado. Lo necesitarás para validar la firma de los envíos.
Firma y Seguridad (HMAC-SHA256)
Para garantizar que las peticiones recibidas provienen exclusivamente de Money Manager y no han sido alteradas en tránsito, cada entrega incluye dos cabeceras de firma:
X-Money-Manager-Signature: Hash hexadecimal HMAC-SHA256 del cuerpo firmado con el Secret de tu webhook.X-Money-Manager-Timestamp: Marca de tiempo Unix en milisegundos en la que se generó la petición.
Verificar la Firma en Node.js
const crypto = require('crypto');
function verifyWebhook(secret, timestamp, body, receivedSignature) {
// 1. Validar que la marca de tiempo sea reciente (evita ataques de repetición)
const now = Date.now();
const timestampMs = parseInt(timestamp, 10);
const fiveMinutesMs = 5 * 60 * 1000; // 5 minutos de tolerancia
if (isNaN(timestampMs) || Math.abs(now - timestampMs) > fiveMinutesMs) {
return false;
}
// 2. Calcular la firma esperada
const message = `${timestamp}.${body}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(message)
.digest('hex');
// 3. Mitigar ataques de sincronización comparando las longitudes de los buffers antes del timingSafeEqual
const expectedBuffer = Buffer.from(expectedSignature, 'utf-8');
const receivedBuffer = Buffer.from(receivedSignature || '', 'utf-8');
if (expectedBuffer.length !== receivedBuffer.length) {
return false;
}
return crypto.timingSafeEqual(expectedBuffer, receivedBuffer);
}javascriptEventos Soportados
El sistema dispara webhooks salientes para los siguientes eventos:
transaction.created: Se registró un nuevo movimiento (gasto, ingreso, transferencia).transaction.updated: Se modificó una transacción existente.transaction.deleted: Se eliminó una transacción del espacio de trabajo.wallet.created: Se creó una nueva cuenta o cartera.wallet.updated: Se editó la cartera o se actualizó su balance.goal.created: Se creó una nueva meta de ahorro.goal.updated: Se modificó una meta o se registraron depósitos/retiros de ahorros.budget.created: Se definió un nuevo presupuesto límite mensual.
Payload de Ejemplo (transaction.created)
{
"id": "b3047bfb-1342-45e7-a9a3-5c8e31a0e883",
"type": "transaction.created",
"ts": "1783512720000",
"data": {
"id": "e3097bfb-1342-45e7-a9a3-5c8e31a0e194",
"workspaceId": "d32b508f-2879-45e5-aa06-8b2b60459c56",
"createdByUserId": "user_3FvLYBUm5GJdZBJGiTEFhPtgSrE",
"type": "expense",
"categoryId": "2bb83bfb-9342-42c2-83b3-8a9d12a9e383",
"walletId": "f7893bfb-7823-4df4-8bc9-9a2d34a8e745",
"amount": "250.00",
"concept": "Cena de negocios",
"description": "Reunión con clientes",
"date": "2026-07-08",
"createdAt": "2026-07-08T12:12:00.000Z"
}
}json