From 28d3b1c719c196e1ae5542c5c1a024fb1fd6ac36 Mon Sep 17 00:00:00 2001 From: Lizandro Date: Sun, 19 Jul 2026 14:19:31 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20bot=C3=B3n=20Reintentar=20en=20web=20ch?= =?UTF-8?q?at=20+=20aviso=20de=2015=20min=20en=20ambos=20canales?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PublicChat: sin_coincidencia guarda datosPago en flujoData, muestra Reintentar - PublicChat: pago.reintentar re-corre validación sin reenviar foto - Telegram y web chat: aviso al recibir comprobante (15 min visibles, 30 reales) Co-Authored-By: Claude Sonnet 4.6 --- app/Http/Livewire/Chat/PublicChat.php | 98 +++++++++++++++++++++++---- app/Services/TelegramBotService.php | 2 +- 2 files changed, 86 insertions(+), 14 deletions(-) diff --git a/app/Http/Livewire/Chat/PublicChat.php b/app/Http/Livewire/Chat/PublicChat.php index ac0f144..64580a6 100755 --- a/app/Http/Livewire/Chat/PublicChat.php +++ b/app/Http/Livewire/Chat/PublicChat.php @@ -445,6 +445,7 @@ class PublicChat extends Component $action === 'perfil.ver' => $this->verPerfil(), $action === 'asesor.solicitar' => $this->solicitarAsesor(), $action === 'pago.aplicar' => $this->aplicarRecargaValidada($data), + $action === 'pago.reintentar' => $this->reintentarValidacionPago(), $action === 'sesion.cerrar' => $this->confirmarCierreSesion(), $action === 'sesion.cerrar.confirmar' => $this->cerrarSesion(), default => $this->mostrarMenuPrincipal($this->convId), @@ -486,6 +487,8 @@ class PublicChat extends Component 'leido' => false, ]); + $this->guardarMensajeBot($this->convId, "⏳ Analizando tu comprobante...\n\nRecuerda: tienes hasta 15 minutos desde que hiciste la transferencia para enviar el soporte."); + $base64 = base64_encode(file_get_contents($this->fotoComprobante->getRealPath())); $mimeType = $this->fotoComprobante->getMimeType(); @@ -504,33 +507,42 @@ class PublicChat extends Component $monto = (int) ($datosPago['valor'] ?? 0); $botones = []; + $motivo = $resultado['motivo'] ?? ''; + if ($resultado['estado'] === 'confirmado') { $botones[] = [ 'label' => 'Aplicar recarga de $' . number_format($monto), 'action' => 'pago.aplicar', 'data' => ['monto' => $monto, 'referencia' => $datosPago['referencia'] ?? null], ]; + $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; + $motivoTexto = null; + } elseif ($motivo === 'sin_coincidencia' || $motivo === 'sin_correos') { + // Guardar datosPago para reintentar sin reenviar foto + $this->flujo = 'pago.pendiente'; + $this->flujoData = ['datosPago' => $datosPago]; + + $botones[] = ['label' => '🔄 Reintentar', 'action' => 'pago.reintentar', 'data' => []]; + $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; + $motivoTexto = 'Por ahora no encontramos tu pago de confirmación. Puede demorar entre 1 y 2 minutos en llegar. Espera un momento y presiona Reintentar.'; + } else { + $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; + $motivoTexto = match ($motivo) { + 'correo_deshabilitado' => 'Verificación por correo no configurada', + 'error_imap' => 'Error al leer correos IMAP', + 'error_sistema' => 'Error interno, intenta de nuevo en unos minutos', + default => 'No se pudo verificar automáticamente', + }; } - $botones[] = ['label' => 'Hablar con asesor', 'action' => 'asesor.solicitar', 'data' => []]; - $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; - - $motivoTexto = match ($resultado['motivo'] ?? '') { - 'correo_deshabilitado' => 'Verificación por correo no configurada', - 'error_imap' => 'Error al leer correos IMAP', - 'sin_correos' => 'Sin correos recientes en bandeja', - 'sin_coincidencia' => 'Ningún correo coincide con este monto/fecha', - default => null, - }; - ChatMessage::create([ 'conversation_id' => $this->convId, 'tipo' => 'bot', 'tipo_ui' => 'validacion', 'contenido' => 'Resultado del analisis:', 'payload' => [ - 'estado' => $resultado['estado'], - 'motivo' => $motivoTexto, + 'estado' => $resultado['estado'], + 'motivo' => $motivoTexto, 'ia_datos' => $datosPago, 'botones' => $botones, ], @@ -1314,6 +1326,66 @@ class PublicChat extends Component // Aplicar recarga validada por IA // ───────────────────────────────────────────────────────── + private function reintentarValidacionPago(): void + { + if ($this->flujo !== 'pago.pendiente' || empty($this->flujoData['datosPago'])) { + $this->guardarMensajeBot($this->convId, 'No hay ningún comprobante pendiente. Envía la foto de tu comprobante.'); + return; + } + + $datosPago = $this->flujoData['datosPago']; + $monto = (int) ($datosPago['valor'] ?? 0); + $resultado = app(\App\Services\PagoValidadorService::class)->validar($datosPago, $this->userId, $this->nombreUsuario, 'web'); + $motivo = $resultado['motivo'] ?? ''; + $botones = []; + + if ($resultado['estado'] === 'confirmado') { + $this->flujo = ''; + $this->flujoData = []; + $botones[] = [ + 'label' => 'Aplicar recarga de $' . number_format($monto), + 'action' => 'pago.aplicar', + 'data' => ['monto' => $monto, 'referencia' => $datosPago['referencia'] ?? null], + ]; + $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; + $motivoTexto = null; + + } elseif ($resultado['estado'] === 'ya_usado') { + $this->flujo = ''; + $this->flujoData = []; + $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; + $motivoTexto = 'Este comprobante ya fue registrado anteriormente.'; + + } elseif ($motivo === 'sin_coincidencia' || $motivo === 'sin_correos') { + $botones[] = ['label' => '🔄 Reintentar', 'action' => 'pago.reintentar', 'data' => []]; + $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; + $motivoTexto = 'Aún no encontramos tu pago. Puede demorar entre 1 y 2 minutos en llegar. Espera un momento y presiona Reintentar.'; + + } else { + $this->flujo = ''; + $this->flujoData = []; + $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; + $motivoTexto = 'No se pudo verificar el pago. Intenta de nuevo.'; + } + + ChatMessage::create([ + 'conversation_id' => $this->convId, + 'tipo' => 'bot', + 'tipo_ui' => 'validacion', + 'contenido' => 'Verificando de nuevo...', + 'payload' => [ + 'estado' => $resultado['estado'], + 'motivo' => $motivoTexto, + 'ia_datos' => $datosPago, + 'botones' => $botones, + ], + 'leido' => true, + ]); + + $this->cargarMensajes(); + $this->dispatchBrowserEvent('scroll-chat'); + } + private function aplicarRecargaValidada(array $data): void { if (! $this->userId) { diff --git a/app/Services/TelegramBotService.php b/app/Services/TelegramBotService.php index f06e787..84a3b2d 100755 --- a/app/Services/TelegramBotService.php +++ b/app/Services/TelegramBotService.php @@ -169,7 +169,7 @@ class TelegramBotService return; } - $this->send($chatId, "⏳ Analizando tu comprobante..."); + $this->send($chatId, "⏳ Analizando tu comprobante...\n\n_Recuerda: tienes hasta 15 minutos desde que hiciste la transferencia para enviar el soporte._"); try { $imageData = $this->downloadTelegramFile($fileId);