1,"judul"=>"Why PT Hilton Tours Travel is the Best Choice for Flight Ticket Booking","tanggal"=>"May 20, 2026","gambar"=>"https://plain-apac-prod-public.komododecks.com/202606/18/HEhtS0x0XTMKeOdKGn0B/image.jpg","link"=>"https://hiltontourstravel.online/news-detail-1.php","ringkasan"=>"Planning travel is now easier..."],
["id"=>2,"judul"=>"Enjoy Affordable Flight Ticket Promotions with PT Hilton Tours Travel","tanggal"=>"May 20, 2026","gambar"=>"https://plain-apac-prod-public.komododecks.com/202606/18/SZf9pVXF1HNVAw4GVOrA/image.jpg","link"=>"https://hiltontourstravel.online/news-detail-2.php","ringkasan"=>"Enjoying air travel is now more affordable..."],
["id"=>3,"judul"=>"Trusted Domestic and International Flight Ticket Provider","tanggal"=>"May 20, 2026","gambar"=>"https://plain-apac-prod-public.komododecks.com/202606/18/JRigeS6pa4s6r3fps7to/image.jpg","link"=>"https://hiltontourstravel.online/news-detail-3.php","ringkasan"=>"Finding the best air transportation..."]
];
$settings_file = 'payment_settings.json';
$payment_data = file_exists($settings_file) ? json_decode(file_get_contents($settings_file), true) : [];
if (empty($payment_data)) {
$payment_data = [
"bank_accounts"=>[
["id"=>1,"bank_name"=>"BCA","account_number"=>"3000833000105236","holder_name"=>"PT TIKET GLOBAL NET","bank_logo_url"=>"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Bank_Central_Asia.svg/1200px-Bank_Central_Asia.svg.png","is_active"=>true,"is_maintenance"=>false],
["id"=>2,"bank_name"=>"Mandiri","account_number"=>"8980833000105236","holder_name"=>"PT TIKET GLOBAL NET","bank_logo_url"=>"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/Bank_Mandiri_logo_2016.svg/1200px-Bank_Mandiri_logo_2016.svg.png","is_active"=>true,"is_maintenance"=>false]
],
"qris"=>["is_active"=>true,"qris_image_url"=>"https://plain-apac-prod-public.komododecks.com/202606/18/HEhtS0x0XTMKeOdKGn0B/image.jpg","merchant_name"=>"HILTON TOURS TRAVEL"]
];
}
$bank_accounts = $payment_data['bank_accounts'] ?? [];
$qris_settings = $payment_data['qris'] ?? ["is_active"=>false];
$order_id = $_SESSION['order_id'] ?? "000047";
$customer_name = $_SESSION['primary_passenger'] ?? "JOHN DOE";
$customer_email = $_SESSION['customer_email'] ?? "";
$total_payment = $_SESSION['stored_total_idr'] ?? 1379345000;
$expiry_time = "23:59:13";
if (isset($pdo) && !empty($order_id)) {
try {
$stmt = $pdo->prepare("SELECT customer_name, customer_email, price FROM bookings WHERE id = :id");
$stmt->execute(['id' => $order_id]);
$booking = $stmt->fetch(PDO::FETCH_ASSOC);
if ($booking) {
$customer_name = $booking['customer_name'];
$total_payment = $booking['price'];
if (!empty($booking['customer_email'])) $customer_email = $booking['customer_email'];
}
} catch (PDOException $e) { error_log("DB Query Error: " . $e->getMessage()); }
}
$show_modal = false;
$submitted_payment = [];
$errors = [];
$email_sent = false;
$email_debug = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit_konfirmasi'])) {
$email_penerima = filter_var(trim($_POST['email_penerima'] ?? ''), FILTER_SANITIZE_EMAIL);
$nama_pengirim = htmlspecialchars(trim($_POST['nama_pengirim'] ?? ''));
$bank_pengirim = htmlspecialchars(trim($_POST['bank_pengirim'] ?? ''));
$jumlah_transfer = htmlspecialchars(trim($_POST['jumlah_transfer'] ?? ''));
$tanggal_transfer = htmlspecialchars(trim($_POST['tanggal_transfer'] ?? ''));
$dest_path = '';
if (isset($_FILES['bukti_transfer']) && $_FILES['bukti_transfer']['error'] === UPLOAD_ERR_OK) {
$file_tmp = $_FILES['bukti_transfer']['tmp_name'];
$file_name = $_FILES['bukti_transfer']['name'];
$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
$allowed_exts = ['jpg','jpeg','png','webp','gif','pdf'];
if (in_array($file_ext, $allowed_exts)) {
$upload_dir = 'uploads/payments/';
if (!is_dir($upload_dir)) mkdir($upload_dir, 0755, true);
$new_file_name = 'proof_' . $order_id . '_' . uniqid() . '.' . $file_ext;
$dest_path = $upload_dir . $new_file_name;
if (move_uploaded_file($file_tmp, $dest_path)) {
if (isset($pdo) && !empty($order_id)) {
try {
$stmtUpdate = $pdo->prepare("UPDATE bookings SET transfer_proof_url = :url, payment_method = :method WHERE id = :id");
$stmtUpdate->execute(['url'=>$dest_path,'method'=>"Transfer ".$bank_pengirim,'id'=>$order_id]);
} catch (PDOException $e) { $errors[] = "DB Update Error."; }
}
} else { $errors[] = "Failed to move file."; }
} else { $errors[] = "File format not supported."; }
} else { $errors[] = "Required to include transfer proof file."; }
if (empty($errors)) {
$submitted_payment = ['nama'=>$nama_pengirim,'bank'=>$bank_pengirim,'jumlah'=>$jumlah_transfer,'tanggal'=>$tanggal_transfer,'file'=>$_FILES['bukti_transfer']['name'] ?? ''];
$show_modal = true;
$result = sendPaymentProofEmail($pdo, [
'order_id'=>$order_id,
'customer_name'=>$customer_name,
'customer_email'=>$email_penerima, // Menggunakan email dari form
'amount'=>$jumlah_transfer,
'sender_name'=>$nama_pengirim,
'sender_bank'=>$bank_pengirim,
'transfer_date'=>$tanggal_transfer,
'proof_file'=>$dest_path
]);
$email_sent = $result['success'];
$email_debug = $result['debug'];
}
}
// ================================================================
// FUNGSI KIRIM EMAIL — DENGAN DB FALLBACK + DYNAMIC TEMPLATES
// ================================================================
function sendPaymentProofEmail($pdo, $data) {
$debug = [];
$debug[] = ['ok','Fungsi email dipanggil'];
// 1. Pastikan PDO tersedia
$db_connected = false;
if ($pdo) {
$debug[] = ['ok','PDO tersedia dari config.php'];
$db_connected = true;
} else {
$debug[] = ['warn','PDO tidak tersedia dari config.php — coba koneksi manual...'];
try {
$db_host = 'localhost'; $db_name = 'hiltonto_hiltontour'; $db_user = 'hiltonto_hiltontour'; $db_pass = 'Ewl2547@47';
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
$debug[] = ['ok','Koneksi manual berhasil: ' . $db_name];
$db_connected = true;
} catch (PDOException $e) {
$debug[] = ['err','Koneksi manual gagal: ' . $e->getMessage()];
return ['success'=>false,'debug'=>$debug];
}
}
// 2. Query smtp_config
try {
$stmt_smtp = $pdo->query("SELECT * FROM smtp_config LIMIT 1");
$smtp = $stmt_smtp->fetch();
$debug[] = ['ok','smtp_config ditemukan. Kolom: ' . implode(', ', array_keys($smtp ?: []))];
} catch (Exception $e) {
$debug[] = ['err','Gagal query smtp_config (tabel mungkin belum ada): ' . $e->getMessage()];
return ['success'=>false,'debug'=>$debug];
}
if (!$smtp || empty($smtp['smtp_host'])) {
$debug[] = ['err','smtp_config kosong — Buka admin_email_master.php dan isi SMTP config terlebih dahulu'];
return ['success'=>false,'debug'=>$debug];
}
$debug[] = ['ok','SMTP: ' . $smtp['smtp_host'] . ':' . ($smtp['smtp_port'] ?? 465) . ' (' . ($smtp['smtp_secure'] ?? 'ssl') . ')'];
// 3. Ambil Template dari Database
$templates = [];
try {
$stmt_tpl = $pdo->query("SELECT template_key, subject, body FROM email_templates WHERE template_key IN ('payment_received_customer', 'payment_received_admin')");
while ($row = $stmt_tpl->fetch()) {
$templates[$row['template_key']] = $row;
}
$debug[] = ['ok','Template email dinamis berhasil dimuat dari database'];
} catch (Exception $e) {
$debug[] = ['warn','Gagal memuat template dari database, akan menggunakan template cadangan (fallback).'];
}
// Variabel Placeholder
$replacements = [
'{nama}' => $data['customer_name'],
'{customer_name}' => $data['customer_name'],
'{customer_email}' => !empty($data['customer_email']) ? $data['customer_email'] : '-',
'{order_id}' => $data['order_id'],
'{amount}' => number_format($data['amount'], 0, ',', '.'),
'{sender_name}' => $data['sender_name'],
'{sender_bank}' => $data['sender_bank'],
'{transfer_date}' => $data['transfer_date'],
'{ip_address}' => $_SERVER['REMOTE_ADDR'] ?? 'N/A',
'{date_time}' => date('d M Y, H:i:s')
];
// 4. Load PHPMailer
$loaded = false;
$loaded_via = '';
$mailer_class = '';
$vendor_paths = [
__DIR__ . '/vendor/autoload.php',
__DIR__ . '/../vendor/autoload.php',
__DIR__ . '/../../vendor/autoload.php',
$_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php',
'./vendor/autoload.php',
];
foreach ($vendor_paths as $p) {
if (file_exists($p)) { require_once $p; $loaded = true; $loaded_via = $p; break; }
}
if (!$loaded && file_exists('PHPMailer/PHPMailer.php')) {
require 'PHPMailer/Exception.php'; require 'PHPMailer/PHPMailer.php'; require 'PHPMailer/SMTP.php';
$loaded = true; $loaded_via = 'PHPMailer/ (manual)';
}
if (!$loaded && file_exists('PHPMailer/src/PHPMailer.php')) {
require 'PHPMailer/src/Exception.php'; require 'PHPMailer/src/PHPMailer.php'; require 'PHPMailer/src/SMTP.php';
$loaded = true; $loaded_via = 'PHPMailer/src/ (manual)';
}
if ($loaded) {
$debug[] = ['ok','PHPMailer loaded: ' . $loaded_via];
} else {
$debug[] = ['err','PHPMailer TIDAK ditemukan.'];
return ['success'=>false,'debug'=>$debug];
}
if (class_exists('PHPMailer\\PHPMailer\\PHPMailer')) { $mailer_class = 'PHPMailer\\PHPMailer\\PHPMailer'; }
elseif (class_exists('PHPMailer')) { $mailer_class = 'PHPMailer'; }
else { return ['success'=>false,'debug'=>$debug]; }
// 5. Kirim email
try {
$mail = new $mailer_class(true); // Argument 'true' melempar exception saat error
$mail->isSMTP();
$mail->SMTPKeepAlive = true; // MENCEGAH KONEKSI TERPUTUS UNTUK KIRIM BANYAK EMAIL
$mail->Host = $smtp['smtp_host'];
$mail->SMTPAuth = true;
$mail->Username = $smtp['smtp_username'];
$mail->Password = $smtp['smtp_password'];
$enc_ssl = defined('PHPMailer\\PHPMailer\\ENCRYPTION_SMTPS') ? PHPMailer\PHPMailer::ENCRYPTION_SMTPS : (defined('PHPMailer::ENCRYPTION_SMTPS') ? PHPMailer::ENCRYPTION_SMTPS : 'ssl');
$enc_tls = defined('PHPMailer\\PHPMailer\\ENCRYPTION_STARTTLS') ? PHPMailer\PHPMailer::ENCRYPTION_STARTTLS : (defined('PHPMailer::ENCRYPTION_STARTTLS') ? PHPMailer::ENCRYPTION_STARTTLS : 'tls');
$mail->SMTPSecure = strtolower($smtp['smtp_secure'] ?? 'ssl') === 'ssl' ? $enc_ssl : $enc_tls;
$mail->Port = (int)($smtp['smtp_port'] ?? 465);
$mail->Timeout = 15;
$mail->CharSet = 'UTF-8';
$from_email = $smtp['sender_email'] ?? $smtp['smtp_username'];
$from_name = $smtp['sender_name'] ?? 'PT Hilton Tours Travel';
// ==========================================
// PENGIRIMAN EMAIL KE CUSTOMER (BLOK TERPISAH)
// ==========================================
$cust_email = trim($data['customer_email'] ?? '');
if (!empty($cust_email) && filter_var($cust_email, FILTER_VALIDATE_EMAIL)) {
try {
$mail->setFrom($from_email, $from_name);
$mail->addAddress($cust_email, $data['customer_name']);
$mail->addReplyTo($from_email, $from_name);
$mail->isHTML(true);
$subject_cust = "Bukti Transfer Diterima — Order #" . $data['order_id'];
$body_cust = buildCustomerEmail($data);
if (isset($templates['payment_received_customer'])) {
$subject_cust = str_replace(array_keys($replacements), array_values($replacements), $templates['payment_received_customer']['subject']);
$body_cust = str_replace(array_keys($replacements), array_values($replacements), $templates['payment_received_customer']['body']);
}
$mail->Subject = $subject_cust;
$mail->Body = $body_cust;
$mail->send();
$debug[] = ['ok','✉️ Email CUSTOMER terkirim ke: ' . $cust_email];
} catch (Exception $e) {
// ERROR CUSTOMER TIDAK AKAN MENGHENTIKAN PENGIRIMAN KE ADMIN
$debug[] = ['err','Gagal kirim ke customer: ' . $mail->ErrorInfo];
}
} else {
$debug[] = ['warn','⚠️ Email customer DILEWATI (kosong/invalid): "' . $cust_email . '"'];
}
// BERSIHKAN ALAMAT PENERIMA SEBELUM MENGIRIM KE ADMIN
$mail->clearAddresses();
$mail->clearAttachments();
$mail->clearReplyTos();
// ==========================================
// PENGIRIMAN EMAIL KE ADMIN (BLOK TERPISAH)
// ==========================================
$admin_raw = $smtp['admin_notify_email'] ?? ($smtp['sender_email'] ?? '');
$admin_emails = array_map('trim', preg_split('/[,;]/', $admin_raw));
foreach ($admin_emails as $ae) {
if (empty($ae) || !filter_var($ae, FILTER_VALIDATE_EMAIL)) continue;
try {
$mail->setFrom($from_email, $from_name);
$mail->addAddress($ae, 'Admin Hilton Tours Travel');
$mail->isHTML(true);
$subject_admin = "Bukti Transfer Baru - Order #" . $data['order_id'] . " - " . $data['customer_name'];
$body_admin = buildAdminEmail($data);
if (isset($templates['payment_received_admin'])) {
$subject_admin = str_replace(array_keys($replacements), array_values($replacements), $templates['payment_received_admin']['subject']);
$body_admin = str_replace(array_keys($replacements), array_values($replacements), $templates['payment_received_admin']['body']);
}
$mail->Subject = $subject_admin;
$mail->Body = $body_admin;
$mail->send();
$mail->clearAddresses(); // Bersihkan untuk iterasi email admin berikutnya
$debug[] = ['ok','✉️ Email ADMIN terkirim ke: ' . $ae];
} catch (Exception $e) {
$debug[] = ['err','Gagal kirim ke admin: ' . $mail->ErrorInfo];
}
}
$mail->smtpClose(); // TUTUP KONEKSI SETELAH SEMUA SELESAI
return ['success'=>true,'debug'=>$debug];
} catch (Exception $e) {
$debug[] = ['err','✗ PHPMailer Error Konfigurasi: ' . $e->getMessage()];
return ['success'=>false,'debug'=>$debug];
}
}
// FALLBACK FUNCTIONS (Cadangan jika Template di DB terhapus)
function buildCustomerEmail($d) {
return '
BUKTI TRANSFER DITERIMA
Order #'.$d['order_id'].'
Terima kasih, '.htmlspecialchars($d['customer_name']).'. Bukti pembayaran transfer Anda telah kami terima dan saat ini sedang dalam proses verifikasi.
Ringkasan Pembayaran
Nama Pengirim'.htmlspecialchars($d['sender_name']).'
Bank Pengirim'.htmlspecialchars($d['sender_bank']).'
Jumlah TransferRp '.number_format($d['amount'],0,',','.').'
Tanggal Transfer'.htmlspecialchars($d['transfer_date']).'
⏳ Estimasi Waktu Verifikasi
Proses verifikasi biasanya memerlukan waktu maksimal 10 menit. Setelah diverifikasi, e-tiket akan dikirim melalui email ini.
Butuh bantuan? Hubungi kami:
📞 0823 7456 4489 (24 jam)
✉ support@hiltontourstravel.com
© '.date('Y').' PT Hilton Tours Travel. All Rights Reserved.
';
}
function buildAdminEmail($d) {
return '
BUKTI TRANSFER BARU
Order #'.$d['order_id'].'
Detail Transfer
Customer'.htmlspecialchars($d['customer_name']).'
Email Customer'.htmlspecialchars($d['customer_email']?:'-').'
Nama Pengirim'.htmlspecialchars($d['sender_name']).'
Bank Pengirim'.htmlspecialchars($d['sender_bank']).'
Jumlah TransferRp '.number_format($d['amount'],0,',','.').'
Tanggal Transfer'.htmlspecialchars($d['transfer_date']).'
Harap verifikasi bukti transfer ini sesegera mungkin.
Waktu: '.date('d M Y, H:i').' WIB
IP: '.($_SERVER['REMOTE_ADDR']??'N/A').'
';
}
?>
Secure Payment - Order #
ORDER #
Total Bill to Transfer
CUSTOMER NAME
PAYMENT DEADLINE
Confirmation of Payment
Verify your payment proof document
Proof Submitted
Dokumen sedang diverifikasi (maks. 10 menit).