= 1 && strlen($segments[0]) === 64 && ctype_xdigit(strtolower($segments[0]))) { $_GET['token'] = $segments[0]; if (count($segments) >= 2) { $r = strtolower($segments[1]); if (in_array($r, array('auth','portal','payment'))) { $_GET['route'] = $r; } elseif ($r === 'status' && count($segments) >= 3) { $_GET['route'] = 'status'; $_GET['trx'] = $segments[2]; } } else { $_GET['route'] = 'auth'; // DEFAULT } } $baseUrl = 'https://wp.manjapro.net/'; session_start(); include __DIR__ . '/../config/connect.php'; include __DIR__ . '/../config/tanggal_indo.php'; require 'services/Customer.php'; require 'services/Invoice.php'; require 'services/PaymentService.php'; require 'services/GatewayFactory.php'; require 'services/PaymentMethodMapper.php'; /** * INIT SERVICE */ $customerService = new Customer($pdo); $invoiceService = new Invoice($pdo); $paymentService = new PaymentService($pdo); /** * HELPER */ function setAlert($msg){ $_SESSION['error'] = $msg; } function redirectTo($path){ header("Location: /$path"); exit; } /** * PARAM */ $token = isset($_GET['token']) ? $_GET['token'] : null; $route = isset($_GET['route']) ? $_GET['route'] : null; $trx_id = isset($_GET['trx']) ? $_GET['trx'] : null; $session_token = isset($_SESSION['token']) ? $_SESSION['token'] : null; $isLogin = isset($_SESSION['customer_id']); /** * ================================ * TOKEN SESSION VALIDATION ✅ * ================================ */ if ($token && $isLogin) { // Token beda → logout & ke auth if ($session_token !== $token) { session_destroy(); setAlert("Token tidak valid, login ulang"); redirectTo($token . '/auth'); } } // Gak ada token + sudah login → ke portal TOKEN SESSION if (!$token && $isLogin && $session_token) { redirectTo($session_token . '/portal'); } /** * ================================ * AUTO REDIRECT KE PORTAL jika sudah login * ================================ */ if ($isLogin && $token && ($route === 'auth' || !$route)) { redirectTo($token . '/portal'); } /** * ================================ * ERROR PAGE (tanpa token) * ================================ */ if ($route === 'error' && !$token) { require 'views/error.php'; exit; } /** * ================================ * WAJIB TOKEN (JIKA BELUM LOGIN) * ================================ */ if (!$token && !$isLogin) { redirectTo('error'); } /** * ================================ * VALIDASI TOKEN (TANPA LOGIN) * ================================ */ if ($token && !$isLogin) { if (strlen($token) !== 64 || !ctype_xdigit($token)) { setAlert("Token tidak valid"); redirectTo('error'); } $customerFromToken = $customerService->getByToken($token); if (!$customerFromToken) { setAlert("Token tidak ditemukan"); redirectTo('error'); } $_SESSION['temp_token'] = $token; } /** * ================================ * PROTECT ROUTE * ================================ */ $protected = array('portal','payment','status'); if (in_array($route, $protected) && !$isLogin) { redirectTo($token . '/auth'); } /** * ================================ * LOAD DATA * ================================ */ $customer = null; $unpaid = array(); $total = 0; $history = array(); $paymentActive = null; if ($isLogin) { $customer = $customerService->getDetail($_SESSION['customer_id']); if (!$customer) { session_destroy(); redirectTo('error'); } $unpaid = $invoiceService->getUnpaid($customer['id']); $total = $invoiceService->getTotalUnpaid($customer['id']); $history = $invoiceService->getLastPaid($customer['id']); if ($trx_id) { $paymentActive = $invoiceService->getPayment($trx_id, $customer['id']); } $paymentPending = $invoiceService->getPaymentPending($unpaid['id']) ?? null; $paymentStatus = $invoiceService->getPaymentStatus($unpaid['transaction_id']) ?? null; } /** * ================================ * HANDLE POST * ================================ */ if ($_SERVER['REQUEST_METHOD'] === 'POST') { // AUTH if ($route === 'auth') { $otp = isset($_POST['otp']) ? $_POST['otp'] : ''; $token = isset($_SESSION['temp_token']) ? $_SESSION['temp_token'] : null; if (!$token) redirectTo('error'); if (strlen($otp) !== 4 || !ctype_digit($otp)) { setAlert("Nomor harus 4 digit"); redirectTo($token . '/auth'); } $customerFromToken = $customerService->getByToken($token); if (!$customerFromToken) redirectTo('error'); $valid = $customerService->verifyLastPhone($customerFromToken['id'], $otp); if (!$valid) { setAlert("4 nomor terakhir yang anda masukan salah"); redirectTo($token . '/auth'); } $_SESSION['customer_id'] = $customerFromToken['id']; $_SESSION['server_id'] = $customerFromToken['id_data_server']; $_SESSION['token'] = $token; unset($_SESSION['temp_token']); redirectTo($token . '/portal'); } // PAYMENT if ($route === 'payment_process') { header('Content-Type: application/json'); if (!$isLogin) { echo json_encode([ 'success' => false, 'message' => 'Session tidak valid' ]); exit; } $method = $_POST['method'] ?? null; if (!$method) { echo json_encode([ 'success' => false, 'message' => 'Pilih metode pembayaran' ]); exit; } $result = $paymentService->createPayment([ 'customer_id' => $_SESSION['customer_id'], 'method' => $method, 'customer' => $customer, 'gateway_type'=> $customer['payment_gateway'], 'invoices' => $unpaid['id'] ?? null ]); if (!$result['success']) { echo json_encode([ 'success' => false, 'message' => $result['message'] ]); exit; } echo json_encode([ 'success' => true, 'trx' => $result['transaction_id'] ]); exit; } if ($route === 'payment' AND $customer['payment_gateway'] == 'doku' ) { header('Content-Type: application/json'); if (!$isLogin) { echo json_encode([ 'success' => false, 'message' => 'Session tidak valid' ]); exit; } $result = $paymentService->createPayment([ 'customer_id' => $_SESSION['customer_id'], 'customer' => $customer, 'gateway_type'=> $customer['payment_gateway'], 'invoices' => $unpaid['id'] ?? null, 'invoice_detail' => $unpaid ]); if ($result['success'] && !empty($result['data']['payment_url'])) { header("Location: " . $result['data']['payment_url']); exit; } else { echo json_encode([ 'success' => false, 'message' => $result['message'] ?? 'Gagal membuat pembayaran' ]); exit; } } } /** * ================================ * ROUTING * ================================ */ switch ($route) { case 'portal': require 'views/portal.php'; break; case 'payment': require 'views/payment.php'; break; // case 'payment_proccess': // require 'views/payment_proccess.php'; // break; case 'status': require 'views/status.php'; break; case 'auth': case null: require 'views/auth.php'; break; case 'error': require 'views/error.php'; break; default: require 'views/error.php'; } /** * ALERT */ if ($route !== 'error' && isset($_SESSION['error'])): ?>