PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $db_user, $db_pass, $options);
$pdo->exec("CREATE TABLE IF NOT EXISTS email_templates (
id INT AUTO_INCREMENT PRIMARY KEY,
template_key VARCHAR(50) UNIQUE NOT NULL,
template_name VARCHAR(100) NOT NULL,
subject VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
placeholders VARCHAR(255) DEFAULT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
$pdo->exec("CREATE TABLE IF NOT EXISTS smtp_config (
id INT PRIMARY KEY DEFAULT 1,
smtp_host VARCHAR(255) NOT NULL,
smtp_port INT NOT NULL,
smtp_username VARCHAR(255) NOT NULL,
smtp_password VARCHAR(255) NOT NULL,
smtp_secure VARCHAR(10) NOT NULL,
sender_name VARCHAR(255) NOT NULL,
sender_email VARCHAR(255) NOT NULL,
admin_notify_email VARCHAR(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
// Auto-migration: add admin_notify_email column if missing
try {
$pdo->exec("ALTER TABLE smtp_config ADD COLUMN admin_notify_email VARCHAR(255) DEFAULT NULL AFTER sender_email");
} catch (\PDOException $e) {
// Column already exists — ignore
}
$count = $pdo->query("SELECT COUNT(*) FROM smtp_config")->fetchColumn();
if ($count == 0) {
$stmt = $pdo->prepare("INSERT INTO smtp_config (id, smtp_host, smtp_port, smtp_username, smtp_password, smtp_secure, sender_name, sender_email, admin_notify_email) VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([
'mail.hytravellers.asia',
465,
'admin@hytravellers.asia',
'Ewl2547@47',
'ssl',
'HyTravellers Admin',
'admin@hytravellers.asia',
'admin@hytravellers.asia'
]);
}
// === SEED TEMPLATE "send_invoice" SECARA OTOMATIS ===
$stmt_check = $pdo->prepare("SELECT COUNT(*) FROM email_templates WHERE template_key = 'send_invoice'");
$stmt_check->execute();
if ($stmt_check->fetchColumn() == 0) {
$stmt_seed_tpl = $pdo->prepare("INSERT INTO email_templates (template_key, template_name, subject, body, placeholders) VALUES (?, ?, ?, ?, ?)");
$stmt_seed_tpl->execute([
'send_invoice',
'Kirim E-Tiket & Invoice Pelanggan',
'E-Tiket & Invoice Perjalanan Anda - {invoice_id}',
'
E-Tiket & Invoice Perjalanan
{invoice_id}
Halo, {nama} !
Terima kasih telah mempercayakan perjalanan Anda kepada HYTRAVELLERS . E-Tiket dan dokumen penagihan resmi Anda telah berhasil diterbitkan.
Maskapai
{carrier}
Rute Penerbangan
{route}
Tanggal & Jam
{date} | {time} WIB
Status Pembayaran
{status}
Total Pembayaran
{total}
Jika tombol tidak berfungsi, salin tautan berikut ke browser:{link_invoice}
💳 Silakan transfer ke salah satu rekening berikut:
BRI BRIVA 2570 8330 0001 1729 6
Mandiri 8980 8330 0001 1729 6
CIMB Niaga 8429 0330 0001 1729 6
BCA VA 3000 8330 0001 1729 6
A/N PT HYTRAVELLERS
PT HYTRAVELLERS
Ruko Keprimall No.46, Batam Kota, Kepulauan Riau 29444
☎ {phone} | ✉ support@hytravellers.asia | 🌐 hytravellers.asia
',
'{nama}, {email}, {invoice_id}, {link_invoice}, {carrier}, {route}, {date}, {time}, {total}, {status}, {phone}, {web}'
]);
}
// === SEED TEMPLATE "payment_received_customer" SECARA OTOMATIS ===
$stmt_check2 = $pdo->prepare("SELECT COUNT(*) FROM email_templates WHERE template_key = 'payment_received_customer'");
$stmt_check2->execute();
if ($stmt_check2->fetchColumn() == 0) {
$stmt_seed_tpl2 = $pdo->prepare("INSERT INTO email_templates (template_key, template_name, subject, body, placeholders) VALUES (?, ?, ?, ?, ?)");
$stmt_seed_tpl2->execute([
'payment_received_customer',
'Notifikasi Bukti Transfer Diterima (Customer)',
'Bukti Transfer Diterima — Order #{order_id}',
'
BUKTI TRANSFER DITERIMA
Order #{order_id}
Terima kasih, {nama} . Bukti pembayaran transfer Anda telah kami terima dan saat ini sedang dalam proses verifikasi.
Ringkasan Pembayaran
Nama Pengirim
{sender_name}
Bank Pengirim
{sender_bank}
Jumlah Transfer
Rp {amount}
Tanggal Transfer
{transfer_date}
⌛ Estimasi Waktu Verifikasi
Proses verifikasi biasanya memerlukan waktu maksimal 10 menit pada jam operasional. Setelah diverifikasi, Anda akan menerima e-tiket melalui email ini.
Butuh bantuan? Hubungi kami:
📞 0823 7456 4489 (24 jam)
✉ support@hiltontourstravel.com
© 2026 PT Hilton Tours Travel. All Rights Reserved.
',
'{nama}, {order_id}, {amount}, {sender_bank}, {sender_name}, {transfer_date}'
]);
}
// === SEED TEMPLATE "payment_received_admin" SECARA OTOMATIS ===
$stmt_check3 = $pdo->prepare("SELECT COUNT(*) FROM email_templates WHERE template_key = 'payment_received_admin'");
$stmt_check3->execute();
if ($stmt_check3->fetchColumn() == 0) {
$stmt_seed_tpl3 = $pdo->prepare("INSERT INTO email_templates (template_key, template_name, subject, body, placeholders) VALUES (?, ?, ?, ?, ?)");
$stmt_seed_tpl3->execute([
'payment_received_admin',
'Notifikasi Bukti Transfer Baru (Admin)',
'Bukti Transfer Baru - Order #{order_id} - {customer_name}',
'
BUKTI TRANSFER BARU
Order #{order_id}
Detail Transfer
Customer
{customer_name}
Email Customer
{customer_email}
Nama Pengirim
{sender_name}
Bank Pengirim
{sender_bank}
Jumlah Transfer
Rp {amount}
Tanggal Transfer
{transfer_date}
Harap verifikasi bukti transfer ini sesegera mungkin di dashboard admin.
Waktu: {date_time} WIB
IP: {ip_address}
',
'{customer_name}, {customer_email}, {order_id}, {amount}, {sender_bank}, {sender_name}, {transfer_date}, {ip_address}, {date_time}'
]);
}
} catch (\PDOException $e) {
die("Koneksi database atau inisialisasi tabel gagal: " . $e->getMessage());
}
$smtp = $pdo->query("SELECT * FROM smtp_config WHERE id = 1")->fetch();
// === 2. HANDLING ACTIONS (POST / GET) ===
$message = '';
$message_type = '';
$active_tab = 'templates';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'save') {
$active_tab = 'templates';
$id = $_POST['id'] ?? null;
$template_key = trim($_POST['template_key'] ?? '');
$template_name = trim($_POST['template_name'] ?? '');
$subject = trim($_POST['subject'] ?? '');
$body = $_POST['body'] ?? '';
$placeholders = trim($_POST['placeholders'] ?? '');
if (empty($template_key) || empty($template_name) || empty($subject) || empty($body)) {
$message = "Mohon lengkapi semua kolom yang bertanda bintang (*).";
$message_type = "danger";
} else {
try {
if ($id) {
$stmt = $pdo->prepare("UPDATE email_templates SET template_key = ?, template_name = ?, subject = ?, body = ?, placeholders = ? WHERE id = ?");
$stmt->execute([$template_key, $template_name, $subject, $body, $placeholders, $id]);
$message = "Template '$template_name' berhasil diperbarui.";
} else {
$stmt = $pdo->prepare("INSERT INTO email_templates (template_key, template_name, subject, body, placeholders) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$template_key, $template_name, $subject, $body, $placeholders]);
$message = "Template baru '$template_name' berhasil ditambahkan.";
}
$message_type = "success";
} catch (\PDOException $e) {
$message = "Gagal menyimpan data: " . $e->getMessage();
$message_type = "danger";
}
}
}
if ($action === 'save_smtp') {
$active_tab = 'smtp';
$smtp_host = trim($_POST['smtp_host'] ?? '');
$smtp_port = (int)($_POST['smtp_port'] ?? 465);
$smtp_username = trim($_POST['smtp_username'] ?? '');
$smtp_password = $_POST['smtp_password'] ?? '';
$smtp_secure = $_POST['smtp_secure'] ?? 'ssl';
$sender_name = trim($_POST['sender_name'] ?? '');
$sender_email = trim($_POST['sender_email'] ?? '');
$admin_notify_email = trim($_POST['admin_notify_email'] ?? '');
if (empty($smtp_host) || empty($smtp_username) || empty($sender_name) || empty($sender_email)) {
$message = "Mohon lengkapi semua isian konfigurasi SMTP.";
$message_type = "danger";
} else {
try {
$stmt = $pdo->prepare("UPDATE smtp_config SET smtp_host = ?, smtp_port = ?, smtp_username = ?, smtp_password = ?, smtp_secure = ?, sender_name = ?, sender_email = ?, admin_notify_email = ? WHERE id = 1");
$stmt->execute([$smtp_host, $smtp_port, $smtp_username, $smtp_password, $smtp_secure, $sender_name, $sender_email, $admin_notify_email]);
$smtp = $pdo->query("SELECT * FROM smtp_config WHERE id = 1")->fetch();
$message = "Konfigurasi SMTP berhasil diperbarui.";
$message_type = "success";
} catch (\PDOException $e) {
$message = "Gagal memperbarui SMTP: " . $e->getMessage();
$message_type = "danger";
}
}
}
if ($action === 'smtp_test') {
$active_tab = 'smtp';
$test_email = trim($_POST['test_email'] ?? '');
if (!$phpmailer_installed) {
$message = "Gagal mengirim tes: File PHPMailer tidak ditemukan di server.";
$message_type = "danger";
} elseif (empty($test_email) || !filter_var($test_email, FILTER_VALIDATE_EMAIL)) {
$message = "Masukkan alamat email penerima yang valid.";
$message_type = "danger";
} else {
try {
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $smtp['smtp_host'];
$mail->SMTPAuth = true;
$mail->Username = $smtp['smtp_username'];
$mail->Password = $smtp['smtp_password'];
$mail->SMTPSecure = ($smtp['smtp_secure'] === 'ssl') ? PHPMailer::ENCRYPTION_SMTPS : PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = $smtp['smtp_port'];
$mail->setFrom($smtp['sender_email'], $smtp['sender_name']);
$mail->addAddress($test_email);
$mail->isHTML(true);
$mail->Subject = 'Tes Koneksi SMTP HyTravellers Berhasil';
$mail->Body = '
Koneksi SMTP Berhasil Terhubung!
Email uji coba ini dikirim menggunakan konfigurasi SMTP terbaru Anda.
Rincian Server SMTP yang Aktif:
Host: ' . htmlspecialchars($smtp['smtp_host']) . '
Port: ' . htmlspecialchars($smtp['smtp_port']) . ' (' . strtoupper($smtp['smtp_secure']) . ')
Username: ' . htmlspecialchars($smtp['smtp_username']) . '
Nama Pengirim: ' . htmlspecialchars($smtp['sender_name']) . '
Waktu Pengujian: ' . date('Y-m-d H:i:s') . '
';
$mail->AltBody = 'Koneksi SMTP Berhasil Terhubung! Tes dilakukan pada ' . date('Y-m-d H:i:s');
$mail->send();
$message = "Koneksi SMTP Sukses! Email pengetesan berhasil dikirim ke: " . htmlspecialchars($test_email);
$message_type = "success";
} catch (Exception $e) {
$message = "Koneksi SMTP Gagal: " . $mail->ErrorInfo;
$message_type = "danger";
}
}
}
if ($action === 'test_send') {
$active_tab = 'templates';
$template_id = $_POST['template_id'] ?? null;
$test_email = trim($_POST['test_email'] ?? '');
if (!$phpmailer_installed) {
$message = "Gagal mengirim tes: File PHPMailer tidak ditemukan di server.";
$message_type = "danger";
} elseif (empty($test_email) || !filter_var($test_email, FILTER_VALIDATE_EMAIL)) {
$message = "Masukkan alamat email penerima yang valid.";
$message_type = "danger";
} else {
try {
$stmt = $pdo->prepare("SELECT * FROM email_templates WHERE id = ?");
$stmt->execute([$template_id]);
$template = $stmt->fetch();
if ($template) {
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $smtp['smtp_host'];
$mail->SMTPAuth = true;
$mail->Username = $smtp['smtp_username'];
$mail->Password = $smtp['smtp_password'];
$mail->SMTPSecure = ($smtp['smtp_secure'] === 'ssl') ? PHPMailer::ENCRYPTION_SMTPS : PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = $smtp['smtp_port'];
$mail->setFrom($smtp['sender_email'], $smtp['sender_name']);
$mail->addAddress($test_email);
$simulated_pdf_link = "https://" . $_SERVER['HTTP_HOST'] . "/invoice.php?booking_id=1";
$replacements = [
'{nama}' => 'Ahmad Ridwan',
'{customer_name}' => 'Ahmad Ridwan',
'{customer_email}' => $test_email,
'{email}' => $test_email,
'{invoice_id}' => 'INV/SAMPLE/001',
'{link_invoice}'=> $simulated_pdf_link,
'{carrier}' => 'Singapore Airlines',
'{route}' => 'CGK → SIN',
'{date}' => 'Thu, 26 Jun 2026',
'{time}' => '08:00 - 10:50',
'{total}' => 'Rp 8.450.000',
'{status}' => 'PENDING',
'{phone}' => '0823 7456 4489 (24 jam)',
'{web}' => 'https://hytravellers.asia',
'{link_reset}' => '#',
'{order_id}' => '000047',
'{amount}' => '1.379.345',
'{sender_name}' => 'Ahmad Ridwan',
'{sender_bank}' => 'BCA (Bank Central Asia)',
'{transfer_date}' => '2026-06-24',
'{ip_address}' => '127.0.0.1',
'{date_time}' => '24 Jun 2026, 22:41'
];
$subject = str_replace(array_keys($replacements), array_values($replacements), $template['subject']);
$body = str_replace(array_keys($replacements), array_values($replacements), $template['body']);
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $body;
$mail->AltBody = strip_tags($body);
$mail->send();
$message = "Email uji coba menggunakan template '" . htmlspecialchars($template['template_name']) . "' berhasil dikirim ke " . htmlspecialchars($test_email);
$message_type = "success";
} else {
$message = "Template tidak ditemukan.";
$message_type = "danger";
}
} catch (Exception $e) {
$message = "SMTP Error: " . $mail->ErrorInfo;
$message_type = "danger";
}
}
}
}
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
$active_tab = 'templates';
try {
$stmt = $pdo->prepare("DELETE FROM email_templates WHERE id = ?");
$stmt->execute([$_GET['id']]);
$message = "Template berhasil dihapus.";
$message_type = "success";
} catch (\PDOException $e) {
$message = "Gagal menghapus template: " . $e->getMessage();
$message_type = "danger";
}
}
$edit_data = null;
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
$active_tab = 'templates';
$stmt = $pdo->prepare("SELECT * FROM email_templates WHERE id = ?");
$stmt->execute([$_GET['id']]);
$edit_data = $stmt->fetch();
}
$stmt = $pdo->query("SELECT * FROM email_templates ORDER BY id DESC");
$templates = $stmt->fetchAll();
// === FUNGSI RENDER PREVIEW HTML DENGAN DATA SAMPLE ===
$preview_sample_data = [
'{nama}' => 'Ahmad Ridwan',
'{customer_name}' => 'Ahmad Ridwan',
'{customer_email}' => 'ahmad.ridwan@gmail.com',
'{email}' => 'ahmad.ridwan@gmail.com',
'{invoice_id}' => 'INV/20260624/HT/000042',
'{link_invoice}'=> 'https://hytravellers.asia/invoice.php?booking_id=42',
'{carrier}' => 'Singapore Airlines',
'{route}' => 'CGK → SIN',
'{date}' => 'Thu, 26 Jun 2026',
'{time}' => '08:00 - 10:50',
'{total}' => 'Rp 8.450.000',
'{status}' => 'PENDING',
'{phone}' => '0823 7456 4489 (24 jam)',
'{web}' => 'https://hytravellers.asia',
'{link_reset}' => '#',
'{order_id}' => '000047',
'{amount}' => '1.379.345',
'{sender_name}' => 'Ahmad Ridwan',
'{sender_bank}' => 'BCA (Bank Central Asia)',
'{transfer_date}' => '2026-06-24',
'{ip_address}' => '127.0.0.1',
'{date_time}' => '24 Jun 2026, 22:41'
];
?>
Master Email & SMTP - HyTravellers
✉️ Master Email & SMTP
Kelola konfigurasi server SMTP dan template email otomatis sistem HyTravellers.
PHPMailer:
📝 Template Email
⚙️ Konfigurasi SMTP
Template
Subjek
Aksi
0): ?>
Belum ada template email.
0): ?>
Identitas Pengirim
🔔
Email Admin Notifikasi
Email ini akan menerima notifikasi otomatis setiap kali customer mengupload bukti transfer pembayaran di halaman pembayaran.
💾 Simpan Konfigurasi
🔔 Notifikasi bukti transfer aktif di
Ubah di form SMTP di atas → "Email Admin Notifikasi"