think
16px
820px

Obscura — daftar harga (usulan keputusan)

Status: usulan, belum diputuskan. Semua angka adalah harga LIST (sebelum diskon), IDR, belum termasuk PPN. Revisi 3 — 2026-08-24.

Sudah diputuskan dan tidak dibuka lagi: nama dua edisi (Obscura Enterprise / Obscura Cloud), band seat dinamai menurut jumlah seat, core perpetual Rp 500 juta (Pak Fariz), harga modul sebagai % dari core, ASM 20%/tahun, dan tarif seat Cloud Starter Rp 75.000 · Professional Rp 125.000 · Enterprise Rp 200.000 (ketiganya disetujui 2026-08-24) — beserta konsekuensinya, bundel Enterprise on-prem Rp 1,2 miliar di band 250.

Perubahan di revisi 3:

  • Tangga Cloud mengikuti katalog plan yang baru di operator console: Starter → Professional → Records → Business → Enterprise (lima tier, bukan tiga). Kode plan starter/professional/records/business/enterprise dipakai sebagai satu-satunya kosakata di lisensi, invoice dan e-Katalog.
  • Modul bertambah dari 6 menjadi 8: securefolder (Brankas) dan contracts (Contract Intelligence) sekarang ada di KnownModules dan sudah dijual di tier Records/Enterprise. Keduanya masuk tabel harga modul.
  • Karena tier Enterprise kini memuat 8 modul (dulu 6), tarifnya naik Rp 175rb → Rp 200rb/seat dan bundel on-prem naik Rp 950 juta → Rp 1,2 miliar di band 250. ✅ Disetujui 2026-08-24.
  • §5 ASM ditulis ulang total — menjawab "jadi mereka bayar ASM supaya modul tambahan tetap hidup?" Jawaban singkatnya: tidak.

Perubahan di revisi 4 (2026-08-24, sore): seat Cloud tidak lagi ditagih per akun aktif, melainkan sebagai blok 5 seat (per_seat_amount = 0 di semua plan). Invoice menjadi angka tetap yang muat di satu SP/PO, dan tangga tarif berjenjang jadi bisa ditagih hari ini tanpa menulis kode — rantai add-on (StackableAttachAddonResolveEntitlementEffectiveSeatsGuardSeat) sudah lengkap dan sudah diverifikasi di kode.


1. Ringkasan — empat lini produk

Lini Siapa yang menjalankan server Model Titik masuk
Obscura Cloud kami, bersama tenant lain langganan tahunan Rp 34,5 juta/tahun (Starter, 25 seat)
Obscura Cloud Private kami, instance khusus 1 pelanggan langganan tahunan Rp 350 juta/tahun (lantai)
Obscura Enterprise pelanggan, on-prem, 1 organisasi lisensi perpetual + ASM Rp 500 juta (Enterprise 250, Dasar/core)
Obscura Cloud Enterprise pelanggan, on-prem, multi-tenant lisensi platform perpetual + ASM Rp 2,5 miliar (Platform 10, semua modul)

Tiga aturan yang mengikat keempatnya. Pakai ini untuk menjawab pertanyaan harga yang tidak ada di tabel mana pun.

  1. Core Rp 500 juta = band Enterprise 250. Di bawah 250 seat, jawabannya bukan perpetual yang lebih murah — jawabannya Cloud. Anchor Pak Fariz tetap utuh dan Cloud punya pekerjaan yang jelas.
  2. Satu nama tier = satu daftar modul, di kedua edisi. records di Cloud dan bundel Records on-prem berisi modul yang sama persis. Tanpa aturan ini, "Records" berarti dua hal berbeda di dua penawaran dan tidak ada yang bisa membandingkan apa pun.
  3. Cloud setahun ≈ 46% dari harga lisensi perpetual setara. Titik impas ±6,5 tahun bila server, sysadmin dan DRC pembeli on-prem dihitung (±Rp 125 juta/tahun), 3,9 tahun bila server mereka dianggap gratis. Yang harus dilawan di ruang penawaran adalah kalimat "servernya kan sudah ada", bukan harganya. Hitungannya di §9 S5.

2. Obscura Cloud — kami yang mengelola

Model: harga dasar tetap (sudah termasuk sejumlah seat) + blok seat tambahan. Ditagih tahunan. Tidak ada tagihan yang bergerak mengikuti jumlah karyawan — invoice adalah angka tetap yang bisa ditulis di satu SP/PO.

Tier Modul (persis seperti di console) Seat termasuk Harga dasar/tahun Storage termasuk
Starter correspondence 25 Rp 34,5 juta 50 GB
Professional + office 25 Rp 55,5 juta 250 GB
Records + klasifikasi, securefolder 25 Rp 67,5 juta 1 TB
Business + esign, ai 25 Rp 87 juta 1 TB
Enterprise + watermarking, contracts (semua 8) 50 Rp 168 juta 2 TB

Harga dasar itu = biaya platform + seat yang termasuk, mis. Enterprise = Rp 48 juta + 50 × Rp 200rb × 12.

Seat tambahan — dijual per blok 5

Tarif per seat turun sesuai TOTAL seat tenant. Harga blok = 5 × tarif band × 12.

Tier Blok B1 (total ≤100) B2 (101–500) B3 (501–2.000) B4 (2.001+)
Starter Rp 4,5 juta naik ke Professional
Professional Rp 7,5 juta Rp 5,7 juta Rp 3,9 juta Rp 2,7 juta
Records Rp 8,7 juta Rp 6,6 juta Rp 4,5 juta Rp 3 juta
Business Rp 10,2 juta Rp 7,8 juta Rp 5,4 juta Rp 3,6 juta
Enterprise Rp 12 juta Rp 9 juta Rp 6,3 juta Rp 4,2 juta

Tarif per seat/bulan yang mendasarinya (untuk perbandingan di penawaran, bukan untuk penagihan):

Tier seat 1–100 101–500 501–2.000 2.001+
Starter 75.000
Professional 125.000 95.000 65.000 45.000
Records 145.000 110.000 75.000 50.000
Business 170.000 130.000 90.000 60.000
Enterprise 200.000 150.000 105.000 70.000

Contoh — Enterprise 250 seat: dasar Rp 168 juta (50 seat) + 10 blok B1 (→100 seat) Rp 120 juta + 30 blok B2 (→250 seat) Rp 270 juta = Rp 558 juta/tahun. Persis sama dengan hitungan bertingkat, hanya tersusun dari baris-baris yang bisa ditagih hari ini — dan invoice mengelompokkan kode yang berulang menjadi satu baris dengan quantity, jadi tampilannya tetap dua baris, bukan empat puluh.

Kenapa blok 5, bukan 25. Blok 25 memaksa pelanggan 40 seat membeli 50. Blok 5 membuat setiap ukuran organisasi jatuh tepat, dengan ongkos satu angka quantity yang lebih besar — yang tidak dilihat siapa pun karena invoice mengelompokkannya.

Kenapa blok, bukan hitung-akun-otomatis. Kode hanya bisa menagih satu tarif seat datar per langganan (IssueInvoice: PerSeat × jumlah akun), jadi tangga berjenjang tidak bisa ditagih sebagai tarif. Sebagai blok add-on, tiap band menjadi baris invoice tersendiri dengan quantity, dan hasilnya identik — tanpa satu baris kode baru. Lagi pula, tagihan yang berubah tiap ada staf masuk/keluar adalah masalah bagi pembeli pemerintah yang PO-nya satu nominal.

Aturan yang menyertainya:

  • Seat dibulatkan ke atas ke kelipatan 5. Pelanggan minta 62 seat ⇒ jual 65.
  • Blok menumpuk (quantity naik tiap kali dilekatkan) dan langsung menaikkan plafon seat tenant pada pengukuran berikutnya (≤60 detik).
  • per_seat_amount di semua harga plan = 0. Mencampur blok dengan hitung-akun-otomatis pada satu tenant = tagih dua kali.
  • Starter berhenti di 100 seat. Di atas itu, naik ke Professional.
  • 🔴 Kalau tab Quotas tenant pernah diisi angka seat secara manual, override itu selalu menang dan blok yang dibeli tidak akan menaikkan plafon. Kosongkan kolom itu agar plan yang menentukan.

Kenapa ada biaya platform di dalam harga dasar. Tenant berisi 25 orang dan tenant berisi 250 orang menghabiskan biaya kami yang hampir sama untuk hal-hal yang tidak bergantung jumlah orang: schema Postgres sendiri, backup terenkripsi yang ditarik dan diuji, pemantauan, jendela upgrade, dan — yang paling mahal — satu jalur dukungan berbahasa manusia. Itu ±Rp 500–800 ribu/bulan per tenant sebelum satu orang pun login. Tarif murni per seat menagih nol untuk semua itu dan membuat tenant kecil merugi.

Kenapa tarif seat turun berjenjang. Tanpa jenjang, 800 pengguna di Cloud menjadi ±Rp 2 juta/seat/tahun sementara lisensi perpetual 1.000 seat hanya ±Rp 2 juta/seat sekali bayar — penawaran Cloud kita sendiri yang membunuh dirinya. Dengan jenjang, Cloud masuk akal sampai ±500 seat, dan di atas itu jawaban jujurnya memang Enterprise on-prem (lihat S4).

Kenapa Records lebih murah dari Business padahal storage-nya sama. Records adalah tier arsip: pembelinya unit kearsipan yang jumlah orangnya sedikit tetapi dokumennya banyak. Business adalah tier komersial: orangnya banyak, dokumennya bernilai transaksi. Kalau storage Records dipangkas, tier itu kehilangan alasan keberadaannya.

  • Bayar bulanan: +20% — tabel lengkapnya di bawah.
  • Prabayar 3 tahun: −15%, harga dikunci.
  • Pemetaan ke kode: plan_prices.base_amount = harga dasar tier, per_seat_amount = 0. Tiap blok seat adalah plan kind='addon' dengan user_quota = 25 dan harganya sendiri. Daftar lengkapnya di §11.
  • ⚠️ Kelima plan di console masih bertanda "no price". Selama itu merah, tidak satu pun tier di atas bisa ditagih.

Harga bulanan — hanya untuk Cloud

Rumus: harga tahunan × 0,1 (yaitu ÷12 lalu +20%). Berlaku untuk semuanya — harga dasar, blok seat, dan blok storage. Enterprise dan Cloud Enterprise tidak punya harga bulanan; keduanya lisensi, bukan langganan.

Tier Harga dasar/bulan Blok B1/bulan B2 B3 B4
Starter Rp 3,45 juta Rp 450 ribu
Professional Rp 5,55 juta Rp 750 ribu Rp 570 ribu Rp 390 ribu Rp 270 ribu
Records Rp 6,75 juta Rp 870 ribu Rp 660 ribu Rp 450 ribu Rp 300 ribu
Business Rp 8,7 juta Rp 1,02 juta Rp 780 ribu Rp 540 ribu Rp 360 ribu
Enterprise Rp 16,8 juta Rp 1,2 juta Rp 900 ribu Rp 630 ribu Rp 420 ribu

Storage ikut aturan yang sama: blok 100 GB = Rp 300 ribu/bulan, blok 1 TB = Rp 2,4 juta/bulan.

Kenapa +20%, dan kenapa itu bukan denda. Pelanggan bulanan menghasilkan 12 invoice, 12 pembayaran, dan 12 kemungkinan penagihan susulan per tahun — biaya administrasi yang nyata, di atas hilangnya kepastian pendapatan. Angkanya juga harus cukup lebar supaya "coba dulu bulanan, nanti pindah tahunan" berakhir dengan pindah, bukan menetap.

Syarat yang menyertainya (ini bagian dari harga, bukan tambahan): bulanan = tanpa komitmen, berhenti dengan pemberitahuan 1 bulan; tahunan = komitmen 12 bulan. Tanpa aturan itu, bulanan hanyalah tahunan yang lebih mahal dan tidak ada yang mau membelinya.

⚠️ Bulanan hampir tidak pernah cocok untuk pembeli pemerintah — mereka membeli dengan satu SP/kontrak per tahun anggaran, dan 12 invoice justru menambah pekerjaan bendahara. Tawarkan bulanan ke perusahaan swasta, startup, notaris/PPAT, dan pilot yang belum punya PO.

⚠️ Periode bulanan dijepit ke akhir bulan: 31 Januari + 1 bulan = 28 Februari, bukan 3 Maret. Tanggal tagih pelanggan karena itu tidak pernah bergeser maju secara permanen.

Storage tambahan

SKU Harga Per GB Catatan
Blok 100 GB Rp 250 ribu/bulan (Rp 3 juta/tahun) Rp 2.500 bertumpuk lewat tenant_plans.quantity
Blok 1 TB Rp 2 juta/bulan (Rp 24 juta/tahun) Rp 2.000 untuk digitalisasi arsip retro
di atas 5 TB penawaran khusus, lantai Rp 1.500/GB/bulan

⚠️ Satuannya biner (GiB) di seluruh sistem — pelanggan diukur pada 1024³ sesuai humanBytes/fmtBytes. Jangan menjanjikan "GB desimal" di kontrak.

⚠️ Storage yang termasuk paket tidak bisa dihitung otomatis per seat ("10 GB × seat"): resolusi kuota hanya menjumlahkan angka tetap dari plan dan add-on. Penyimpangan dilakukan operator lewat override per tenant — dan override selalu menang atas katalog.

Seat

Plafon seat tenant datang dari plan + blok yang dilekatkan, bukan dari angka yang diketik. Biarkan kolom seat di tab Quotas tenant kosong; kalau diisi, override manual itu mengalahkan semua blok yang dibeli.

Prorata SUDAH ADA (§12 #2, selesai 2026-08-25): blok yang dilekatkan di tengah periode ditagih untuk sisa periode lewat invoice tersendiri di luar siklus, dijalankan sapuan harian. Tidak perlu lagi menerbitkan invoice manual, dan prorata boleh dijanjikan di kontrak untuk PENAMBAHAN. ⚠️ Pengurangan di tengah periode tetap tidak dikembalikan otomatis — invoice yang sudah terbit bersifat final, dan pengembalian dana adalah keputusan operator; invoice perpanjangan berikutnya menagih jumlah yang lebih rendah.

Definisi seat (Cloud): akun aktif (tidak disabled), bukan akun layanan. Menonaktifkan karyawan yang keluar langsung membebaskan seat. Penanda tangan eksternal tidak pernah menjadi seat — pembeda utama melawan pesaing yang menagih per pengguna.

Diskon dan program

Program Aturan
Pilot 3 bulan gratis, Starter, maks. 25 seat, otomatis berhenti
Prabayar 3 tahun −15%
Mitra/SI reseller −25% dari list, mitra memegang relasi pelanggan
Tender pemerintah jangan pernah diskon tarif per seat — diskon lewat bundel dan biaya platform saja

Alasan baris terakhir: tarif per seat adalah angka yang tayang di e-Katalog dan dipakai pelanggan berikutnya sebagai pembanding. Yang bocor bukan satu deal, melainkan seluruh daftar harga.


3. Obscura Cloud Private — instance khusus, kami yang mengelola

Untuk pembeli yang menolak berbagi deployment tetapi tidak mau mengurus server.

Harga = tarif tier Cloud × 1,5, lantai Rp 350 juta/tahun.

Termasuk: VM sendiri, domain sendiri, kunci enkripsi blob sendiri, jadwal backup sendiri, jendela upgrade sendiri, dan satu uji-pulih (restore drill) per tahun yang dilaporkan tertulis.

Lantai Rp 350 juta bukan angka gengsi. Satu instance khusus memakan VM (8 vCPU/32 GB/1 TB NVMe) ±Rp 60 juta/tahun, ditambah salinan backup, pemantauan, dan — biaya sebenarnya — jendela upgrade yang tidak bisa digabung dengan tenant lain: setiap rilis harus diuji dan dipasang lagi untuk satu pelanggan ini. Semuanya ±Rp 150–200 juta/tahun. Di bawah Rp 350 juta, Cloud Private adalah pekerjaan yang dibayar setengah harga.

Kenapa Cloud Private terlihat lebih murah daripada Cloud Enterprise — dan sebenarnya tidak

Dua angka itu tidak sebanding: satu langganan tahunan untuk satu organisasi, satu lagi lisensi sekali bayar untuk sepuluh organisasi. Sandingkan pada dasar yang sama:

melayani 5 tahun (lisensi + 5 × ASM) per organisasi per tahun
Cloud Private (lantai) 1 organisasi Rp 1,75 miliar Rp 350 juta
Cloud Enterprise Platform 10 10 organisasi 2,5 M + 5 × 500 jt = Rp 5 miliar Rp 100 juta
Cloud Enterprise Platform 50 50 organisasi 6 M + 5 × 1,2 M = Rp 12 miliar Rp 48 juta

Per organisasi, Cloud Enterprise 3,5–7× lebih murah — dan memang harus begitu, karena di sana pelanggan yang membeli server, membayar sysadmin, menjalankan backup, dan menanggung risiko upgrade. Angka Rp 2,5 miliar hanya terlihat besar karena dibayar sekali dan menanggung sepuluh organisasi sekaligus.

Jadi jawaban atas "kita kan juga memelihara server": betul, dan itu sudah dibayar di Cloud Private lewat langganan yang berulang setiap tahun selamanya. Cloud Enterprise tidak membayari kami server apa pun karena kami tidak menjalankan server apa pun di sana — yang dijual adalah perangkat lunak dan hak menjalankannya.

⚠️ Angka per organisasi itu hanya berlaku kalau slotnya terisi: Platform 50 yang cuma dipakai 30 tenant berharga Rp 80 juta/organisasi/tahun, bukan Rp 48 juta. Lihat S6.


4. Obscura Enterprise — on-prem, perpetual, satu organisasi

Band core (perpetual)

Band Core Kelipatan Implied per seat
Enterprise 250 Rp 500 juta 1,0× Rp 2 juta
Enterprise 1.000 Rp 850 juta 1,7× Rp 850 ribu
Enterprise 5.000 Rp 1,4 miliar 2,8× Rp 280 ribu
Tanpa Batas Rp 2 miliar 4,0×

Band 500 bisa ditambahkan kapan saja tanpa mengubah nama apa pun — itulah gunanya menamai band menurut jumlah seat.

Delapan modul — % dari harga core band pelanggan

Modul Kode % @ Enterprise 250 @ Enterprise 1.000
Correspondence (surat & disposisi) correspondence 30% 150 juta 255 juta
e-Sign (TTE tersertifikasi + e-Meterai) esign 30% 150 juta 255 juta
Records Compliance (ANRI/JRA) klasifikasi 25% 125 juta 212,5 juta
Protection (watermark & egress marking) watermarking 25% 125 juta 212,5 juta
Contract Intelligence contracts 25% 125 juta 212,5 juta
AI (Ask-the-Archive, semantic, enrichment) ai 20% 100 juta 170 juta
Secure Folders (Brankas) securefolder 20% 100 juta 170 juta
Office editing (DOCX/XLSX in place) office 15% 75 juta 127,5 juta

Jumlah kedelapan modul = 190% core. Core sengaja tetap bagian terbesar (dokumen, ACL/RBAC, versioning, workflow, retensi, pencarian, audit chain, permintaan dokumen, delegasi), supaya modul duduk di bawah core, bukan menyainginya.

Bundel — sama persis dengan tier Cloud, ini yang dipakai di penawaran

Bundel Modul List (% core) Harga jual @ 250 @ 1.000
Dasar core saja 1,00× 1,00× Rp 500 juta Rp 850 juta
Starter correspondence 1,30× 1,30× Rp 650 juta Rp 1,105 M
Professional + office 1,45× 1,45× Rp 725 juta Rp 1,233 M
Records + klasifikasi, securefolder 1,90× 1,75× (−8%) Rp 875 juta Rp 1,488 M
Business + esign, ai 2,40× 2,05× (−15%) Rp 1,025 M Rp 1,743 M
Enterprise semua 8 modul 2,90× 2,40× (−17%) Rp 1,2 miliar Rp 2,04 miliar

Modul satuan tetap bisa dibeli di luar bundel dengan harga tabel di atas — bundel adalah diskon, bukan pagar.

Definisi seat (Enterprise): akun manusia yang belum dihapus, termasuk yang disabled.

🔴 Definisi seat kedua edisi memang berbeda dan itu harus masuk kontrak apa adanya. Enterprise menghitung akun disabled (deleted_at IS NULL AND is_service = false); Cloud tidak (WHERE NOT disabled). Keduanya benar untuk konteksnya: di Enterprise, "disable, tambah orang, enable lagi" akan menjadikan lisensi tak terbatas; di Cloud, seat yang dibebaskan harus cocok dengan invoice. Jangan menyeragamkannya di brosur — seragamkan di kontrak masing-masing.

Storage tidak dijual di Enterprise. Tidak ada apa pun di lisensi yang membatasi byte, dan disknya milik pelanggan. Menjual GB di sini berarti menjual sesuatu yang tidak bisa ditagih.


5. Lisensi perpetual dan ASM — apa yang sebenarnya dibeli

Pertanyaannya: "jadi mereka bayar ASM supaya modul tambahan tetap hidup?"

Tidak. Modul hidup karena LISENSI, bukan karena ASM.

Yang menghidupkan modul adalah berkas lisensi bertanda tangan Ed25519 di disk mereka: di dalamnya ada daftar modul, jumlah seat, nama pelanggan, tanggal kedaluwarsa, dan (opsional) node-lock. Gerbangnya lisensi ∩ entitlement, dibaca dari berkas itu — tidak ada satu baris kode pun yang tahu apakah ASM dibayar. Pelanggan berhenti membayar ASM hari ini, besok semua modul masih menyala, persis seperti kemarin.

Kalau ASM benar-benar menjadi syarat hidupnya modul, yang kita jual bukan lisensi perpetual melainkan langganan yang menyamar — dan itu jenis kesalahan yang menghancurkan hubungan dengan pembeli pemerintah saat ketahuan di tahun keempat.

Kalau begitu, ASM itu membeli apa?

Empat hal, semuanya nyata dan semuanya berulang:

  1. Update versi dan patch keamanan. Tanpa ASM, sistem membeku di versi hari pembelian. Untuk perangkat lunak yang menyimpan arsip negara dan memegang kunci enkripsi, ini bukan kenyamanan — ini kepatuhan.
  2. Dukungan. Jalur ke manusia yang mengenal deployment mereka, dengan SLA tertulis.
  3. Penerbitan ulang berkas lisensi. Perpanjangan tanggal, perubahan node-lock saat pindah server, perubahan band seat, penambahan modul. Ini yang paling sering dipakai dan paling jarang diantisipasi pembeli.
  4. Bantuan migrasi versi mayor. Perubahan skema besar dijalankan bersama, bukan dilempar sebagai catatan rilis.

Analoginya satu kalimat: lisensi = membeli mobil, ASM = servis berkala + garansi + suku cadang. Berhenti servis, mobilnya tetap milik Anda dan tetap jalan — ia hanya tidak diperbaiki, tidak dapat suku cadang, dan tidak ada yang datang saat mogok.

Satu-satunya kaitan ASM dengan hidup-matinya modul — dan keputusan yang harus Anda ambil

🔴 expiry adalah field WAJIB di kode. VerifyLicense menolak payload dengan expiry kosong, jadi tidak ada cara menuliskan "tidak pernah kedaluwarsa". "Perpetual" pada praktiknya dicetak sebagai tanggal jauh di depan — prod dms1 memakai 2035-12-31, demo x056 memakai 2030-01-01.

Pada tanggal itu, lisensi berhenti memberi modul: sistem tidak mati, tapi jatuh ke core-only dan setiap rute berbayar menjawab 403. Jadi berapa lama kita mencetaknya adalah keputusan komersial, bukan teknis. Tiga pilihan:

Cetak Artinya Penilaian
1 tahun, diperpanjang lewat ASM modul benar-benar mati kalau ASM putus ❌ ini langganan yang dijual sebagai perpetual. Jangan.
10 tahun ASM putus ⇒ mereka masih aman bertahun-tahun, lalu core-only ⚠️ berfungsi, tapi menaruh bom waktu di deployment yang mungkin sudah tidak kita pantau
Sampai 2050 perpetual berarti perpetual rekomendasi

Rekomendasi: cetak sampai 2050 dan jual ASM atas nilainya sendiri. ASM tidak butuh sandera untuk laku — hampir setiap pelanggan on-prem mengganti server dalam lima tahun, dan node-lock mengikat lisensi ke identitas database (db:<hash>), sehingga pindah server tanpa ASM berarti membeli jasa penerbitan ulang satuan. Sediakan harga untuk itu: penerbitan ulang di luar ASM = Rp 25 juta, supaya tidak ada pelanggan yang benar-benar terjebak, dan supaya berlangganan ASM tetap pilihan yang lebih murah.

⚠️ Portal menolak memundurkan tanggal tanpa konfirmasi eksplisit, dan klien menolaknya saat pemasangan (kontrak §4). Perpanjangan hanya bisa maju — jangan pernah mencetak 2050 lalu berpikir bisa "menariknya kembali" menjadi 1 tahun.

Angka dan aturan ASM

  • 20%/tahun dari nilai lisensi, wajib tahun pertama. Di model perpetual ini satu-satunya pendapatan berulang; tanpa itu kita menjual sekali dan menanggung dukungan selamanya secara gratis.
  • Menambah modul atau naik band = pembelian, bukan ASM. Bayar selisih harga (Enterprise 250 Records → Business = Rp 150 juta), berkas diterbitkan ulang, lalu ASM tahun berikutnya dihitung dari nilai lisensi yang baru.
  • ASM putus lalu ingin aktif kembali = membayar tahun-tahun yang terlewat. Kalau tidak, memutus ASM menjadi strategi rasional bagi pelanggan.
  • Tidak termasuk ASM: kredit e-Meterai/e-Sign, implementasi baru, pengembangan khusus, pelatihan tambahan, dan penambahan modul/band.
  • Cloud tidak punya berkas lisensi per pelanggan. Satu deployment memegang satu lisensi; entitlement tiap tenant adalah centang di operator console. Pertanyaan "bagaimana tenant mengunggah lisensinya?" jawabannya: tidak ada, dan itu memang desainnya.

Kenapa lini perpetual tetap ada meski Cloud lebih menguntungkan kami

Perpetual masuk belanja modal: satu baris DIPA, satu kali pengadaan, menjadi aset yang disusutkan. Langganan masuk belanja barang/jasa dan harus dianggarkan ulang setiap tahun oleh pejabat yang mungkin sudah pindah. Untuk kementerian dan BUMN, itu bukan preferensi — itu sering satu-satunya bentuk yang bisa mereka beli. Anchor Rp 500 juta ada karena itu.


6. Obscura Cloud Enterprise — multi-tenant, dijalankan pelanggan

Pembelinya: pemprov/pemkab yang melayani puluhan dinas, holding BUMN dengan banyak anak usaha, atau mitra SI yang menjual ulang. Mereka menjalankan TENANCY_MODE=schema + operator console sendiri.

Harga per tenant slot, seat tidak dibatasi di dalam tenant, semua modul sudah termasuk.

Platform Tenant Harga perpetual ASM/tahun (20%) Per tenant/tahun @5 th, slot penuh
Platform 10 ≤ 10 Rp 2,5 miliar Rp 500 juta Rp 100 juta
Platform 25 ≤ 25 Rp 4 miliar Rp 800 juta Rp 64 juta
Platform 50 ≤ 50 Rp 6 miliar Rp 1,2 miliar Rp 48 juta
Tanpa Batas Rp 9 miliar Rp 1,8 miliar penawaran khusus
  • Semua 8 modul termasuk, sengaja. Menawar delapan modul untuk tiga puluh dinas adalah rapat yang tidak menghasilkan apa-apa. Pembeli yang benar-benar hanya mau core: −40%.
  • Opsi langganan untuk yang tidak punya belanja modal: 45%/tahun dari harga perpetual (Platform 10 = Rp 1,125 miliar/tahun). Sengaja di atas 40%: perpetual + ASM selama 5 tahun = 200% harga lisensi, jadi langganan harus melewatinya (5 × 45% = 225%) atau membeli menjadi keputusan yang bodoh secara finansial.
  • Naik platform (10 → 25) = bayar selisih, tanpa penalti. Slot kosong adalah kerugian murni, jadi jangan menjual tingkat yang lebih besar dari kenyataan.

Uji kewajaran terhadap Cloud kami: Platform 50 yang dipakai 30 dinas = Rp 80 juta/dinas/tahun selama 5 tahun, sementara dinas yang sama di Cloud kami (Professional, 40 seat) membayar Rp 78 juta/tahun — hampir sama sebelum infrastruktur mereka dihitung, dan kalah setelah ditambah ±Rp 30 juta/dinas/tahun untuk server, storage, backup dan tim operasi. Self-hosting baru menang kalau slotnya terisi penuh. Pemprov dengan 30 dinas sebaiknya dijual ke Cloud kami, kecuali mereka memang membeli kendali, bukan harga.

🔴 Tidak satu pun angka di tabel ini bisa dipaksakan oleh kode hari ini. Lisensi tidak punya field jumlah tenant, dan seat guard lisensi hanya dipasang saat !cfg.MultiTenant() — di edisi Cloud yang di-host sendiri, lisensi hanya membatasi modul. Lihat §8.


7. Konsumabel dan jasa

e-Meterai — bea diteruskan apa adanya, biaya platform terpisah

Komponen Harga Catatan
Bea meterai Rp 10.000/keping ditetapkan UU 10/2020, diteruskan tanpa markup
Biaya platform Obscura Rp 3.000/keping pembubuhan, ledger, audit chain, penyimpanan bukti
Paket 100 keping Rp 1,3 juta prabayar, control.credit_pools / tenant_credits

Jangan pernah menjual "meterai Rp 15.000". Bea adalah angka yang ditetapkan negara dan distributor resmi menjualnya di Rp 10.000; margin kami adalah jasa, dan harus tertulis sebagai jasa.

e-Sign

Item Harga
Tanda tangan tersertifikasi PSrE (Peruri/TERA), paket 100 Rp 600 ribu (Rp 6.000/tanda tangan)
Tanda tangan internal PAdES (CA sendiri) gratis, tak terbatas
Penanda tangan eksternal (undangan email/WhatsApp) gratis, tidak menghitung seat

Pembanding: Privy Enterprise Rp 175 ribu/pengguna/bulan (±Rp 2,1 juta/tahun) untuk tanda tangan tak terbatas per orang — untuk 100 orang itu Rp 210 juta/tahun, hanya untuk tanda tangan.

AI

Termasuk dalam modul ai, wajar pakai. Tidak ada tagihan per pertanyaan. Alasannya bukan kemurahan hati: tidak ada meter AI di sistem (credit_events hanya mengenal emeterai | esign | stamp). Menjual yang tidak terukur adalah sengketa yang menunggu terjadi. Pelanggan besar boleh memakai kunci API sendiri — tanpa markup, tanpa biaya.

Jasa

Item Harga
Implementasi Cloud (org chart, JRA, template, 2 sesi pelatihan) Rp 25 juta
Implementasi Enterprise / Cloud Enterprise (+ instalasi, SSO, hardening) Rp 75 juta
Migrasi data Rp 15 juta per 10.000 dokumen
Pelatihan tambahan Rp 7,5 juta/hari (+ perjalanan)
Penerbitan ulang lisensi di luar ASM Rp 25 juta
Pengembangan khusus Rp 2,5 juta/man-day

8. Apa yang benar-benar dipaksakan oleh kode

Ini pembatas dari seluruh daftar harga di atas. Menjual baris bertanda ❌ berarti menjual atas dasar kepercayaan, bukan atas dasar sistem.

Yang dijual Dipaksakan? Di mana
Modul, kedelapannya, di kedua edisi httpapi.moduleEnabled = lisensi ∩ tenant
Seat — Enterprise licenceSeatGuard, 3 jalur provisioning (SSO sengaja dikecualikan)
Seat — tenant Cloud quotaSvc.GuardSeat
Storage — tenant Cloud MinIOStore.Put (gagal-terbuka, cache 60 dtk, boleh lewat 1 berkas)
Kredit e-Meterai / e-Sign migrasi 00018, saldo pool + tenant
Masa berlaku lisensi LicensePayload.Expiry (wajib) + portal lisensi
Storage — Enterprise tidak ada apa pun. Jangan dijual.
Jumlah tenant — Cloud Enterprise tidak ada field di LicensePayload
Total seat — Cloud Enterprise seat guard hanya dipasang saat !cfg.MultiTenant()
Pemakaian AI tidak ada meter. Jangan dijual per pemakaian.

Tiga hal kecil yang harus dibangun sebelum tanda tangan Cloud Enterprise pertama (perkiraan 1–2 hari kerja, bukan proyek):

  1. Field tenants di LicensePayload + penjagaan di jalur Provision. 🔴 Ini menyentuh byte kanonik yang ditandatangani — ikuti persis pemisahan yang dipakai ModuleAliases (verifikasi dulu, penafsiran belakangan), atau setiap lisensi di lapangan gagal sebagai "payload is not canonical", persis seperti insiden konsolidasi modul.
  2. Pasang licenceSeatGuard juga di mode multi-tenant, dihitung lintas seluruh schema, sebagai plafon deployment di atas kuota per tenant.
  3. Portal lisensi harus bisa mencetak angka tenant itu.

Satu hal yang harus dilakukan minggu ini: kelima plan di operator console bertanda "no price". Isi plan_prices untuk kelimanya (base = biaya platform, per-seat = tarif tier, interval annual) — sampai itu dilakukan, tidak ada satu pun tenant yang bisa ditagih otomatis.


9. Simulasi harga

Semua simulasi memakai harga list, belum PPN. "5 tahun" = total kas keluar pelanggan selama lima tahun, termasuk implementasi, dengan ASM ditagih sejak tahun pertama.

S1 — Dinas kecil: 25 pengguna, e-office saja (Starter)

Tahun 1 Tahun 2–5/tahun 5 tahun
Cloud Starter dasar 34,5 (25 seat, tanpa blok) + 25 implementasi = Rp 59,5 juta Rp 34,5 juta Rp 197,5 juta

Enterprise tidak ditawarkan pada ukuran ini (band terkecil 250 seat = Rp 500 juta). Aturan 1 bekerja: pertanyaan "ada yang lebih murah?" dijawab dengan produk, bukan dengan diskon. Tahun 1 di bawah Rp 200 juta ⇒ bisa lewat Pejabat Pengadaan / e-purchasing.

S2 — Dinas menengah: 40 pengguna, arsip ANRI/JRA + brankas (Records)

Tahun 1 Tahun 2–5/tahun 5 tahun
Cloud Records dasar 67,5 (25 seat) + 3 blok seat-rec-b1 (→40 seat) 26,1 + 25 = Rp 118,6 juta Rp 93,6 juta Rp 493 juta
Enterprise 250 Records (pembanding) 875 + ASM 175 + 75 = Rp 1,125 miliar Rp 175 juta + server Rp 1,825 miliar + server

Selisihnya 3,7× — pada ukuran ini Cloud satu-satunya jawaban yang jujur, dan menawarkan perpetual di sini hanya membuat kita kalah tanpa alasan.

S3 — BUMN: 150 pengguna, semua modul (Enterprise), 3 TB arsip

Komponen Perhitungan Setahun
Harga dasar enterprise sudah termasuk 50 seat + 2 TB Rp 168 juta
seat-ent-b1 × 10 50 seat → total 100 Rp 120 juta
seat-ent-b2 × 10 50 seat → total 150 Rp 90 juta
Storage 1 TB tambahan (2 TB termasuk) 1 × Rp 24 juta Rp 24 juta
Total langganan Rp 402 juta/tahun
Implementasi (sekali) Rp 25 juta
e-Meterai 3.000 keping/tahun 3.000 × Rp 13.000 Rp 39 juta

Tahun 1 = Rp 466 juta. 5 tahun = Rp 2,23 miliar.

S4 — Kementerian: 800 pengguna, semua modul, on-prem

Tahun 1 Tahun 2–5/tahun 5 tahun
Enterprise 1.000, bundel Enterprise 2.040 + ASM 408 + 75 = Rp 2,523 miliar Rp 408 juta Rp 4,155 miliar + server mereka
Cloud Enterprise (pembanding) dasar 168 + b1×10 (120) + b2×80 (720) + b3×60 (378) = Rp 1,386 miliar Rp 1,386 miliar Rp 6,93 miliar

Di 800 seat, perpetual on-prem menang telak dan itu memang jawaban yang benar — jangan dipaksa ke Cloud. Inilah fungsi jenjang seat: Cloud masuk akal sampai ±500 seat, di atas itu ia menyerahkan pelanggan ke lini perpetual dengan sendirinya, bukan menahan mereka di harga yang buruk.

S5 — Titik impas: satu organisasi 250 pengguna, semua modul

Lini Tahun 1 5 tahun Siapa yang beli server
Cloud Enterprise (kami) dasar 168 + b1×10 (120) + b2×30 (270) + 25 = Rp 583 juta Rp 2,82 miliar kami
Cloud Private (khusus) 837 + 25 = Rp 862 juta Rp 4,21 miliar kami, khusus dia
Enterprise 250, bundel Enterprise 1.200 + ASM 240 + 75 = Rp 1,515 miliar 1.200 + 5×240 + 75 = 2,475 M + ±625 juta server/ops = Rp 3,10 miliar mereka

Titik impas ±6,5 tahun dengan server dihitung; 3,9 tahun kalau server mereka dianggap gratis. Siapkan jawabannya: sysadmin, backup yang diuji, DRC, dan risiko upgrade tidak pernah gratis — hanya tidak tercatat di baris anggaran mana pun.

S6 — Pemprov: 30 dinas, ±40 pengguna per dinas

30 dinas tidak muat di Platform 25, jadi tingkat yang benar adalah Platform 50 dengan 20 slot tersisa untuk pertumbuhan.

Opsi Tahun 1 5 tahun Per dinas per tahun
Platform 50 perpetual (mereka jalankan) 6.000 + ASM 1.200 + 75 = Rp 7,275 miliar Rp 12,08 miliar Rp 80,5 juta + infra mereka ±Rp 30 juta
Langganan platform 45%/tahun 2.700 + 75 = Rp 2,775 miliar Rp 13,58 miliar Rp 90,5 juta + infra mereka
30 tenant di Cloud kami (Professional) 30 × 78 + 30 × 25 = Rp 3,09 miliar Rp 12,45 miliar Rp 78 juta, tanpa infra apa pun

Ketiganya bertemu di Rp 12–13,6 miliar untuk lima tahun, dan opsi pertama justru kalah setelah infrastruktur mereka dihitung. Harga bukan pembeda di sini; yang membedakan adalah siapa yang memegang kendali dan siapa yang bangun jam 2 pagi saat disk penuh.

S7 — Mitra SI reseller

Membeli Platform 25 dengan diskon mitra 25% = Rp 3 miliar, ASM 20% dari harga net = Rp 600 juta/tahun, menjual ulang ke 20 pelanggan @Rp 100 juta/tahun = Rp 2 miliar/tahun. Margin bersih Rp 1,4 miliar/tahun ⇒ balik modal ±2,1 tahun, lalu Rp 1,4 miliar/tahun selama sisa umur platform. Cukup lebar untuk membuat mitra bekerja, cukup sempit untuk mencegah mitra menjual di bawah harga kami.


10. Keputusan yang masih menunggu Anda

Sudah diputuskan 2026-08-24: tarif seat Starter Rp 75.000, Professional Rp 125.000, Enterprise Rp 200.000 — dan konsekuensinya, bundel Enterprise on-prem Rp 1,2 miliar di band 250. Kedelapan modul tetap ada di tier Enterprise; contracts tidak diturunkan ke Business.

Yang masih terbuka:

  1. Harga dua modul baru: Contract Intelligence 25% dan Secure Folders 20% dari core. Contract Intelligence sengaja setara Protection karena isinya produk tersendiri (ekstraksi, kewajiban, pengingat perpanjangan, migrasi 00198–00201).
  2. Umur cetak lisensi perpetual: sampai 2050 (§5). Keputusan komersial yang tidak bisa ditarik kembali setelah dicetak — dan satu-satunya di dokumen ini yang bisa merusak kepercayaan pelanggan kalau salah.
  3. Cloud Enterprise Platform 10 = Rp 2,5 miliar. Ini yang menentukan pemprov besar lari ke self-hosted atau tinggal di Cloud kami. Naikkan 30% kalau targetnya menahan mereka di Cloud.
  4. Isi harga kelima plan di console minggu ini. Semuanya masih "no price"; sampai itu diisi, tidak ada tenant yang bisa ditagih otomatis. Angkanya sudah siap tempel di §11.

11. Lampiran — angka siap tempel ke control.plan_prices

Seluruh isi §11 sudah dimasukkan ke katalog PROD (dms1) pada 2026-08-24 lewat control API: 5 plan dasar (seat + storage), 9 blok seat, 2 blok storage, dan 32 baris harga (annual + monthly). Diverifikasi dengan membaca ulang — tidak ada plan yang tersisa tanpa harga. Nol tenant memegang plan mana pun dan tidak ada subscription, jadi tidak ada pelanggan yang terdampak.

⚠️ Dua koreksi yang ditemukan saat mengisi: storage professional dan records tertukar (Professional memegang 1 TB, Records 250 GB — tier yang lebih murah mendapat 4× lipat); sudah ditukar. Dan harga monthly yang sudah ada memakai per_seat_amount > 0 dari revisi 3; semuanya kini 0, sesuai model blok.

⚠️ VM2 / getobscura.id (dms2) masih memakai katalog lama: 3 plan dasar (starter/professional/enterprise) dengan per_seat_amount > 0 dan add-on bernama addon-users-25, addon-storage-250gb, dan seterusnya. Satu tenant sudah berlangganan enterprise di sana, jadi menyamakannya dengan prod mengubah tagihan pelanggan hidup — itu keputusan tersendiri, bukan entri data.

Kelima tier, interval annual, currency IDR, satuan minor unit = rupiah penuh (eksponen IDR = 0, jadi angka di bawah adalah angka yang dibaca pelanggan).

🔴 per_seat_amount pada interval annual adalah tarif SETAHUN, bukan sebulan. Mengetik 75.000 di baris annual berarti menjual satu seat seharga Rp 75.000 setahun — 1/12 dari yang dimaksud. Kalikan 12 dulu.

🔴 per_seat_amount = 0 di SEMUA baris. Seat dijual sebagai blok add-on. Mengisi kolom ini berarti tenant ditagih dua kali: sekali lewat blok yang mereka beli, sekali lagi lewat hitungan akun aktif.

plan_code base_amount annual base_amount monthly per_seat_amount
starter 34.500.000 3.450.000 0
professional 55.500.000 5.550.000 0
records 67.500.000 6.750.000 0
business 87.000.000 8.700.000 0
enterprise 168.000.000 16.800.000 0

Baris monthly adalah baris kedua untuk plan yang sama dengan interval='monthly'. Indeks unik hanya melarang dua baris hidup pada (plan, currency, interval) yang sama, jadi annual dan monthly hidup berdampingan.

Blok seat — plan kind='addon', user_quota = 5

Kode: seat-<tier>-b<band>. Semuanya menumpuk lewat quantity, tidak membawa modul, dan tidak punya storage_quota_bytes.

plan_code Band (total seat tenant) user_quota base_amount annual monthly
seat-sta-b1 ≤100 5 4.500.000 450.000
seat-pro-b1 / b2 / b3 / b4 ≤100 / 101–500 / 501–2.000 / 2.001+ 5 7.500.000 / 5.700.000 / 3.900.000 / 2.700.000 ×0,1
seat-rec-b1 / b2 / b3 / b4 idem 5 8.700.000 / 6.600.000 / 4.500.000 / 3.000.000 ×0,1
seat-bus-b1 / b2 / b3 / b4 idem 5 10.200.000 / 7.800.000 / 5.400.000 / 3.600.000 ×0,1
seat-ent-b1 / b2 / b3 / b4 idem 5 12.000.000 / 9.000.000 / 6.300.000 / 4.200.000 ×0,1

Buat hanya band yang benar-benar terjual; sisanya menyusul saat ada penawaran yang membutuhkannya. Rumusnya tetap: harga blok = 5 × tarif band × 12.

⚠️ Band tidak dipaksakan oleh kode — tidak ada yang mencegah operator melekatkan sepuluh seat-ent-b4 ke tenant 60 seat dan menjual 250 seat dengan harga band termurah. Band adalah aturan penawaran, bukan aturan sistem; yang menegakkannya adalah proses penawaran dan jejak audit, bukan database.

Storage bawaan tiap plan — plans.storage_quota_bytes

Ini kolom di control.plans (bukan di plan_prices), diisi sekali saat plan disunting. NULL = plan tidak memberi kapasitas sama sekali, dan itulah kondisi kelima plan hari ini — jadi selama kolom ini kosong, tidak ada tenant yang punya plafon storage dari planya.

plan_code Storage bawaan storage_quota_bytes
starter 50 GiB 53.687.091.200
professional 250 GiB 268.435.456.000
records 1 TiB 1.099.511.627.776
business 1 TiB 1.099.511.627.776
enterprise 2 TiB 2.199.023.255.552

Konsol menerima angka dalam GiB dan mengubahnya ke byte di tepi; angka byte di atas ada supaya bisa dicocokkan kalau nanti diperiksa lewat SQL. Kapasitas dijumlahkan: plan dasar + setiap add-on × quantity.

🔴 Biarkan plans.user_quota tetap NULL. Menaruh 25 di plan starter berarti setiap tenant Starter tertutup di 25 akun, termasuk yang membeli 60 seat — dan plafon itu menolak akun baru dengan 403, tepat saat admin mereka sedang onboarding staf. Jumlah seat berbeda-beda per pelanggan, jadi tempatnya adalah override kuota per tenant (yang selalu menang atas katalog), disetel sama dengan seat yang dibeli.

⚠️ Menaikkan plafon menjatuhkan cache 60 detik di kedua sisi, jadi operator bisa membuka blokir pelanggan di tengah telepon tanpa menunggu.

Add-on kapasitas dibuat sebagai plan kind='addon' dengan storage_quota_bytes terisi, lalu diberi harga di tabel yang sama:

plan_code storage_quota_bytes base_amount annual base_amount monthly Catatan
storage-100gb 107.374.182.400 3.000.000 300.000 bertumpuk; quantity naik tiap kali dilekatkan
storage-1tb 1.099.511.627.776 24.000.000 2.400.000 bertumpuk

Add-on kapasitas tidak punya per_seat_amount (0) — yang dijual adalah byte, bukan orang. ⚠️ Harga add-on harus sama mata uang dan sama interval dengan langganan tenant yang melekatinya; add-on tanpa harga tetap melekat dan memberi kapasitas, hanya tidak pernah muncul di invoice.

Jenjang seat (101+, 501+, 2001+) belum perlu dibuat sekarang. Skema hanya menyimpan satu per_seat_amount per (plan, currency, interval), jadi jenjang lahir sebagai kode plan baru — enterprise-500 dan seterusnya — dan hanya dibuat saat ada penawaran yang membutuhkannya. Rumusnya ada di tabel jenjang §2.

⚠️ Kalau harga tersimpan tetapi tetap tampil "no price", bukan savePlan penyebabnya — harga lewat savePrice, handler yang berbeda. (Kedua proxy kini meneruskan badan permintaan apa adanya, jadi kelas kesalahan "field baru hilang diam-diam" sudah tertutup untuk keduanya.) Periksa dulu yang sederhana: baris plan_prices memang belum diisi, atau diisi pada interval yang berbeda dari langganan tenant.


12. Fitur yang belum ada di kode

Diperiksa langsung di kode 2026-08-24. Hanya pekerjaan pemrograman — mengisi katalog harga, storage bawaan dan dua SKU add-on adalah entri data (§11), tidak dihitung di sini.

Tingkat 1 — daftar harga ini tidak bisa ditagih dengan benar tanpa ini

# Fitur yang hilang Akibat Beban
1 ~~Tarif seat berjenjang~~ — DISELESAIKAN tanpa kode 2026-08-24. IssueInvoice memang hanya bisa satu tarif datar per langganan, tetapi seat kini dijual sebagai blok add-on (§2): tiap band menjadi baris invoice tersendiri dengan quantity, dan totalnya identik dengan hitungan bertingkat. Rantainya sudah lengkap di kode: Stackable()AttachAddonResolveEntitlement (menjumlahkan user_quota × qty) → EffectiveSeatsGuardSeat. Sisa: band tidak dipaksakan sistem (aturan penawaran), dan pemilihan blok manual. 0 hari
2 ~~Prorata~~ — SELESAI. Blok yang dilekatkan di tengah periode ditagih untuk sisa periode lewat invoice di luar siklus (subscription_id NULL — indeks unik 00013 menolak invoice kedua atas periode yang sama). 🔴 tenant_plans.attached_at TIDAK BISA dipakai seperti dugaan dokumen ini: penumpukan adalah quantity + 1 pada satu baris dan tidak pernah menyentuh kolom itu, jadi untuk tenant dengan sepuluh blok ia hanya mencatat kapan yang PERTAMA dibeli. Karena itu ada buku besar perubahan (migrasi 00029). 0 hari
3 Harga khusus per pelanggan — SATU-SATUNYA YANG TERSISA. Satu harga hidup per (plan, currency, interval), dan berlangganan ke harga terarsip ditolak (billing.price.archived). Diskon mitra 25%, diskon tender, dan prabayar 3 tahun semuanya memaksa membuat kode plan baru — yang ikut menyalin modul, mengotori katalog dan memenuhi laporan drift. 2 hari (bukan 1 — lihat catatan)

🔴 Kenapa 2 hari, bukan 1. IssueInvoice memberi harga add-on dari ListPrices(ctx, false) yang di-key per plan_code, menang-yang-terakhir. Begitu ada harga hidup KEDUA untuk satu plan, baris add-on mengambil baris sembarang — dan harga khusus tenant A bisa diam-diam menagih add-on tenant B. Jadi resolusi harga add-on harus ikut dibuat per-langganan, bukan hanya harga dasarnya. Diskon MITRA sudah ada dan bukan ini: itu persentase pada mitra (§12 #12), yaitu syarat kanal, bukan harga satu pelanggan.

Tingkat 2 — program penjualan yang sudah tertulis tetapi tidak punya jalur di kode

# Fitur yang hilang Akibat Beban
4 ~~Masa percobaan (trial)~~ — SELESAI. trial_end pada langganan (migrasi 00024); periode yang MULAI sebelum tanggal itu ditagih nol, dan periode berbayar pertama mulai tepat saat trial berhenti. Ada flag trial di tenant, tetapi billing tidak mengenalnya. Pilot 3 bulan gratis hanya bisa dijalankan dengan menunda pembuatan langganan — dan selama ditunda, tidak ada yang menjadwalkan invoice pertama. 0,5 hari
5 ~~Termin multi-tahun~~ — SELESAI. triennial (migrasi 00025); interval kini jumlah BULAN di satu tabel, jadi termin 5 tahun tinggal satu baris. interval hanya monthly \| annual (CHECK di database). Prabayar 3 tahun −15% tidak bisa direpresentasikan; harus dijual sebagai tiga periode tahunan, yang bukan prabayar. 0,5 hari
6 ~~Peringatan mendekati plafon~~ — SELESAI. Ambang 80% (QUOTA_WARN_PERCENT), email + kotak masuk ke admin tenant sendiri, plus daftar berisiko di konsol operator. quota.go hanya punya penjaga yang menolak; tidak ada ambang 80%, tidak ada email, tidak ada spanduk di aplikasi. Pelanggan pertama kali tahu plafonnya saat unggahan ditolak 403 — dan add-on kapasitas baru laku setelah orang terlanjur terhalang. Ini kehilangan pendapatan, bukan hanya UX. 1 hari
7 ~~Seat dijual vs dipaksakan~~ — SELESAI, dan lebih kecil dari dugaan. EffectiveSeats memang sudah menurunkan seat dari blok; yang hilang hanyalah PERINGATAN saat override manual lebih rendah dari yang dibeli. Itu kini ada di tab Quotas. Tidak ada yang menurunkan tenants.user_quota dari plan atau langganan; operator mengetiknya di layar lain. Dua angka tentang hal yang sama, diketik manusia, di dua tempat. Yang satu menagih, yang satu menolak akun. 0,5 hari
8 🔴 ~~Top-up kredit mandiri~~ — SUDAH ADA SEJAK AWAL; DOKUMEN INI SALAH. GET /api/v1/me/credits dan POST /me/credits/buy hidup, control.credit_packs adalah katalog SKU sungguhan, dan UI tenant-nya ada di BillingTab.tsx. Tidak ada rute /me/credits; kredit e-Meterai/e-Sign habis ⇒ pelanggan menelepon operator. Tidak ada pula katalog SKU paket kredit — harga paket diketik ulang tiap penjualan. Pembubuhan meterai berhenti sampai ada manusia kami yang mengangkat telepon. 1–2 hari

Tingkat 3 — hanya sebelum lini/kanal itu benar-benar dijual

# Fitur yang hilang Kapan wajib Beban
9 ~~Field tenants di LicensePayload~~ — SELESAI. omitempty (WAJIB), plafon di jalur Provision. + penjagaan di jalur Provision. 🔴 Menyentuh byte kanonik yang ditandatangani — ikuti pemisahan ModuleAliases. sebelum tanda tangan Cloud Enterprise pertama 1 hari
10 ~~Seat guard multi-tenant~~ — SELESAI. Berjalan BERDAMPINGAN dengan kuota per tenant, dihitung lintas schema. (sekarang hanya dipasang saat !cfg.MultiTenant()). idem 0,5 hari
11 ~~Portal mencetak angka tenant~~ — SELESAI. Kolom registry 00009 + dibawa saat perpanjangan. (menyusul #9). idem 0,5 hari
12 ~~Model mitra/reseller~~ — SELESAI. Entitas mitra, penanda "dijual melalui", diskon kanal (persen, basis poin) yang dipotong SEBELUM pajak. Paket kredit sengaja TIDAK didiskon: bea diteruskan apa adanya.: tidak ada entitas mitra, tidak ada harga mitra, tidak ada penanda "dijual melalui" pada tenant, tidak ada komisi. sebelum kanal SI dibuka 1–2 hari
13 ~~Meter AI~~ — SELESAI, dan meternya sudah ada sejak 00077. Yang hilang cuma sambungan ke buku besar; kini ditagih per TOKEN, idempoten per hari.: credit_events hanya mengenal emeterai \| esign \| stamp. hanya kalau AI mau ditagih per pemakaian 2–3 hari
14 ~~Kelebihan storage otomatis~~ — SELESAI. Opt-in per tenant, BERPLAFON, dan menolak membeli saat override operator sedang berlaku (blok yang dibeli tidak akan menaikkan plafon).: melewati plafon menolak unggahan, tidak ada yang otomatis melekatkan atau menagih blok tambahan. opsional — sengaja begini, tetapi berarti pendapatan kapasitas bergantung pada operator yang memperhatikan 1 hari

Dua bug kecil yang akan menghantam orang pertama yang mengisi katalog

# Bug Beban
15 ~~Formulir plan mengirim 0~~ — SELESAI. untuk user_quota, database menolaknya (CHECK (user_quota IS NULL OR user_quota > 0)) ⇒ operator melihat error mentah. Yang benar adalah mengosongkan** field itu. Klien harus menolak 0 dengan kalimat itu, atau memetakan 0 → NULL. 1 jam
16 ~~Proxy savePlan~~ — SELESAI (badan diteruskan apa adanya). Catatan: saat diperiksa, proxy itu belum benar-benar menjatuhkan field apa pun — bahayanya struktural. Dan §11 menyalahkan savePlan untuk "no price" yang tidak mungkin disebabkannya: harga lewat savePrice, handler yang berbeda. di operator console men-decode ke struct sendiri lalu meng-encode ulang** ⇒ field control-API baru hilang diam-diam: tersimpan 200, tidak berlaku. 1 jam

Sudah ada — jangan dibangun ulang

Renewal otomatis dan idempoten per periode · pengingat jatuh tempo (dunning) · invoice tenant-facing + pembayaran online (/me/billing) · PPN (tax_rate_bp + label, dibekukan saat terbit) · add-on bertumpuk dengan quantity · pembuatan plan add-on di console (Plans → New plan → Kind) · kredit e-Meterai/e-Sign (pool + tenant + ledger append-only) · penegakan seat di Enterprise dan di tenant Cloud · penegakan storage di tenant Cloud · pembayaran kartu/VA/QRIS lewat Midtrans.

⚠️ docs/BILLING.md masih menulis bahwa renewal cron, dunning dan invoice tenant-facing "belum dibangun" — itu sudah usang. Ketiganya ada di kode. Perbaiki dokumen itu sebelum ada yang merencanakan pekerjaan yang sudah selesai.

Status akhir (diperiksa di kode 2026-08-25)

Lima belas dari enam belas selesai. #1 tidak perlu kode, #8 ternyata sudah ada. Yang tersisa
hanya #3, harga khusus per pelanggan.

Migrasi control yang ditambahkan: 00024 trial · 00025 triennial · 00026 storage overage ·
00027 mitra · 00028 kredit AI · 00029 buku besar prorata. Portal lisensi: 00009.

🔴 Urutan rilis lisensi. VerifyLicense memakai DisallowUnknownFields, jadi lisensi yang
membawa tenants DITOLAK oleh biner yang lebih lama. Pasang biner dulu, cetak lisensi
sesudahnya
— terbalik akan mematikan pelanggan Cloud Enterprise yang baru saja membayar.

Urutan yang saya sarankan (sudah dijalankan, kecuali #3)

  1. #15 + #16 (2 jam) — dua bug yang menghantam Anda sendiri saat mengisi katalog minggu ini.
  2. #2 prorata (1–2 hari) — satu-satunya jurang yang mengambil uang dari kas kita setiap kali pelanggan tumbuh.
  3. #6 peringatan plafon (1 hari) — murah, dan langsung menjual blok kapasitas.
  4. #3 harga khusus (1 hari) — sebelum deal bermitra atau bertender yang pertama, bukan sesudah.
  5. #9–#11 (2 hari) — hanya sebelum tanda tangan Cloud Enterprise pertama.