diff --git a/app/Http/Livewire/Chat/PublicChat.php b/app/Http/Livewire/Chat/PublicChat.php index bbc5785..e78ab29 100755 --- a/app/Http/Livewire/Chat/PublicChat.php +++ b/app/Http/Livewire/Chat/PublicChat.php @@ -507,48 +507,67 @@ class PublicChat extends Component $monto = (int) ($datosPago['valor'] ?? 0); $botones = []; + // Verificar solicitud activa + $solicitud = $this->userId ? \App\Models\SolicitudRecarga::pendiente($this->userId) : null; + if (! $solicitud) { + $this->guardarMensajeBot($this->convId, "No tienes ninguna solicitud de recarga activa. Inicia una recarga desde el menu para poder enviar el comprobante."); + $this->cargarMensajes(); + return; + } + + // Verificar que el monto coincida con la solicitud + $valorIA = (int) ($datosPago['valor'] ?? 0); + if ($valorIA !== $solicitud->monto) { + $this->guardarMensajeBot($this->convId, "El monto del comprobante ($" . number_format($valorIA) . ") no coincide con tu solicitud de recarga ($" . number_format($solicitud->monto) . ")."); + $this->cargarMensajes(); + return; + } + $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; + $this->autoAplicarRecargaWeb($solicitud, $solicitud->monto); + return; + + } elseif ($resultado['estado'] === 'ya_usado') { + $this->flujo = ''; + $this->flujoData = []; + $this->guardarMensajeBot($this->convId, "β›” Comprobante ya utilizado. Este pago ya fue registrado anteriormente."); + } elseif ($motivo === 'sin_coincidencia' || $motivo === 'sin_correos') { - // Guardar datosPago para reintentar sin reenviar foto $this->flujo = 'pago.pendiente'; - $this->flujoData = ['datosPago' => $datosPago]; + $this->flujoData = array_merge($this->flujoData, ['datosPago' => $datosPago]); + + ChatMessage::create([ + 'conversation_id' => $this->convId, + 'tipo' => 'bot', + 'tipo_ui' => 'validacion', + 'contenido' => 'Por ahora no encontramos tu pago de confirmacion. Puede demorar entre 1 y 2 minutos en llegar. Espera un momento y presiona Reintentar.', + 'payload' => [ + 'estado' => 'pendiente', + 'motivo' => 'Por ahora no encontramos tu pago de confirmacion. Puede demorar entre 1 y 2 minutos.', + 'ia_datos' => $datosPago, + 'botones' => [ + ['label' => 'πŸ”„ Reintentar', 'action' => 'pago.reintentar', 'data' => []], + ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []], + ], + ], + 'leido' => true, + ]); + $this->cargarMensajes(); + $this->dispatchBrowserEvent('scroll-chat'); + return; - $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', + 'correo_deshabilitado' => 'Verificacion 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', + default => 'No se pudo verificar automaticamente', }; + $this->guardarMensajeBot($this->convId, "⚠️ No confirmado: {$motivoTexto}"); } - ChatMessage::create([ - 'conversation_id' => $this->convId, - 'tipo' => 'bot', - 'tipo_ui' => 'validacion', - 'contenido' => 'Resultado del analisis:', - 'payload' => [ - 'estado' => $resultado['estado'], - 'motivo' => $motivoTexto, - 'ia_datos' => $datosPago, - 'botones' => $botones, - ], - 'leido' => true, - ]); - } catch (\Throwable $e) { $this->guardarMensajeBot($this->convId, "Error analizando el comprobante. Por favor intenta de nuevo."); } finally { @@ -1115,6 +1134,14 @@ class PublicChat extends Component ]); $this->guardarMensajeBot($this->convId, "Cuando hayas transferido, envia el comprobante usando el icono de camara (πŸ“·) y el sistema lo validara automaticamente.\n\nTienes hasta 15 minutos despues de la transferencia para enviar el soporte."); + + // Registrar solicitud pendiente + if ($this->userId) { + $solicitud = \App\Models\SolicitudRecarga::crear($this->userId, $monto, 'web'); + $this->flujo = 'pago.solicitud'; + $this->flujoData = ['solicitud_id' => $solicitud->id, 'monto' => $monto]; + } + $this->volver('menu.principal'); } @@ -1329,63 +1356,86 @@ class PublicChat extends Component 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.'); + $this->guardarMensajeBot($this->convId, 'No hay ningun comprobante pendiente. Envia la foto de tu comprobante.'); + return; + } + + $solicitud = $this->userId ? \App\Models\SolicitudRecarga::pendiente($this->userId) : null; + if (! $solicitud) { + $this->flujo = ''; + $this->flujoData = []; + $this->guardarMensajeBot($this->convId, '⚠️ Tu solicitud de recarga expiro. Inicia una nueva recarga desde el menu.'); + $this->cargarMensajes(); 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; + $this->autoAplicarRecargaWeb($solicitud, $solicitud->monto); + return; } elseif ($resultado['estado'] === 'ya_usado') { $this->flujo = ''; $this->flujoData = []; - $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; - $motivoTexto = 'Este comprobante ya fue registrado anteriormente.'; + $this->guardarMensajeBot($this->convId, 'β›” Comprobante ya utilizado. Este pago 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.'; + ChatMessage::create([ + 'conversation_id' => $this->convId, + 'tipo' => 'bot', + 'tipo_ui' => 'validacion', + 'contenido' => 'Aun no encontramos tu pago.', + 'payload' => [ + 'estado' => 'pendiente', + 'motivo' => 'Aun no encontramos tu pago. Puede demorar entre 1 y 2 minutos en llegar.', + 'ia_datos' => $datosPago, + 'botones' => [ + ['label' => 'πŸ”„ Reintentar', 'action' => 'pago.reintentar', 'data' => []], + ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []], + ], + ], + 'leido' => true, + ]); + $this->cargarMensajes(); + $this->dispatchBrowserEvent('scroll-chat'); + return; } else { $this->flujo = ''; $this->flujoData = []; - $botones[] = ['label' => '<- Menu', 'action' => 'menu.principal', 'data' => []]; - $motivoTexto = 'No se pudo verificar el pago. Intenta de nuevo.'; + $this->guardarMensajeBot($this->convId, '⚠️ 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 autoAplicarRecargaWeb(\App\Models\SolicitudRecarga $solicitud, int $monto): void + { + $user = User::with('saldo')->find($this->userId); + $saldo = $user->saldo ?? Saldo::create(['usuario_id' => $this->userId, 'valor' => 0]); + $nuevoSaldo = $saldo->valor + $monto; + $saldo->update(['valor' => $nuevoSaldo]); + $this->saldoUsuario = $nuevoSaldo; + + $solicitud->confirmar(); + + $this->flujo = ''; + $this->flujoData = []; + + $this->guardarMensajeBot( + $this->convId, + "βœ… Β‘Tu recarga de $" . number_format($monto) . " fue aplicada exitosamente!\nTu nuevo saldo es $" . number_format($nuevoSaldo) . "." + ); + $this->cargarMensajes(); + $this->dispatchBrowserEvent('scroll-chat'); + } + + // ───────────────────────────────────────────────────────── + private function aplicarRecargaValidada(array $data): void { if (! $this->userId) { diff --git a/app/Models/SolicitudRecarga.php b/app/Models/SolicitudRecarga.php new file mode 100644 index 0000000..2a4405a --- /dev/null +++ b/app/Models/SolicitudRecarga.php @@ -0,0 +1,45 @@ + 'datetime']; + + public static function crear(int $userId, int $monto, string $canal): static + { + // Expirar cualquier solicitud pendiente anterior del mismo usuario + static::where('user_id', $userId) + ->where('estado', 'pendiente') + ->update(['estado' => 'expirada']); + + return static::create([ + 'user_id' => $userId, + 'monto' => $monto, + 'canal' => $canal, + 'estado' => 'pendiente', + ]); + } + + public static function pendiente(int $userId): ?static + { + return static::where('user_id', $userId) + ->where('estado', 'pendiente') + ->where('created_at', '>=', now()->subMinutes(30)) + ->latest('id') + ->first(); + } + + public function confirmar(): void + { + $this->update(['estado' => 'confirmada']); + } +} diff --git a/database/migrations/2026_07_19_000001_create_solicitudes_recarga_table.php b/database/migrations/2026_07_19_000001_create_solicitudes_recarga_table.php new file mode 100644 index 0000000..4b89e65 --- /dev/null +++ b/database/migrations/2026_07_19_000001_create_solicitudes_recarga_table.php @@ -0,0 +1,27 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->integer('monto'); + $table->string('canal', 20)->default('telegram'); + $table->string('estado', 20)->default('pendiente'); // pendiente | confirmada | expirada + $table->timestamp('created_at')->useCurrent(); + + $table->index(['user_id', 'estado']); + }); + } + + public function down(): void + { + Schema::dropIfExists('solicitudes_recarga'); + } +};