Panduan · 3 September 2026
Menagih langganan bulanan tanpa autodebet: alur per periode yang bisa dijalankan
Kasera Pay tidak menyimpan instruksi debet berulang. Tidak ada kartu tersimpan, tidak ada objek langganan di API, dan tidak ada penarikan yang berjalan sendiri saat jatuh tempo tiba. Setiap periode dimulai dari pelanggan yang membuka tautan lalu membayar sendiri. Panduan ini tentang cara menagih langganan bulanan di dalam batas itu tanpa kehilangan yang sebenarnya dibutuhkan penagih: tahu siapa yang sudah membayar untuk periode mana, dan kapan harus menutup akses.
Yang menggantikan autodebet bukan satu fitur, melainkan tiga hal di sisi penagih: jadwal penerbitan tautan, tangga pengingat, dan catatan periode di basis data sendiri. Ketiganya bisa diotomatiskan penuh. Yang tidak bisa diotomatiskan hanyalah tindakan membayarnya.
Putuskan panjang periodenya sebelum apa pun dibuat
Satu aturan menentukan bentuk seluruh penagihan, dan lebih murah diketahui sekarang daripada setelah pelanggan pertama membayar. Kebijakan penggunaan terlarang menempatkan pre-order dan langganan yang penyerahannya lebih dari 30 hari ke depan pada daftar yang membutuhkan persetujuan tertulis lebih dulu, bersama tiket, perjalanan, dan donasi. Daftar lengkapnya ada di kebijakan penggunaan terlarang.
Konsekuensinya langsung. Paket bulanan tidak menyentuh aturan itu sama sekali, karena penyerahannya selalu berakhir di dalam 30 hari sejak pembayaran. Paket tahunan yang dibayar di muka menyentuhnya secara telak, dan harus dikabarkan lalu menunggu persetujuan sebelum tautan pertamanya dibuat. Paket triwulanan pun sudah melewati 30 hari, jadi perlakuannya sama dengan tahunan.
Batas kedua adalah nominal: satu pembayaran dibatasi Rp 10.000 sampai Rp 10.000.000, sehingga paket tahunan di atas plafon itu harus dipecah, sementara paket bulanan hampir tidak pernah menyentuhnya.
Kenapa tautan tidak bisa diterbitkan jauh di muka
Godaan pertama saat menyusun penagihan berulang adalah membuat dua belas tautan sekaligus di awal tahun lalu menjadwalkan pengirimannya. Cara itu tidak tersedia, dan alasannya ada pada masa berlaku, bukan pada aturan langganan. Nilai expires_in_minutes divalidasi pada rentang 1 sampai 10080 menit, yaitu tujuh hari, dan di luar itu ditolak sebagai validation_failed. Di bawahnya masih ada plafon akun yang lebih ketat, bawaannya 24 jam, dengan kode expiry_too_long. Keduanya terdokumentasi di daftar kode error.
Artinya tautan periode berikutnya diterbitkan pada awal periode berikutnya, dan itu bukan keterbatasan yang perlu disiasati: tautan yang hidup berbulan-bulan menumpuk sebagai kewajiban yang bisa dibayar kapan saja, termasuk oleh pelanggan yang sudah berhenti berlangganan tiga bulan lalu. Cara memilih angkanya dibahas di artikel masa berlaku tagihan.
Alur satu periode, lima langkah
Ditulis untuk penagih yang punya sistem sendiri. Tanpa sistem sendiri, langkah satu sampai tiga dikerjakan dari dashboard dan sisanya tetap berlaku apa adanya.
- Tugas terjadwal berjalan tiap hari, bukan sebulan sekali. Pelanggan berlangganan pada tanggal berbeda-beda, jadi tugas harian mengambil siapa saja yang jatuh tempo hari itu. Tugas bulanan memaksa semua orang ditagih pada tanggal yang sama dan menumpuk seluruh beban pengingat pada satu hari.
- Terbitkan pembayaran untuk periode itu. Lewat endpoint create, dengan
descriptionyang menyebut paket dan periodenya, misalnya “Paket Pro, September 2026”. Teks itu tampil di halaman pembayaran dan terbawa ke ekspor CSV, jadi menulis periode di situ adalah selisih antara rekap yang terbaca dan rekap yang harus ditebak. - Kirim tautannya dengan tiga angka di dalam pesan: nominal, periode yang ditagih, dan jam berakhirnya masa berlaku tautan. Tanpa yang ketiga, tautan yang mati dalam 24 jam terbaca sebagai sistem yang rusak.
- Tandai lunas dari webhook, bukan dari halaman balik. Perpanjangan dicatat saat webhook
payment.paidbertanda tanganKasera-Signature-V1diterima dan diverifikasi, karena pelanggan yang menutup tab setelah membayar tetap harus mendapat perpanjangannya. Kenapa tanda tangan yang sah belum membuktikan nominalnya benar dibahas di artikel keamanan webhook. - Perpanjang dari tanggal jatuh tempo lama, bukan dari tanggal pembayaran. Pelanggan yang membayar tagihan September pada tanggal 5 September tetap berhak sampai akhir September. Menghitung dari tanggal pembayaran diam-diam memberi hadiah kepada yang telat membayar dan menggeser tanggal tagih setiap bulan.
Satu kunci idempotensi per pelanggan per periode
Tugas terjadwal adalah tempat tagihan ganda lahir. Tugas yang gagal di tengah lalu diulang otomatis, atau dijalankan ulang manual karena hasilnya diragukan, akan menerbitkan pembayaran kedua untuk periode yang sama. Yang mencegahnya hanya header Idempotency-Key pada permintaan create, diisi nilai yang berasal dari identitas pelanggan dan periodenya, misalnya sub-8241-2026-09.
Nilai itu harus deterministik. Kunci acak pada setiap percobaan tidak melindungi apa pun, karena percobaan kedua membawa kunci baru dan diperlakukan sebagai tagihan baru. Dan external_id maupun merchant_ref bukan penggantinya: keduanya label yang disimpan, dikembalikan, dan bisa disaring, tetapi tidak pernah menjadi pernyataan bahwa dua permintaan adalah satu pembayaran. Uraian lengkapnya ada di artikel Idempotency-Key.
Tangga pengingat dijalankan dari expires_at, bukan dari webhook
Tidak ada webhook yang dikirim saat sebuah pembayaran kedaluwarsa; satu-satunya jenis event adalah payment.paid. Konsekuensinya menentukan bentuk penagihan: keadaan “belum membayar” tidak akan pernah datang sebagai pemberitahuan, jadi harus dicari sendiri dengan membandingkan waktu sekarang terhadap expires_at pembayaran yang masih pending.
Tangga yang masuk akal untuk langganan bulanan, dihitung dari tanggal jatuh tempo periode, bukan dari kapan tautan dibuat:
| Waktu | Tindakan | Nada |
|---|---|---|
| H-3 sebelum jatuh tempo | Pemberitahuan nominal dan tanggal, belum ada tautan | Informasi |
| Hari jatuh tempo | Terbitkan pembayaran, kirim tautannya | Tagihan |
| H+2 | Terbitkan tautan baru, kirim ulang | Pengingat |
| H+7 | Terbitkan tautan baru, sebutkan tanggal penutupan akses | Peringatan |
| H+14 | Tutup akses, simpan datanya, tautan tetap tersedia bila diminta | Penutupan |
Setiap pengingat menerbitkan tautan baru alih-alih mengirim ulang yang lama, karena yang lama hampir pasti sudah kedaluwarsa pada plafon 24 jam. Itu tidak menambah biaya: biaya hanya muncul pada pembayaran yang berhasil, jadi tautan yang tidak dibayar berbiaya nol.
Bulanan atau tahunan, dihitung dengan angka
Argumen finansial untuk paket tahunan biasanya diperkirakan terlalu besar. Pada tarif yang berlaku saat panduan ini ditulis, QRIS ditagih MDR 0,7 persen yang diteruskan apa adanya ditambah Rp 250 per pembayaran berhasil, tanpa biaya pendaftaran dan tanpa biaya bulanan. Untuk langganan Rp 99.000 per bulan:
| Cara menagih | Biaya setahun | Diterima setahun |
|---|---|---|
| Bulanan, 12 pembayaran Rp 99.000 | Rp 11.316 | Rp 1.176.684 |
| Tahunan, 1 pembayaran Rp 1.188.000 | Rp 8.566 | Rp 1.179.434 |
Selisihnya Rp 2.750 setahun, dan angka itu bukan kebetulan: komponen persentasenya identik karena totalnya identik, sehingga yang hemat hanya sebelas komponen tetap Rp 250 yang tidak jadi ditagih. Itulah seluruh keuntungan biaya dari menagih tahunan. Melawannya berdiri persetujuan tertulis yang harus diurus lebih dulu, dan kewajiban mengembalikan sisa bulan bila layanan berhenti di tengah jalan.
Pilihan channel berpengaruh jauh lebih besar daripada pilihan periode. Virtual Account ditagih tetap Rp 5.000 per transaksi tanpa komponen persen, sehingga langganan bulanan Rp 99.000 lewat Virtual Account berbiaya Rp 60.000 setahun, lebih dari lima kali lipat QRIS. Pada pembayaran tahunan Rp 1.188.000 posisinya berbalik. Titik impas kedua bentuk tarif itu dibahas di panduan memilih QRIS atau Virtual Account. Untuk langganan bulanan bernominal di bawah ratusan ribu, QRIS hampir selalu jawabannya.
Yang tetap harus dicatat di sisi penagih
Kasera Pay mencatat pembayaran, bukan langganan. Empat hal berikut harus disimpan sendiri, karena tanpanya penagihan berulang berubah menjadi pekerjaan manual dalam dua atau tiga bulan.
- Tanggal jatuh tempo berikutnya per pelanggan. Ini sumber kebenaran tugas harian, dan satu-satunya kolom yang benar-benar wajib.
- Status langganan yang terpisah dari status pembayaran. Aktif, dalam masa tenggang, dan berhenti adalah keadaan langganan. Pembayaran hanya mengenal
pending,succeeded, danexpired, dan tidak tahu apa pun tentang akses. - Riwayat periode yang sudah lunas. Dibutuhkan saat pelanggan bertanya bulan mana yang belum terbayar, dan saat pengembalian dana dihitung.
- Permintaan berhenti berlangganan. Karena tidak ada instruksi debet yang bisa dibatalkan, berhenti berlangganan berarti tugas harian berhenti menerbitkan tautan untuk pelanggan itu. Tanpa kolom ini, permintaan berhenti tidak punya tempat dicatat dan tagihan tetap terbit.
Bila penagihannya bernominal sama dan tidak mengatur akses, misalnya iuran kelas atau iuran warga, bentuk yang jauh lebih ringan biasanya lebih tepat: satu halaman pembayaran permanen yang dipakai ulang tiap bulan, tanpa penerbitan tautan per orang sama sekali. Bentuk itu diuraikan di panduan iuran komunitas.
Pertanyaan yang sering muncul
Apakah Kasera Pay bisa menarik iuran langganan otomatis tiap bulan?
Tidak. Tidak ada instruksi debet berulang yang tersimpan, tidak ada kartu tersimpan, dan tidak ada objek langganan di API. Yang bisa diotomatiskan adalah sisi penagih: penerbitan tautan, pengingat, dan pencatatan status saat webhook payment.paid masuk.
Apakah paket tahunan yang dibayar di muka diperbolehkan?
Perlu persetujuan tertulis lebih dulu. Kebijakan penggunaan terlarang menempatkan pre-order dan langganan yang penyerahannya lebih dari 30 hari ke depan pada daftar yang wajib dikabarkan dan menunggu persetujuan sebelum dimulai. Paket bulanan berjalan tanpa langkah itu karena penyerahannya selalu berada di dalam 30 hari.
Berapa selisih biaya antara menagih bulanan dan menagih tahunan?
Lebih kecil daripada yang biasa diperkirakan. Komponen persentasenya sama karena totalnya sama, jadi yang hemat hanya komponen tetap Rp 250 yang tidak jadi ditagih sebelas kali: pada langganan Rp 99.000 per bulan dengan QRIS, selisihnya Rp 2.750 setahun.