Dokumentasi Sistem
Annual Pass
Disusun oleh PT Liburania Teknologi Internasional
1Ikhtisar
Annual Pass adalah sistem keanggotaan tahunan Taman Safari: satu pembelian, kunjungan sepuasnya selama 12 bulan, plus diskon F&B dan wahana. Terdiri atas portal pelanggan, CMS admin, dan API yang menghubungkan ke DOKU (pembayaran), ESB (POS F&B), GlobalTix (tiket), NetSuite (akuntansi), dan aplikasi Taman Safari (login).
Alamat
| Bagian | Alamat (demo) | Pengguna |
|---|---|---|
| Portal pelanggan | tsi.103-161-184-82.sslip.io | Calon & pemegang Annual Pass |
| CMS admin | cms.tsi.103-161-184-82.sslip.io | Admin, kasir, petugas gerbang |
| API | api.tsi.103-161-184-82.sslip.io | Aplikasi TSI, ESB, DOKU, GlobalTix |
| Dokumentasi | docs.tsi.103-161-184-82.sslip.io | Halaman ini |
sslip.io untuk demo. Saat server production siap, diganti ke subdomain resmi Taman Safari tanpa mengubah cara kerjanya.Alur singkat
- Pelanggan beli Annual Pass di portal, bayar lewat DOKU (VA/QRIS/kartu).
- Setelah lunas, Annual Pass aktif dan setiap anggota keluarga dapat Member ID sendiri.
- Sebelum berkunjung, pelanggan membuat reservasi tanggal, lalu konfirmasi (H-1 atau hari-H) → terbit QR Masuk.
- Di gerbang, petugas memindai QR Masuk; di kasir F&B/wahana, pelanggan menunjukkan QR Member ID untuk diskon.
- Transaksi F&B dari ESB masuk ke sistem; laporan terlihat di CMS.
2Istilah
| Istilah | Arti |
|---|---|
| Annual Pass | Keanggotaan tahunan. Dulu disebut "membership". |
| Member ID | Nomor pengenal tiap orang (format TSI-XXXX-XXXXX), dipakai kasir ESB untuk memberi diskon dan mencatat belanja atas nama orang itu. |
| QR Masuk | QR untuk gerbang taman. Terbit setelah reservasi dikonfirmasi, berganti tiap 30 detik, dan hanya berlaku di hari kunjungan. |
| QR Member ID | QR berisi Member ID untuk kasir F&B/wahana. Tidak berubah. |
| Reservasi | Pendaftaran tanggal kunjungan. Wajib sebelum datang. |
| Komposisi | Isi paket keluarga: jumlah dewasa + anak (mis. 2 dewasa + 1 anak 1–5 th). |
| Produk tersembunyi | Produk yang tidak tampil di katalog, hanya dibeli lewat link/QR (kampanye videotron). |
3Beli Annual Pass Pengguna
Dari portal pelanggan. Bisa tanpa daftar lebih dulu; akun terbentuk otomatis saat pembelian, atau login dulu lewat email/HP, Google, atau Apple.
Langkah
- Buka portal → Lihat Paket / Pilih Pass.
- Pilih taman: Satu Taman (Bogor/Prigen/Batang/Bali) atau Multi Taman (satu pass untuk beberapa taman).
- Untuk siapa: Student, Couple, Family, dll.
- Pilih paket → halaman checkout: data pemegang, anggota keluarga, metode bayar.
- Setujui syarat → bayar.
Paket keluarga dewasa/anak
Paket Family bisa berisi komposisi, misalnya 2 dewasa + 1 anak (1–5 th). Umur dihitung saat beli. Di bawah umur minimum anak gratis dan tidak dihitung; di atas umur maksimum anak dihitung dewasa. Pemegang pass selalu dewasa.
4Pembayaran Pengguna
Pembayaran lewat DOKU. Tersedia Virtual Account (VA), QRIS, dan kartu, tergantung channel yang diaktifkan.
- Virtual Account: nomor VA tampil di halaman portal sendiri, lengkap dengan langkah bayar per bank. Berlaku 60 menit.
- Halaman pembayaran berpindah sendiri setelah pembayaran diterima; status juga dikirim lewat email.
- Jika belum selesai bayar, saat login kembali akan ada pengingat untuk melanjutkan.
5Keluarga & tambah orang Pengguna
Satu Annual Pass berlaku untuk satu keluarga. Tiap anggota punya Member ID sendiri.
Tambah orang di luar paket
Saat checkout atau dari menu Keluarga, pelanggan bisa menambah orang di luar kapasitas paket: Tambah dewasa, Tambah anak, atau Upgrade slot anak ke dewasa (bila anak sudah di atas umur anak). Pada paket berkomposisi, sistem memilih opsi termurah dari tanggal lahir yang diisi.
"Isi nanti"
Pelanggan boleh memilih Isi nanti untuk nama anggota, tetapi tetap bisa menambah/upgrade orang (bayar sekarang, nama diisi belakangan dari menu Keluarga).
Diskon tambah orang
Makin banyak orang ditambah, makin besar diskonnya (diatur per produk di CMS). Contoh: tambah 1–4 orang diskon 5%, tambah 5+ diskon 10%.
6Reservasi & QR Masuk Pengguna
- Menu Kunjungan → Buat Reservasi → pilih taman & tanggal.
- Pada H-1 atau hari-H, tekan "Saya akan datang" untuk konfirmasi kedatangan.
- Setelah konfirmasi, QR Masuk terbuka. Di gerbang, tunjukkan QR ke petugas.
- QR Masuk berganti tiap 30 detik dan hanya berlaku di hari kunjungan — mencegah QR disebar.
- QR tetap bisa dibuka walau sinyal hilang, asalkan sudah pernah dibuka sekali saat online (mode offline).
- QR hanya terbuka di area taman (geofence), sebagai pengaman tambahan.
7QR Member ID di kasir Pengguna
Untuk belanja F&B dan wahana di kasir ESB — berbeda dengan QR Masuk.
- Beri tahu kasir bahwa Anda member Annual Pass.
- Buka Ringkasan → tekan "QR Member ID untuk kasir" (atau ketuk Member ID).
- Kasir memindai QR itu, atau mengetik Member ID tanpa tanda strip (mis.
TSI482917365). - Diskon member langsung terpotong di struk.
- Beberapa menit kemudian struknya muncul di Transaksi › Belanja F&B.
/akun/panduan).8Belanja, akun, aplikasi Pengguna
- Belanja F&B: rincian struk (item, outlet, taman, diskon) di menu Transaksi.
- Foto profil: dipakai petugas gerbang mengenali pemegang pass.
- Pasang aplikasi: portal bisa dipasang di layar HP seperti aplikasi (PWA). Di Android/Chrome muncul dialog pasang; di iPhone lewat Bagikan → "Tambahkan ke Layar Utama". Bila aplikasi TSI ada di App Store/Play Store, banner aplikasi juga muncul.
- Login Google/Apple dan akun aplikasi Taman Safari didukung (SSO).
9CMS — Akses & peran Admin
CMS dibuka di cms.tsi…. Menu yang tampil mengikuti peran.
| Peran | Akses utama |
|---|---|
| Super Admin | Semua menu, termasuk Integrasi, Pengguna, Setelan. |
| Admin Unit | Produk, reservasi, laporan, member untuk unitnya. |
| Kasir (Counter) | Penjualan loket, member, reservasi. |
| Validator (Gerbang) | Scan QR, statistik akses. |
| HO Finance | Laporan, tagihan unit. |
10Produk & harga Admin
Membership Products → Create Product membuka Membership Builder (9 langkah).
| Langkah | Isi |
|---|---|
| 1. Product Information | Kode, nama, tipe, kategori home page, gambar, saklar Show in the public catalog (lihat bab 11). |
| 2. Membership Rules | Cakupan Single/Multi Park, masa berlaku, hari kunjungan, Not valid on public holidays, Not valid in high season. |
| 3. Visit Limits | Kuota kunjungan; "Unlimited visits" per produk. |
| 4. Family Capacity | Jumlah orang, komposisi dewasa/anak, harga tambah orang, diskon (bab 11). |
| 5. Pricing | Harga publikasi + harga promo berjangka waktu. |
| 6. Benefits & Locations | Manfaat (diskon F&B/wahana, dll) dan lokasi tercakup. Single Park = satu lokasi. |
| 7–8. NetSuite & Pairing | Akun NetSuite dan pairing tiket GlobalTix. |
| 9. Review & Publish | Tinjau, simpan sebagai draft atau aktifkan. |
11Diskon bertingkat & produk tersembunyi Admin
Skema diskon (Group Discount)
Tab Group Discount di samping Benefit type master. Buat skema dengan jumlah tingkat bebas (tombol + Add tier): tiap tingkat isi "dari berapa orang" dan "% diskon". Tingkat tertinggi yang tercapai yang dipakai. Di produk (Family Capacity) tinggal pilih skemanya; satu skema bisa dipakai banyak produk.
Produk tersembunyi (kampanye videotron)
Di Product Information, matikan "Show in the public catalog":
- Produk tidak muncul di
/belimaupun halaman depan. - Tetap bisa dibeli lewat link/QR langsung (muncul QR + tombol Copy setelah produk disimpan).
- Pakai untuk produk harga khusus di videotron dalam park; yang beli dari web biasa tetap harga publish.
- Di daftar produk muncul badge Hidden.
12Operasional Admin
| Menu | Fungsi |
|---|---|
| Scan QR | Validasi QR Masuk di gerbang. Ada mode offline: validasi tanpa internet + daftar tamu harian + pencarian offline. |
| Members / Reservations | Data member dan reservasi; status kunjungan. |
| ESB F&B POS | Transaksi F&B dari ESB: ringkasan, per outlet & taman, struk per item, ekspor Excel (per item). |
| Reports & Analytics | Laporan pendapatan dan kunjungan. |
| Promotions / Referral Codes | Promo dan kode member-get-member. |
| Park Locations | Titik & radius taman untuk geofence QR. |
| Email Templates / Receipt Template | Teks email dan struk. |
13Integrasi & setelan Super Admin
Integration Settings
Menu System › Integration Settings: ganti konfigurasi integrasi tanpa membuka server. Per tab: DOKU (Sandbox/Production + Client ID/Secret), ESB, GlobalTix, NetSuite, Aplikasi TSI & Cognito, Email, WhatsApp. Nilai rahasia disimpan terenkripsi (hanya 4 karakter terakhir yang tampil). Menyimpan memuat ulang API ±10 detik.
Unit Credentials
Akun GlobalTix/ESB berbeda per taman diisi di Unit Credentials; tanpa itu, unit memakai akun bawaan dari server.
14Arsitektur Teknis
| Komponen | Teknologi | Port |
|---|---|---|
| API | Go (gin + gorm), PostgreSQL | 8090 |
| Portal pelanggan (web) | SvelteKit 2 / Svelte 5, Tailwind, adapter-node | 8092 |
| CMS (dashboard) | SvelteKit 2 / Svelte 5, adapter-node | 8082 |
| Face engine (opsional) | Python | 8095 |
nginx di depan menangani HTTPS (Let's Encrypt) dan mem-proxy tiap subdomain ke port di atas. Service dijalankan systemd (tsi-api, tsi-web, tsi-dashboard, tsi-face) di VPS Ubuntu dengan akses root. Database PostgreSQL 16.
15Struktur kode Teknis
/srv/tsi-membership/repo
├─ api/ Go: cmd/api, internal/{handler,service,models,...}
├─ web/ Portal pelanggan (SvelteKit)
├─ dashboard/ CMS (SvelteKit)
├─ db/migrations/ 0000NN_*.up.sql / .down.sql (urut, idempoten)
├─ scripts/ deploy, e2e, bersihkan-data-uji, ganti-domain-gambar
├─ docs/ dokumen + situs ini (docs/situs/)
├─ update.sh deploy: pull, build, migrasi, restart, health check
└─ setup.sh setup sekali jalan
chown -R tsi:tsi pada .svelte-kit dan src sebelum deploy, agar service (user tsi) bisa membacanya.16Deploy & migrasi Teknis
# Deploy satu komponen (otomatis: pull, build, migrasi, restart, cek sehat)
/srv/tsi-membership/repo/update.sh --only api --force
/srv/tsi-membership/repo/update.sh --only web --force
/srv/tsi-membership/repo/update.sh --only dashboard --force
- Migrasi SQL di
db/migrations/, dijalankan otomatis olehupdate.sh --only api. pg_dump cadangan diambil sebelum migrasi. - Setiap migrasi punya
.up.sqldan.down.sql, memakaiIF NOT EXISTSagar aman diulang. - Nomor & kode: Member/Membership/Reservation acak dengan Luhn; nomor transaksi sekuensial (
TRX-YYYY-NNNNNN).
Variabel lingkungan penting (api/.env)
| Kunci | Guna |
|---|---|
JWT_SECRET, QR_SECRET | Token login & QR (wajib, ≥32 char). |
INTEGRATION_KEY | Kunci enkripsi kredensial integrasi & Integration Settings (wajib dibawa sama saat pindah server). |
LICENSE_KEY | Lisensi domain + masa sewa (bab 18). |
DB_*, APP_URL, CORS_ORIGINS | Database & alamat. |
DOKU_*, ESB_*, GLOBALTIX_*, NETSUITE_*, COGNITO_* | Integrasi (bisa ditimpa dari CMS Integration Settings). |
17Integrasi (detail) Teknis
| Integrasi | Ringkas |
|---|---|
| DOKU | Checkout widget (Jokul) + Direct VA (nomor VA di halaman sendiri). Signature HMAC. Status diverifikasi ke server DOKU; notifikasi lewat webhook. Sandbox/Production ditentukan dari DOKU_BASE_URL; portal memilih skrip checkout sesuai host. |
| ESB Loyalty | Lookup member by Member ID/HP (tanpa tanda baca), kirim transaksi & voucher. Outlet via Company Code (longest-prefix) ke taman. |
| GlobalTix | Booking tiket kunjungan/parkir/wahana; pairing produk ke tiket. Akun per taman di Unit Credentials. |
| NetSuite | Jurnal penjualan harian & pengakuan pendapatan. |
| Amazon Cognito | Login Google/Apple & akun aplikasi TSI; sinkron user. Sistem juga jadi penyedia OIDC untuk aplikasi TSI. |
QR offline
Token TSIO1.<rsv>.<unit>.<window>.<code>, window = unix/30, code = 10 hex pertama HMAC-SHA256(secret, "rsv|unit|window"), toleransi ±2 window. Validator gerbang bisa memeriksanya tanpa internet.
18Keamanan & lisensi Teknis
- Password di-hash bcrypt; tak pernah disimpan polos.
- HTTPS/TLS semua lalu lintas; API hanya lewat nginx.
- Kredensial integrasi dienkripsi AES-256-GCM dengan
INTEGRATION_KEY. - Query berparameter (aman dari SQL injection); akses per peran.
- Audit log untuk perubahan penting.
- License lock: di produksi, binary API menolak jalan tanpa lisensi Ed25519 yang sah untuk domainnya dan masih dalam masa sewa. Kunci privat penerbit lisensi dipegang Liburania (tidak di repo/server). Melindungi kode dari pemakaian di luar kontrak.
19Go-live & pindah server Teknis
Perlu VPS Ubuntu 24.04 dengan akses root (bukan hosting PHP managed). Butuh PostgreSQL, Go, Node, nginx, systemd.
- Siapkan server, clone repo, isi
api/.env(bawaINTEGRATION_KEY&OIDC_SIGNING_KEYsama; buatLICENSE_KEYuntuk domain baru). - Restore database, jalankan
scripts/bersihkan-data-uji.sh(buang data uji, simpan setelan) danscripts/ganti-domain-gambar.sh. - Pasang service + nginx + SSL (template di
scripts/server-baru/),update.sh --force. - Daftarkan alamat baru di DOKU (Notification URL), ESB, GlobalTix, Cognito (callback), aplikasi TSI.
- Smoke test; aktifkan DOKU production dari CMS saat channel siap.
docs/Runbook_Pindah_Server_Live.md di repo.© 2026 PT Liburania Teknologi Internasional · Dokumentasi Sistem Annual Pass Taman Safari Indonesia.