fix: ya_usado solo dispara cuando el email coincide en fecha, hora y llave

Antes: monto coincide → hash ya_usado → retorna "reutilizado" (falso positivo
si había un email viejo del mismo valor en la ventana IMAP de 120 min).
Ahora: monto + fecha + hora + llave deben coincidir primero; solo entonces
se verifica el hash — garantizando que es el mismo comprobante exacto.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro
2026-07-19 14:53:49 +00:00
co-authored by Claude Sonnet 4.6
parent 437adc531f
commit 4b2eb7c709
+27 -26
View File
@@ -72,7 +72,33 @@ class PagoValidadorService
continue;
}
// ── 2. Hash único (anti-doble-uso) ─────────────────────
// ── 2. Fecha (mismo día) — solo si ambos tienen fecha ──
if ($fechaIA && ($datosCorreo['fecha'] ?? '')) {
if (! $this->mismoDia($fechaIA, $datosCorreo['fecha'])) {
Log::info("[PagoValidador] Correo #{$i}: fecha no coincide (ia={$fechaIA} correo={$datosCorreo['fecha']})");
continue;
}
}
// ── 3. Hora (±15 min) — solo si ambos tienen hora ──────
if ($horaIA && ($datosCorreo['hora'] ?? '')) {
if (! $this->horaProxima($horaIA, $datosCorreo['hora'], 15)) {
Log::info("[PagoValidador] Correo #{$i}: hora fuera de rango (ia={$horaIA} correo={$datosCorreo['hora']})");
continue;
}
}
// ── 4. Llave Bancolombia (si la foto la tiene) ──────────
if ($llaveIA) {
$llaveCorreo = strtolower(preg_replace('/\s+/', '', $datosCorreo['llave'] ?? ''));
if ($llaveCorreo && $llaveIA !== $llaveCorreo) {
Log::info("[PagoValidador] Correo #{$i}: llave no coincide (ia={$llaveIA} correo={$llaveCorreo})");
continue;
}
}
// ── 5. Hash único (anti-doble-uso) — solo tras verificar fecha/hora/llave ──
// Si el email coincide en todos los campos pero ya fue usado → es el mismo comprobante
$emailHash = sha1($body . $date);
try {
@@ -86,31 +112,6 @@ class PagoValidadorService
return ['estado' => 'no_encontrado', 'correo' => null, 'motivo' => 'error_sistema'];
}
// ── 3. Fecha (mismo día) — solo si ambos tienen fecha ──
if ($fechaIA && ($datosCorreo['fecha'] ?? '')) {
if (! $this->mismoDia($fechaIA, $datosCorreo['fecha'])) {
Log::info("[PagoValidador] Correo #{$i}: fecha no coincide (ia={$fechaIA} correo={$datosCorreo['fecha']})");
continue;
}
}
// ── 4. Hora (±15 min) — solo si ambos tienen hora ──────
if ($horaIA && ($datosCorreo['hora'] ?? '')) {
if (! $this->horaProxima($horaIA, $datosCorreo['hora'], 15)) {
Log::info("[PagoValidador] Correo #{$i}: hora fuera de rango (ia={$horaIA} correo={$datosCorreo['hora']})");
continue;
}
}
// ── 5. Llave Bancolombia (si la foto la tiene) ──────────
if ($llaveIA) {
$llaveCorreo = strtolower(preg_replace('/\s+/', '', $datosCorreo['llave'] ?? ''));
if ($llaveCorreo && $llaveIA !== $llaveCorreo) {
Log::info("[PagoValidador] Correo #{$i}: llave no coincide (ia={$llaveIA} correo={$llaveCorreo})");
continue;
}
}
// ── 6. Remitente (informativo, no bloquea) ──────────────
$coincideRemitente = $this->remitenteCoincide($datosCorreo['remitente'] ?? '', $nombreUsuario ?? '');