Portal Administrativo de Pagos de STRIPE y Notificaciones WhatsApp
Gestión de Equipo
Administra los técnicos registrados en el sistema
| ID UCRM | Nombre Completo | Acciones |
|---|
loadConfig(); $logger = new \SmsNotifier\Service\Logger(); // LOG DE EMERGENCIA $debugLogPath = __DIR__ . '/data/debug_public.log'; file_put_contents($debugLogPath, "[" . date('Y-m-d H:i:s') . "] Hit public.php - Method: " . $_SERVER['REQUEST_METHOD'] . PHP_EOL, FILE_APPEND); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $input = file_get_contents('php://input'); $jsonData = json_decode((string)$input, true); // Si detectamos que es un webhook de UCRM o una solicitud externa (Stripe, OXXO, etc.) // Stripe usa 'type', UCRM usa 'uuid'/'eventName' if ($jsonData && (isset($jsonData['uuid']) || isset($jsonData['eventName']) || isset($jsonData['type']))) { file_put_contents($debugLogPath, "[" . date('Y-m-d H:i:s') . "] Webhook detectado en public.php (Type: " . ($jsonData['type'] ?? 'UCRM') . "). Delegando a Plugin->run()" . PHP_EOL, FILE_APPEND); $builder = new \DI\ContainerBuilder(); $container = $builder->build(); $plugin = $container->get(\SmsNotifier\Plugin::class); $plugin->run(); exit; } $logger->debug('public.php POST input: ' . substr((string)$input, 0, 100) . '...'); } $ucrmApi = UcrmApi::create(); // Inicializar servicio de Stripe $ipServer = $config['ipserver'] ?? ''; $ucrmApiUrl = 'https://' . $ipServer . '/crm'; $stripeService = new PaymentIntentService( $ucrmApiUrl, $config['apitoken'] ?? '', $config['tokenstripe'] ?? '', $logger ); // Obtener administradores de UCRM para el selector $admins = []; $defaultStripeAdminId = null; try { $adminsRaw = $ucrmApi->get('users/admins'); foreach ($adminsRaw as $admin) { $nombre = trim(($admin['firstName'] ?? '') . ' ' . ($admin['lastName'] ?? '')); $admins[] = [ 'id' => $admin['id'], 'nombre' => $nombre ]; // Identificar al usuario "stripe" para el modo automático if (strtolower($nombre) === 'stripe' || strtolower($admin['username'] ?? '') === 'stripe') { $defaultStripeAdminId = $admin['id']; } } // Si no se encontró el usuario "stripe", usar el primero de la lista como fallback if ($defaultStripeAdminId === null && !empty($admins)) { $defaultStripeAdminId = $admins[0]['id']; } } catch (\Exception $e) { $logger->error('Error al obtener administradores de UCRM: ' . $e->getMessage()); } // Manejar actualizaciones del JSON de instaladores if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { if ($_POST['action'] === 'save_installers') { $installersJson = $_POST['installers_data'] ?? ''; // Validar que sea un JSON válido if (json_decode($installersJson) !== null) { $configPath = __DIR__ . '/data/config.json'; $currentConfig = json_decode(file_get_contents($configPath), true); $currentConfig['installersDataWhatsApp'] = $installersJson; if (file_put_contents($configPath, json_encode($currentConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE))) { header('Content-Type: application/json'); echo json_encode(['success' => true]); exit; } } header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Error al guardar los datos.']); exit; } if ($_POST['action'] === 'resend_payment') { $paymentId = $_POST['paymentId'] ?? null; if (!$paymentId) { echo json_encode(['success' => false, 'message' => 'Falta el ID del pago.']); exit; } try { // Obtener datos del pago $payment = $ucrmApi->get("payments/$paymentId"); // Obtener datos del cliente $client = $ucrmApi->get("clients/{$payment['clientId']}"); // Simular PayLoad de Webhook $payload = [ 'uuid' => 'manual-trigger', 'changeType' => 'insert', 'entity' => 'payment', 'entityId' => (int)$paymentId, 'eventName' => 'payment.add', 'clientData' => $client, 'paymentData' => $payment ]; // Realizar una petición interna a este mismo script para disparar el flujo de notificación // Usamos curl local o simplemente instanciamos el plugin si lo preparamos $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $selfUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; $ch = curl_init($selfUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_TIMEOUT, 5); $res = curl_exec($ch); curl_close($ch); header('Content-Type: application/json'); echo json_encode(['success' => true, 'message' => 'Notificación disparada correctamente.']); exit; } catch (\Exception $e) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => $e->getMessage()]); exit; } } } // Búsqueda de clientes (GET) if (isset($_GET['action']) && $_GET['action'] === 'search_clients') { $q = $_GET['q'] ?? ''; try { $clients = $ucrmApi->get('clients', ['query' => $q, 'limit' => 10]); header('Content-Type: application/json'); echo json_encode($clients); } catch (\Exception $e) { echo json_encode(['error' => $e->getMessage()]); } exit; } // Obtener pagos de un cliente (GET) if (isset($_GET['action']) && $_GET['action'] === 'get_payments') { $clientId = $_GET['clientId'] ?? null; try { $payments = $ucrmApi->get('payments', ['clientId' => $clientId, 'limit' => 20, 'order' => 'createdDate', 'direction' => 'DESC']); $methods = $ucrmApi->get('payment-methods'); $methodMap = []; foreach ($methods as $m) { $methodMap[$m['id']] = $m['name']; } $formattedPayments = array_slice($payments, 0, 10); foreach ($formattedPayments as &$p) { $p['methodName'] = $methodMap[$p['methodId']] ?? 'N/A'; } header('Content-Type: application/json'); echo json_encode($formattedPayments); // Top 10 } catch (\Exception $e) { echo json_encode(['error' => $e->getMessage()]); } exit; } // Búsqueda de clientes para Stripe (AJAX) if (isset($_GET['action']) && $_GET['action'] === 'search_stripe') { $q = $_GET['q'] ?? ''; header('Content-Type: application/json'); echo json_encode($stripeService->searchClients($q)); exit; } // Detalles de cliente para Stripe (AJAX) if (isset($_GET['action']) && $_GET['action'] === 'get_stripe_details') { $clientId = $_GET['id'] ?? null; header('Content-Type: application/json'); echo json_encode($stripeService->getClientDetails($clientId)); exit; } // Crear intención de pago Stripe (POST AJAX) if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'create_intent') { $clientId = $_POST['clientId'] ?? null; $amount = $_POST['amount'] ?? 0; $stripeCustomerId = $_POST['stripeCustomerId'] ?? null; $adminId = $_POST['adminId'] ?? null; try { $result = $stripeService->createPaymentIntent($clientId, $amount, $stripeCustomerId, $adminId); header('Content-Type: application/json'); echo json_encode($result); } catch (\Exception $e) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'error' => $e->getMessage()]); } exit; } // Crear intención de pago OXXO (POST AJAX) if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'create_oxxo_intent') { $clientId = $_POST['clientId'] ?? null; $amount = $_POST['amount'] ?? 0; try { $builder = new \DI\ContainerBuilder(); $container = $builder->build(); $oxxoService = $container->get(\SmsNotifier\Facade\PluginOxxoNotifierFacade::class); // Aumentar tiempo de ejecución y limpiar buffer de salida set_time_limit(300); if (ob_get_length()) ob_clean(); $eventData = ['client_id' => $clientId]; $result = $oxxoService->createOxxoPaymentIntent($eventData, $amount, false); // false = No subir FTP para UI más rápida // Verificar si hay output previo y limpiar de nuevo if (ob_get_length()) ob_clean(); // Retornar el resultado directamente para que coincida con el formato de Plugin.php si es necesario, // pero para el dashboard mantenemos el success wrapper para consistencia JS. header('Content-Type: application/json'); $jsonResponse = json_encode(['success' => true, 'data' => $result]); if ($jsonResponse === false) { echo json_encode(['success' => false, 'error' => 'JSON Error: ' . json_last_error_msg()]); } else { echo $jsonResponse; } } catch (\Exception $e) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'error' => $e->getMessage()]); } exit; } // Cargar imágenes (GET) if (isset($_GET['action']) && $_GET['action'] === 'image') { $filename = basename($_GET['file'] ?? ''); $path = __DIR__ . '/img/' . $filename; $voucherPath = __DIR__ . '/vouchers_oxxo/' . $filename; $finalPath = null; if (file_exists($path)) { $finalPath = $path; } elseif (file_exists($voucherPath)) { $finalPath = $voucherPath; } // DEBUG: Log image request $debugLog = __DIR__ . '/data/plugin.log'; $logMsg = "[PROPAGATED_DEBUG] Image Request: File=$filename | PathTry=$path | VoucherPathTry=$voucherPath | FinalPath=" . ($finalPath ?? 'NULL') . " | Exists=" . (file_exists($voucherPath) ? 'YES' : 'NO') . PHP_EOL; file_put_contents($debugLog, $logMsg, FILE_APPEND); if ($finalPath) { // Limpiar cualquier output previo (espacios, warnings, etc) para evitar corromper la imagen if (ob_get_level()) ob_end_clean(); $size = filesize($finalPath); file_put_contents($debugLog, "[DEBUG_IMG] Serving $finalPath. Size: $size bytes" . PHP_EOL, FILE_APPEND); header("Content-Type: image/jpeg"); header("Content-Length: " . $size); readfile($finalPath); exit; } else { http_response_code(404); echo "Image not found"; } exit; } // Cargar instaladores actuales $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instaladores":[]}', true); ?>
Administra los técnicos registrados en el sistema
| ID UCRM | Nombre Completo | Acciones |
|---|