# SaaS Recurring Billing in Indonesia: Midtrans and Xendit

> Cara membangun billing langganan SaaS di Indonesia dengan Midtrans, Xendit, dan QRIS saat kebanyakan pelanggan tidak memakai kartu.

URL: https://www.matthewswong.com/id/blog/saas-recurring-billing-midtrans-xendit-qris-indonesia/

- Author: Matthews Wong (https://www.matthewswong.com/id/about/)
- Published: 2026-04-08
- Updated: 2026-10-17
- Category: Backend

> **Key takeaway:** Di Indonesia, hanya kartu dan e-wallet yang sudah ditautkan yang bisa ditagih otomatis: Subscription API Midtrans menagih kartu tersimpan dan GoPay, Xendit Subscriptions menagih channel apa pun yang mendukung merchant-initiated transaction, dan QRIS, yang tidak bisa ditagih otomatis oleh keduanya, butuh tautan pembayaran baru tiap siklus. Modelkan langganan sebagai mesin status eksplisit berupa aktif, past due, dan canceled, dan anggap hanya webhook yang bertanda tangan dan idempoten sebagai bukti satu siklus sudah dibayar.

Menagih kartu satu kali itu mudah. Menagih pelanggan yang sama secara otomatis tiap bulan, terus-menerus, tanpa ada yang mengklik apa pun, adalah masalah yang berbeda. Itulah inti sebuah langganan, dan di Indonesia hal ini lebih sulit dari yang disiratkan tutorial Stripe.

Kebanyakan pelanggan Indonesia tidak membayar dengan kartu kredit tersimpan. Mereka membayar lewat QRIS, GoPay, OVO, DANA, ShopeePay, atau transfer bank. Sebagian besar rail ini dirancang untuk pembayaran sekali jalan, bukan untuk merchant yang menarik dana secara diam-diam bulan depan. Membangun billing SaaS di sini berarti memahami rail lokal mana yang mendukung tagihan berulang, dan merekayasa solusi untuk yang tidak mendukungnya.

## Kenapa Recurring Billing Sulit di Sini

Penetrasi kartu di Indonesia rendah, sementara QRIS terus tumbuh: Bank Indonesia mencatat 65,77 juta pengguna dan 44,86 juta merchant QRIS per Juni 2026. Recurring billing mengasumsikan kebalikannya: instrumen tersimpan yang bisa ditagih merchant lagi tanpa kehadiran pelanggan. Ketika metode yang dipakai pelanggan adalah kode QR yang dipindai setiap kali, model card-on-file yang jadi andalan SaaS Barat sama sekali tidak cocok.

Akibatnya, kamu tidak bisa sekadar menyalin alur langganan Stripe. Kamu butuh gateway yang mendukung merchant-initiated transaction di rail lokal, cara untuk tokenisasi instrumen apa pun yang dimiliki pelanggan, dan rencana cadangan untuk porsi besar pengguna yang metode bayarnya memang hanya bisa sekali pakai.

- Kepemilikan kartu kredit adalah perilaku minoritas, sehingga default card-on-file justru mengecualikan mayoritas calon pelanggan.
- E-wallet bisa ditautkan untuk tagihan merchant-initiated, tetapi hanya lewat produk tertentu: Subscription API Midtrans menerima GoPay selain kartu, dan Xendit mencantumkan GoPay (lewat channel recurring terpisah yang butuh aktivasi dengan mitra), OVO, DANA, dan ShopeePay sebagai channel yang mendukungnya.
- QRIS, standar QR nasional, menuntut pelanggan bertindak di aplikasinya sendiri untuk setiap pembayaran, entah memindai kode merchant atau menunjukkan kodenya sendiri, sehingga tidak dirancang untuk perpanjangan otomatis diam-diam.

## Gateway dan Fitur Recurring-nya

Midtrans dan Xendit sama-sama mendokumentasikan fitur penagihan berulang. Subscription API Midtrans menagih token tersimpan dengan interval harian, mingguan, atau bulanan dan bisa mengulang penagihan yang gagal hingga tiga kali, tetapi hanya menerima kartu dan GoPay. Recurring kartu memakai ulang token One Click, karena menurut Midtrans recurring dan one click adalah fitur yang sama dan hanya berbeda pada apa yang memicu penagihan, dan fitur ini butuh persetujuan tambahan dari bank serta pembayaran pertama 3DS yang berhasil. Biaya yang dipublikasikan menentukan pilihan itu sama besarnya dengan API-nya. Pada 17 Oktober 2026 Midtrans mencantumkan QRIS 0,7%, kartu 2,9% ditambah Rp 2.000, tarif tetap Rp 4.000 untuk virtual account, GoPay dan ShopeePay 2%, serta DANA dan OVO 1,5%, dengan tarif e-wallet dan QRIS berbeda untuk perusahaan gaming dan produk digital. Bank Indonesia menetapkan MDR QRIS 0% hingga Rp 100.000 untuk semua merchant sejak 1 Oktober 2026, sementara halaman Midtrans hari itu masih menampilkan 0,7%, jadi pastikan tarif mana yang berlaku di akunmu. Tarif tetap virtual account menjadi lebih murah daripada kartu untuk tagihan di atas sekitar Rp 69.000.

Xendit menawarkan produk Subscriptions untuk paket fixed-amount dan usage-based dengan jadwal mingguan, bulanan, atau tahunan. Kamu menentukan nominal, jadwal, dan opsi pemulihan untuk pembayaran gagal, termasuk tautan pembayaran yang bisa dipakai pelanggan saat percobaan gagal, lalu Xendit menangani penarikan dana sambil mengirim webhook seperti recurring.cycle.retrying saat percobaan gagal dan recurring.cycle.succeeded saat satu siklus berhasil; ia butuh minimal satu payment channel yang mendukung merchant-initiated transaction. QRIS, yang distandarkan Bank Indonesia, tidak termasuk: baik Subscription API Midtrans maupun channel QRIS Xendit tidak mendukung penagihan merchant-initiated, sehingga pembayar QRIS menjadi titik perpanjangan manual, bukan instrumen recurring sejati.

> Gateway mana pun yang kamu pilih, simpan token dan subscription id milik gateway terhadap pengguna kamu sendiri, jangan pernah menyimpan kredensial kartu atau dompet mentah. Tokenisasi menjaga data sensitif tetap di luar server kamu dan justru itulah yang membuat penagihan merchant-initiated di kemudian hari menjadi mungkin.

## Mesin Status Langganan

Sebuah langganan adalah mesin status kecil, dan menetapkan status serta transisinya dengan benar adalah sebagian besar pekerjaannya. Modelkan secara eksplisit, bukan menyimpulkan status dari baris pembayaran yang berserakan.

- Active: siklus saat ini sudah dibayar dan pelanggan punya akses, dengan penagihan berikutnya dijadwalkan pada akhir periode.
- Past due: penagihan perpanjangan gagal, sehingga akses bisa berlanjut selama masa tenggang sementara retry dunning berjalan dengan jadwal backoff.
- Canceled: pelanggan atau urutan dunning yang habis mengakhiri langganan, dan akses berhenti di akhir periode berbayar, bukan seketika.
- Proration: ketika paket berubah di tengah siklus, kreditkan porsi paket lama yang belum terpakai dan tagih sisa paket baru secara prorata.

## Keandalan: Webhook dan Idempotency

Pembayaran bersifat asinkron. Pelanggan menyetujui di aplikasi dompet atau memindai QR, dan server kamu baru mengetahui hasilnya belakangan lewat webhook, bukan lewat respons API sinkron. Perlakukan webhook sebagai sumber kebenaran apakah satu siklus berhasil, dan jangan pernah menandai langganan aktif hanya karena kamu mengirim permintaan penagihan.

Webhook melakukan retry dan bisa datang lebih dari sekali atau tidak berurutan, jadi setiap handler harus idempoten: lakukan dedupe berdasarkan event atau order id dari gateway dan buat pemrosesan event yang sama dua kali menjadi no-op. Midtrans mendukung header Idempotency-Key saat membuat langganan, sehingga permintaan create yang di-retry dengan key yang sama dalam tiga menit mengembalikan respons yang sama alih-alih duplikat. Lakukan rekonsiliasi harian dengan menarik daftar transaksi gateway dan membandingkannya dengan ledger kamu sendiri untuk menangkap webhook yang terlewat.

> Jangan pernah mempercayai webhook tanpa memverifikasi tanda tangannya, dan jangan pernah mengubah pengguna menjadi berbayar hanya berdasarkan permintaan. Webhook palsu atau yang di-replay dan kamu proses membabi buta bisa memberi akses gratis atau menagih pelanggan dua kali.

## Jebakan yang Harus Diantisipasi

Mode kegagalan di sini spesifik untuk pasar lokal. Rancang untuk menghadapinya sejak awal, bukan menambal setelah perpanjangan pertama gagal.

- Perpanjangan gagal itu normal, karena saldo e-wallet habis dan kartu kedaluwarsa, jadi urutan dunning dengan retry dan pengingat wajib ada, bukan opsional.
- QRIS dan pembayaran e-wallet yang tidak ditautkan bersifat sekali bayar secara desain, jadi untuk pengguna itu kamu tidak bisa menagih ulang diam-diam: kirim notifikasi perpanjangan dengan tautan pembayaran baru tiap siklus, yang bisa memuat kode QRIS, karena QRIS Tanpa Tatap Muka dari Bank Indonesia memungkinkan merchant membagikan kode lewat gambar atau invoice.
- Pajak dan faktur penting: jika kamu Pengusaha Kena Pajak (PKP), PPN dikenakan 12% atas DPP 11/12 untuk jasa yang bukan barang mewah, dan faktur pajak dibuat lewat Coretax DJP serta kanal yang terhubung dengannya sejak 1 Januari 2025, jadi tanamkan penomoran faktur dan field pajak ke dalam catatan billing kamu dan terbitkan faktur pajak yang benar per penagihan.

Recurring billing SaaS di Indonesia lebih soal kenyataan bahwa kebanyakan pelanggan tidak bisa ditagih ulang secara diam-diam ketimbang soal API pembayaran. Pilih gateway yang menokenisasi instrumen yang benar-benar dimiliki pengguna, modelkan langganan sebagai mesin status yang eksplisit, dan buat setiap webhook idempoten serta terekonsiliasi. Ketika card-on-file mustahil, ubah perpanjangan menjadi alur notifikasi-plus-tautan yang andal.

## Sumber dan bacaan lanjutan

- Midtrans Docs — One Click, Two Clicks, and Recurring Transaction
- Xendit Docs — How Subscriptions Work
- Bank Indonesia — QRIS: mode pembayaran, QRIS Tanpa Tatap Muka, dan skema MDR
- Wikipedia — Subscription business model
- Bank Indonesia — MDR QRIS 0% mulai 1 Oktober 2026 (No. 28/159/DKom)
- Midtrans — daftar biaya transaksi per metode pembayaran

## Source links

- https://docs.midtrans.com/docs/one-click-two-clicks-and-recurring-transaction
- https://docs.xendit.co/docs/how-subscriptions-work
- https://www.bi.go.id/id/fungsi-utama/sistem-pembayaran/ritel/kanal-layanan/qris/default.aspx
- https://en.wikipedia.org/wiki/Subscription_business_model
- https://www.bi.go.id/en/publikasi/ruang-media/news-release/Pages/sp_2815926.aspx
- https://midtrans.com/id/pricing

## FAQ

### Kenapa tidak bisa langsung pakai billing card-on-file ala Stripe di Indonesia?

Kepemilikan kartu kredit di Indonesia rendah, sehingga default card-on-file akan mengecualikan banyak calon pelanggan kamu. Kamu butuh gateway yang bisa menautkan instrumen lokal seperti e-wallet untuk tagihan merchant-initiated, dan alur cadangan untuk rail seperti QRIS yang hanya sekali bayar.

### Apakah Midtrans dan Xendit mendukung langganan berulang?

Ya, dengan batasan. Subscription API Midtrans menagih kartu tersimpan atau akun GoPay yang ditautkan dengan interval harian, mingguan, atau bulanan, dan recurring kartu butuh persetujuan tambahan dari bank. Xendit Subscriptions mendukung paket fixed-amount dan usage-based, retry untuk pembayaran gagal, serta webhook untuk tiap siklus, pada channel apa pun yang mendukung merchant-initiated transaction.

### Bisakah saya menagih pembayaran QRIS otomatis tiap bulan?

Tidak. QRIS menuntut pelanggan bertindak di aplikasinya sendiri untuk setiap pembayaran, dan baik Subscription API Midtrans maupun channel QRIS Xendit tidak mendukung penagihan merchant-initiated. Untuk pengguna QRIS, kirim notifikasi perpanjangan dengan tautan pembayaran atau kode QRIS baru tiap siklus alih-alih penarikan otomatis.

### Apa itu dunning dan kenapa saya membutuhkannya?

Dunning adalah proses otomatis untuk mencoba ulang penagihan perpanjangan yang gagal dan mengingatkan pelanggan. Di Indonesia, saldo e-wallet habis dan kartu kedaluwarsa cukup sering, jadi perpanjangan rutin gagal. Urutan retry-dan-pengingat dengan masa tenggang penting agar tidak kehilangan pelanggan berbayar.

### Kenapa webhook pembayaran perlu idempoten?

Gateway mengirim hasil secara asinkron dan me-retry webhook, jadi event yang sama bisa datang dua kali atau tidak berurutan. Jika handler kamu tidak idempoten, kamu bisa menagih dua kali atau memberi akses ganda. Lakukan dedupe pada event id gateway dan buat pemrosesan ulang event yang sama menjadi no-op.

---

- HTML version: https://www.matthewswong.com/id/blog/saas-recurring-billing-midtrans-xendit-qris-indonesia/
- English: https://www.matthewswong.com/en/blog/saas-recurring-billing-midtrans-xendit-qris-indonesia/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
