Habla con una persona real
Sin bots, sin vueltas. Te mostramos Kleva en vivo.
Actualizar un convenio de pago sin los controles adecuados puede reintroducir intereses que ya fueron condonados, generando cobros indebidos, reclamos del deudor y sanciones regulatorias. En fintech, bancos y BPOs de cobranza, este error técnico erosiona la confianza del cliente y expone a la empresa a auditorías de CNBV, SIC o BCRA.
Este artículo detalla el orden correcto de operaciones, controles de sistema y trazabilidad obligatoria para evitar que la actualización de un convenio recalcule intereses condonados. Dirigido a CFOs, directores financieros y gerentes de cobranza que operan plataformas de recuperación con IA en Latinoamérica.

Un convenio de pago típico en LATAM incluye tres componentes: capital adeudado, intereses ordinarios acumulados hasta la fecha del convenio, e intereses moratorios. La condonación puede aplicarse sobre intereses moratorios (parcial o total), intereses ordinarios (menos común), o ambos.
El problema surge cuando el sistema de cobranza no separa el saldo condonado del saldo exigible al momento de actualizar el convenio. Por ejemplo:
Esto ocurre porque la mayoría de plataformas legacy tratan la actualización como "crear un nuevo convenio desde cero" en vez de "modificar el convenio existente preservando su contexto". Sin un campo explícito de "monto_condonado_original", la reliquidación vuelve al saldo bruto.
Análisis de incidentes en operaciones de cobranza automatizada revelan cuatro causas recurrentes:
Sistemas que registran la condonación como "aplicar descuento" sin crear un campo descuento_aplicado asociado al convenio. Al modificar el convenio, el sistema consulta saldo_bruto (que nunca cambió) y recalcula cuotas sobre ese monto. Solución: tabla convenio_descuentos con columnas monto_condonado, tipo_interes (ordinario/moratorio), fecha_condonacion, vinculada por convenio_id.
Scripts de actualización que ejecutan SELECT capital + intereses_acumulados WHERE cuenta_id = X sin filtrar por WHERE fecha . Si pasaron 3 meses desde el convenio, intereses_acumulados incluye nuevos intereses de las cuotas vencidas, sumándolos al saldo condonado original. Solución: congelar el snapshot del convenio en convenio_saldo_original y reliquidar solo sobre ese valor.
Actualizar el registro del convenio con UPDATE convenios SET cuotas = 18 WHERE id = 123 sobrescribe el convenio anterior. Si algo falla, no hay forma de saber cuál era el saldo condonado antes. Solución: tabla convenio_versiones con version_numero, fecha_creacion, usuario, razon_modificacion, y copiar todas las columnas relevantes (cuotas, monto, descuentos) por versión.
En plataformas B2B con módulos de "Condonación" y "Convenios" separados, la condonación registra un ajuste contable pero no notifica al módulo de convenios. Al actualizar, el módulo de convenios consulta el ledger financiero (que sí tiene el saldo bruto) y recalcula desde ahí. Solución: event bus interno que emita CondonacionAplicada con cuenta_id, monto_condonado, tipo, y que el módulo de convenios suscriba ese evento para actualizar su caché.

El proceso seguro en tres pasos (aplicado en plataformas de cobranza de fintech en México y Colombia):
PasoAcciónResultadoRegistro de sistema
1. ReliquidarCalcular el saldo real a la fecha de negociación: capital + intereses ordinarios + intereses moratorios desde origen hasta hoy.Saldo bruto actualizado (ej: $130,000).INSERT INTO saldo_snapshot (cuenta_id, fecha, saldo_bruto, capital, int_ordinario, int_moratorio)
2. CondonarAplicar quita sobre intereses: restar monto condonado del saldo bruto.Saldo neto post-condonación (ej: $105,000).INSERT INTO condonaciones (cuenta_id, monto, tipo, fecha, aprobador)
3. ConvenirCrear convenio sobre el saldo neto. El sistema debe almacenar saldo_convenio = saldo_neto y monto_condonado_referencia = X.Convenio con cuotas = $105,000 / N.INSERT INTO convenios (cuenta_id, saldo_original, monto_condonado, cuotas, fecha_inicio, vigente = true)
Regla crítica: al actualizar el convenio (paso 3 repetido), NO volver al paso 1. La reliquidación solo ocurre una vez al crear el convenio original. Las modificaciones posteriores operan sobre saldo_original del convenio, no sobre el ledger de la cuenta.
Ejemplo de actualización segura (extender de 12 a 18 cuotas):
-- INCORRECTO: recalcular desde ledger
UPDATE convenios
SET cuotas = 18,
monto_cuota = (SELECT capital + intereses FROM cuentas WHERE id = X) / 18 -- ❌ vuelve al saldo bruto
WHERE id = 123;
-- CORRECTO: reliquidar sobre saldo_original del convenio
UPDATE convenios
SET cuotas = 18,
monto_cuota = saldo_original / 18, -- ✅ usa el saldo ya condonado
version = version + 1,
fecha_modificacion = NOW()
WHERE id = 123;
Plataformas B2B de cobranza implementan estos safeguards técnicos:
Tabla convenios debe tener columna monto_condonado_total DECIMAL NOT NULL DEFAULT 0 marcada como READ-ONLY después de la creación. Cualquier UPDATE que intente modificarla debe ser rechazado por el ORM o trigger de base de datos:
CREATE TRIGGER convenio_condonacion_immutable
BEFORE UPDATE ON convenios
FOR EACH ROW
BEGIN
IF OLD.monto_condonado_total != NEW.monto_condonado_total THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'monto_condonado_total es inmutable';
END IF;
END;
Antes de ejecutar un UPDATE convenios, ejecutar función de validación que compare saldo_original con el saldo calculado desde el ledger. Si difieren por más de un threshold (ej: 1%), rechazar la actualización y escalar a aprobación manual.
-- Función de validación
CREATE FUNCTION validar_saldo_convenio(convenio_id INT) RETURNS BOOLEAN AS $$
DECLARE
saldo_convenio DECIMAL;
saldo_ledger DECIMAL;
BEGIN
SELECT saldo_original INTO saldo_convenio FROM convenios WHERE id = convenio_id;
SELECT capital + intereses INTO saldo_ledger FROM cuentas WHERE id = (SELECT cuenta_id FROM convenios WHERE id = convenio_id);
IF ABS(saldo_convenio - saldo_ledger) / saldo_ledger > 0.01 THEN
RETURN FALSE; -- Diferencia > 1%, rechazar
END IF;
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
Siguiendo el patrón de ComunidadFeliz (plataforma de cobranza para condominios en Chile), convenios no pueden editarse desde el módulo de Recaudación. Solo el módulo de Convenios tiene permisos de escritura. Esto previene que un analista de cobranza, al aplicar un pago, accidentalmente modifique el convenio base.
Tabla convenio_audit_log que registra cada UPDATE con un JSON diff de campos modificados:
INSERT INTO convenio_audit_log (convenio_id, usuario_id, timestamp, campos_modificados)
VALUES (123, 'analista@empresa.com', NOW(),
'{"cuotas": {"old": 12, "new": 18}, "monto_cuota": {"old": 8750, "new": 5833.33}}'
);
Si campos_modificados incluye "saldo_original" o "monto_condonado_total", disparar alerta a compliance.

Para auditorías de SIC (Colombia), CNBV (México) o BCRA (Argentina), la plataforma debe poder responder: "¿Qué intereses se condonaron en el convenio original, y cómo se preservaron al extenderlo?"
Documento de trazabilidad mínimo por convenio:
Exportar este documento como PDF con firma digital del sistema al cerrar el convenio (totalmente pagado o incumplido). Guardar en bucket S3 con retención de 10 años (requisito CNBV para contratos de crédito en México).
Kleva implementa controles nativos en su motor de cobranza con IA para garantizar que los intereses condonados nunca se recalculan al modificar un convenio de pago negociado por un voice agent.
Cuando el voice agent de Kleva negocia un convenio con el deudor (ej: "Le ofrezco pagar $105,000 en 12 cuotas sin intereses adicionales"), el sistema:
Si el cliente llama 2 meses después solicitando extender de 12 a 18 cuotas, el voice agent:
Durante la llamada de actualización, el voice agent de Kleva verbaliza:
"Su convenio original era de $105,000 en 12 cuotas, con $25,000 de intereses perdonados. Ha pagado 4 cuotas ($35,000). Su saldo pendiente es $70,000. Si extendemos a 18 cuotas, cada cuota sería de $3,889. Los $25,000 de intereses perdonados se mantienen. ¿Acepta estas condiciones?"
Esta confirmación verbal en cada modificación reduce reclamos por "cobros no autorizados" a cero en los clientes de Kleva (0 violaciones regulatorias en 900,000+ minutos de llamadas en LATAM).
Cada modificación de convenio por voice agent genera:
Notificación vía WhatsApp con resumen del convenio modificado enviada al cliente en
Para más información sobre cómo Kleva integra voice agents con plataformas de cobranza con IA, ver nuestra guía de implementación.
Depende de cómo esté diseñado el sistema de cobranza. En sistemas legacy sin controles, la actualización puede recalcular el saldo desde el ledger original, reintroduciendo intereses que ya fueron perdonados. Sistemas correctamente diseñados preservan el monto_condonado_original como campo inmutable y reliquidan solo sobre el saldo neto del convenio. Antes de actualizar, verificar que el sistema tenga una tabla de condonaciones vinculada al convenio y que la lógica de actualización consulte saldo_original del convenio, no el saldo bruto de la cuenta.
Implementar tres controles técnicos: (1) Campo inmutablemonto_condonado en la tabla de convenios, con trigger de base de datos que rechace cualquier UPDATE que intente modificarlo. (2) Snapshot del saldo original en una columna saldo_original que congela el monto condonado al crear el convenio; las actualizaciones operan sobre ese snapshot, no sobre el ledger de la cuenta. (3) Validación pre-actualización que compare saldo_original vs saldo_ledger y rechace si difieren >1%, escalando a aprobación manual. Estos controles previenen que scripts de reliquidación vuelvan al saldo bruto.
El orden seguro es: (1) Reliquidar el saldo bruto a la fecha de negociación (capital + intereses ordinarios + moratorios acumulados desde origen). (2) Condonar la quita acordada sobre intereses (restar del saldo bruto). (3) Convenir el saldo neto post-condonación en N cuotas. Nunca volver al paso 1 al actualizar el convenio; las modificaciones posteriores (extender cuotas, diferir vencimientos) operan sobre el saldo_original del convenio (resultado del paso 2), no sobre el ledger de la cuenta. Esto garantiza que la condonación no se pierda.
Cinco controles mínimos en plataformas B2B de cobranza: (1) Tabla convenio_descuentos con columnas monto_condonado, tipo_interes, fecha_condonacion, vinculada por convenio_id. (2) Trigger de inmutabilidad que rechace UPDATEs sobre monto_condonado_total. (3) Bloqueo de edición desde módulos externos: solo el módulo de Convenios puede modificar convenios, no Recaudación ni Cobranza. (4) Versionado de convenios: tabla convenio_versiones que registra cada modificación con diff de campos. (5) Event bus interno que emita CondonacionAplicada para sincronizar módulos desacoplados. Estos controles previenen reliquidaciones accidentales.
Implementar versionado de convenios con tabla convenio_versiones que contenga: version_numero (autoincremental), convenio_id (FK), fecha_creacion, usuario, razon_modificacion (texto libre), y copia de todos los campos relevantes (cuotas, monto_cuota, saldo_original, monto_condonado, fecha_inicio, fecha_fin). Cada UPDATE al convenio crea una nueva fila en convenio_versiones (INSERT) en vez de sobrescribir el registro antiguo. La tabla convenios mantiene una columna version_actual apuntando a la última versión. Esto permite auditorías de "¿qué cambió entre v1 y v3?" mediante diff de versiones.
Campos mínimos en tabla convenios: saldo_original (DECIMAL, monto sobre el cual se calculan cuotas), monto_condonado_total (DECIMAL, suma de condonaciones aplicadas antes de crear el convenio, inmutable), version (INT, número de versión del convenio), fecha_creacion (TIMESTAMP). Campos en tabla convenio_descuentos: convenio_id (FK), monto (DECIMAL, monto condonado en esta línea), tipo_interes (ENUM: ordinario/moratorio), fecha_aplicacion (TIMESTAMP), aprobador (VARCHAR, usuario o sistema que aprobó). Estos campos permiten reconstruir el saldo neto y auditar cada condonación.
Ejecutar query de validación mensual: SELECT c.id, c.saldo_original, c.monto_condonado_total, SUM(p.monto) AS total_cobrado FROM convenios c JOIN pagos p ON p.convenio_id = c.id WHERE c.vigente = false GROUP BY c.id HAVING total_cobrado > c.saldo_original. Esto detecta convenios donde el monto cobrado excedió el saldo_original (señal de que se cobraron intereses condonados). Para cada caso, extraer convenio_versiones y convenio_audit_log para identificar cuándo se reintrodujeron los intereses. Exportar informe a compliance. Ejecutar también SELECT * FROM convenio_audit_log WHERE campos_modificados LIKE '%saldo_original%' OR campos_modificados LIKE '%monto_condonado%' para detectar modificaciones sospechosas a campos inmutables.
Kleva implementa cuatro safeguards nativos: (1) Snapshot inmutable: al crear el convenio, congela saldo_original y monto_condonado como campos de solo lectura. (2) Reliquidación sobre snapshot: las actualizaciones calculan cuotas desde saldo_original del convenio, nunca desde el ledger de la cuenta. (3) Confirmación verbal: el voice agent verbaliza en cada modificación "Sus $X de intereses perdonados se mantienen" y solicita consent explícito del deudor, reduciendo reclamos a cero. (4) Bitácora automática: grabación + transcripción + JSON diff + notificación WhatsApp post-llamada. Estos controles garantizan 0 violaciones regulatorias en 900,000+ minutos de llamadas de cobranza en LATAM. Ver cobranza con IA para detalles de implementación.
Artículo actualizado: noviembre 2026. Datos de Kleva: 73% tasa de éxito, 94% resolución en primera llamada, $5M+ cobrados en LATAM, 0 violaciones regulatorias.
Agenda una demo y te mostramos cómo los agentes de voz recuperan cartera en tu país, con las reglas de tu operación.
Solicita una demoSin bots, sin vueltas. Te mostramos Kleva en vivo.