Dokumentasi Sistem
Annual Pass

Taman Safari Indonesia
Panduan Pengguna · Panduan CMS · Dokumentasi Teknis
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

BagianAlamat (demo)Pengguna
Portal pelanggantsi.103-161-184-82.sslip.ioCalon & pemegang Annual Pass
CMS admincms.tsi.103-161-184-82.sslip.ioAdmin, kasir, petugas gerbang
APIapi.tsi.103-161-184-82.sslip.ioAplikasi TSI, ESB, DOKU, GlobalTix
Dokumentasidocs.tsi.103-161-184-82.sslip.ioHalaman ini
Alamat di atas memakai sslip.io untuk demo. Saat server production siap, diganti ke subdomain resmi Taman Safari tanpa mengubah cara kerjanya.

Alur singkat

  1. Pelanggan beli Annual Pass di portal, bayar lewat DOKU (VA/QRIS/kartu).
  2. Setelah lunas, Annual Pass aktif dan setiap anggota keluarga dapat Member ID sendiri.
  3. Sebelum berkunjung, pelanggan membuat reservasi tanggal, lalu konfirmasi (H-1 atau hari-H) → terbit QR Masuk.
  4. Di gerbang, petugas memindai QR Masuk; di kasir F&B/wahana, pelanggan menunjukkan QR Member ID untuk diskon.
  5. Transaksi F&B dari ESB masuk ke sistem; laporan terlihat di CMS.

2Istilah

IstilahArti
Annual PassKeanggotaan tahunan. Dulu disebut "membership".
Member IDNomor pengenal tiap orang (format TSI-XXXX-XXXXX), dipakai kasir ESB untuk memberi diskon dan mencatat belanja atas nama orang itu.
QR MasukQR untuk gerbang taman. Terbit setelah reservasi dikonfirmasi, berganti tiap 30 detik, dan hanya berlaku di hari kunjungan.
QR Member IDQR berisi Member ID untuk kasir F&B/wahana. Tidak berubah.
ReservasiPendaftaran tanggal kunjungan. Wajib sebelum datang.
KomposisiIsi paket keluarga: jumlah dewasa + anak (mis. 2 dewasa + 1 anak 1–5 th).
Produk tersembunyiProduk 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

  1. Buka portal → Lihat Paket / Pilih Pass.
  2. Pilih taman: Satu Taman (Bogor/Prigen/Batang/Bali) atau Multi Taman (satu pass untuk beberapa taman).
  3. Untuk siapa: Student, Couple, Family, dll.
  4. Pilih paket → halaman checkout: data pemegang, anggota keluarga, metode bayar.
  5. 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.

Setelah lunas: Annual Pass aktif, Member ID terbit, dan pelanggan bisa langsung membuat reservasi.

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%.

Nama anggota keluarga dikunci setelah tersimpan: petugas gerbang mencocokkan orang dengan Member ID lewat namanya. Untuk ganti orang, keluarkan anggota lalu daftarkan yang benar.

6Reservasi & QR Masuk Pengguna

  1. Menu Kunjungan → Buat Reservasi → pilih taman & tanggal.
  2. Pada H-1 atau hari-H, tekan "Saya akan datang" untuk konfirmasi kedatangan.
  3. Setelah konfirmasi, QR Masuk terbuka. Di gerbang, tunjukkan QR ke petugas.

7QR Member ID di kasir Pengguna

Untuk belanja F&B dan wahana di kasir ESB — berbeda dengan QR Masuk.

  1. Beri tahu kasir bahwa Anda member Annual Pass.
  2. Buka Ringkasan → tekan "QR Member ID untuk kasir" (atau ketuk Member ID).
  3. Kasir memindai QR itu, atau mengetik Member ID tanpa tanda strip (mis. TSI482917365).
  4. Diskon member langsung terpotong di struk.
  5. Beberapa menit kemudian struknya muncul di Transaksi › Belanja F&B.
Tip: naikkan kecerahan layar supaya QR mudah dipindai. Panduan lengkap ada di menu "Cara pakai Annual Pass" (/akun/panduan).

8Belanja, akun, aplikasi Pengguna

9CMS — Akses & peran Admin

CMS dibuka di cms.tsi…. Menu yang tampil mengikuti peran.

PeranAkses utama
Super AdminSemua menu, termasuk Integrasi, Pengguna, Setelan.
Admin UnitProduk, reservasi, laporan, member untuk unitnya.
Kasir (Counter)Penjualan loket, member, reservasi.
Validator (Gerbang)Scan QR, statistik akses.
HO FinanceLaporan, tagihan unit.

10Produk & harga Admin

Membership Products → Create Product membuka Membership Builder (9 langkah).

LangkahIsi
1. Product InformationKode, nama, tipe, kategori home page, gambar, saklar Show in the public catalog (lihat bab 11).
2. Membership RulesCakupan Single/Multi Park, masa berlaku, hari kunjungan, Not valid on public holidays, Not valid in high season.
3. Visit LimitsKuota kunjungan; "Unlimited visits" per produk.
4. Family CapacityJumlah orang, komposisi dewasa/anak, harga tambah orang, diskon (bab 11).
5. PricingHarga publikasi + harga promo berjangka waktu.
6. Benefits & LocationsManfaat (diskon F&B/wahana, dll) dan lokasi tercakup. Single Park = satu lokasi.
7–8. NetSuite & PairingAkun NetSuite dan pairing tiket GlobalTix.
9. Review & PublishTinjau, simpan sebagai draft atau aktifkan.
Urutan kartu produk di portal diatur di daftar Membership Products (drag & drop, atau harga/nama/terbaru). Banner hero/footer diatur di menu Banners.

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":

12Operasional Admin

MenuFungsi
Scan QRValidasi QR Masuk di gerbang. Ada mode offline: validasi tanpa internet + daftar tamu harian + pencarian offline.
Members / ReservationsData member dan reservasi; status kunjungan.
ESB F&B POSTransaksi F&B dari ESB: ringkasan, per outlet & taman, struk per item, ekspor Excel (per item).
Reports & AnalyticsLaporan pendapatan dan kunjungan.
Promotions / Referral CodesPromo dan kode member-get-member.
Park LocationsTitik & radius taman untuk geofence QR.
Email Templates / Receipt TemplateTeks 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.

Memilih DOKU Production berarti pembayaran menjadi uang nyata. Pastikan channel (BCA VA/QRIS/dll) sudah diaktifkan di akun DOKU production, dan Notification URL terdaftar di dashboard DOKU.

Unit Credentials

Akun GlobalTix/ESB berbeda per taman diisi di Unit Credentials; tanpa itu, unit memakai akun bawaan dari server.

14Arsitektur Teknis

KomponenTeknologiPort
APIGo (gin + gorm), PostgreSQL8090
Portal pelanggan (web)SvelteKit 2 / Svelte 5, Tailwind, adapter-node8092
CMS (dashboard)SvelteKit 2 / Svelte 5, adapter-node8082
Face engine (opsional)Python8095

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
Hak akses: setelah build sebagai root, 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

Variabel lingkungan penting (api/.env)

KunciGuna
JWT_SECRET, QR_SECRETToken login & QR (wajib, ≥32 char).
INTEGRATION_KEYKunci enkripsi kredensial integrasi & Integration Settings (wajib dibawa sama saat pindah server).
LICENSE_KEYLisensi domain + masa sewa (bab 18).
DB_*, APP_URL, CORS_ORIGINSDatabase & alamat.
DOKU_*, ESB_*, GLOBALTIX_*, NETSUITE_*, COGNITO_*Integrasi (bisa ditimpa dari CMS Integration Settings).

17Integrasi (detail) Teknis

IntegrasiRingkas
DOKUCheckout 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 LoyaltyLookup member by Member ID/HP (tanpa tanda baca), kirim transaksi & voucher. Outlet via Company Code (longest-prefix) ke taman.
GlobalTixBooking tiket kunjungan/parkir/wahana; pairing produk ke tiket. Akun per taman di Unit Credentials.
NetSuiteJurnal penjualan harian & pengakuan pendapatan.
Amazon CognitoLogin 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

19Go-live & pindah server Teknis

Perlu VPS Ubuntu 24.04 dengan akses root (bukan hosting PHP managed). Butuh PostgreSQL, Go, Node, nginx, systemd.

  1. Siapkan server, clone repo, isi api/.env (bawa INTEGRATION_KEY & OIDC_SIGNING_KEY sama; buat LICENSE_KEY untuk domain baru).
  2. Restore database, jalankan scripts/bersihkan-data-uji.sh (buang data uji, simpan setelan) dan scripts/ganti-domain-gambar.sh.
  3. Pasang service + nginx + SSL (template di scripts/server-baru/), update.sh --force.
  4. Daftarkan alamat baru di DOKU (Notification URL), ESB, GlobalTix, Cognito (callback), aplikasi TSI.
  5. Smoke test; aktifkan DOKU production dari CMS saat channel siap.
Rincian lengkap: docs/Runbook_Pindah_Server_Live.md di repo.

© 2026 PT Liburania Teknologi Internasional · Dokumentasi Sistem Annual Pass Taman Safari Indonesia.