Deduplicación
Por qué importa
Dado que existen reintentos in-process y persistentes, es esperable que un mismo evento se reciba más de una vez. Sin deduplicación, la misma factura podría marcarse dos veces como “aceptado”, podrían enviarse correos repetidos o podría ejecutarse dos veces la lógica de negocio.
Mecanismo
Cada envío incluye dos campos pensados para detectar la repetición:
nonce— identificador único por intento de envío (32 caracteres hexadecimales, 16 bytes).intento— número del intento (1 a 5).
Debe utilizarse
noncecomo clave de deduplicación, nuncaclaveninumero_consecutivo: estos últimos sí se repiten entre intentos, porque pertenecen al comprobante y no al envío.
Patrón
Se recomienda emplear un índice único en la BD para que la deduplicación sea atómica: si el INSERT falla por colisión, el evento ya fue procesado y la ejecución puede finalizar sin afectar el resto del flujo.
async function procesarWebhook(evento) {
try {
await db.eventosLxs.create({
data: { nonce: evento.nonce, payload: evento, procesadoEn: new Date() }
});
} catch (err) {
if (err.code === 'P2002') { // unique constraint violation
// Ya procesado, descartar
return;
}
throw err;
}
await aplicarLogicaDeNegocio(evento);
}