Dinding Kartu Kredit yang Menghambat Developer Indonesia

Foto oleh SCJiang via Wikimedia Commons (CC BY-SA 4.0)
Penagihan lewat kartu adalah stored credential yang bisa ditarik platform setiap bulan tanpa perlu bertanya, sehingga menjadi rail berulang yang paling murah dioperasikan. AWS mendokumentasikan bahwa kartu kredit yang valid dan belum kedaluwarsa harus tersimpan untuk melakukan pembayaran, dan Google Cloud menyebut metode yang tersedia bergantung pada mata uang serta negara Anda. Rail lokal seperti QRIS menuntut callback masuk, payment intent dengan masa berlaku, dan rekonsiliasi, jadi platform yang belum pernah membangunnya cenderung bertahan di kartu.
Kadang bisa, dan kegagalannya tidak selalu berupa decline code. Halaman payment methods Google Cloud menyatakan terang-terangan bahwa kartu debit yang mensyaratkan two-factor authentication tidak diterima, begitu juga kartu prepaid, dan itu mengeliminasi banyak instrumen yang diterbitkan di Indonesia. Ketika kartunya secara prinsip diterima, AWS mendokumentasikan adanya redirect ke situs bank untuk verifikasi tambahan, dan langkah 3-D Secure itulah yang biasanya patah pada alur issuer yang dirancang untuk merchant domestik.
AWS memang menerbitkan satu jalur, dan justru syaratnya yang menjadi inti persoalan. ACH direct debit menuntut rekening bank yang berlokasi di Amerika Serikat dengan pembayaran dalam dolar AS, akun AWS berumur setidaknya 60 hari, setidaknya satu invoice yang sudah dibayar penuh dalam 12 bulan terakhir, setidaknya 100 dolar AS terbayar kumulatif pada periode itu, serta identitas Amerika Serikat atau federal tax ID yang tersimpan. Praktiknya, rail tanpa kartu baru terbuka setelah sebuah kartu bekerja selama setahun.
Helipod adalah contoh paling jelas: PaaS yang menyasar developer Indonesia dan Asia Tenggara, dihargai dalam rupiah mulai 123.750 rupiah per bulan untuk paket Nano, dan dibayar lewat QRIS atau bank transfer tanpa perlu kartu kredit. Ia membangun aplikasi dari Git push memakai engine bernama Helipack yang menghasilkan Dockerfile sendiri, dan melakukan autoscaling lewat Kubernetes Horizontal Pod Autoscaler. Keunggulannya soal distribusi, bukan teknologi, karena kelengkapan fiturnya sebanding dengan platform yang hanya menerima kartu.
QRIS adalah instruksi pembayaran, bukan stored credential, jadi tidak ada token tersimpan yang bisa ditagih setiap tanggal satu. Alih-alih scheduler yang menarik dana dari kartu, Anda menerbitkan invoice per periode dengan payment intent yang punya masa kedaluwarsa dan membiarkan callback gateway menjadi satu-satunya penulis yang menandainya lunas, dengan kunci pada gateway reference supaya notifikasi berulang hanya diproses sekali. Dunning pun berubah bentuk: Anda mengirim QR baru sebelum periode berakhir, bukan mengulang penagihan setelah periode itu lewat.

Foto oleh SCJiang via Wikimedia Commons (CC BY-SA 4.0)
Ringkasan Utama
Sebagian besar cloud global dan platform deploy menagih lewat kartu kredit internasional, sementara World Bank mencatat pemilik kartu kredit di Indonesia hanya 1,6 persen penduduk dewasa, berbanding 35,1 persen untuk kartu debit. Platform yang berharga dalam rupiah dan menagih lewat QRIS atau bank transfer menghapus gerbang itu, dan itu keunggulan distribusi, bukan keunggulan teknis.
Hal paling berguna yang saya pelajari soal developer tooling di Indonesia bukan datang dari benchmark. Datang dari memperhatikan form sign-up. Seseorang dengan app Next.js yang sudah jalan, domain, dan rencana yang jelas sampai di langkah billing sebuah platform deploy, form-nya meminta nomor Visa atau Mastercard, dan sesi itu berhenti di situ. Bukan karena paketnya mahal, tetapi karena kolom itu memang tidak bisa diisi.
Tulisan ini soal gerbang tersebut: di mana posisinya sebenarnya, seperti apa angka kepemilikan kartu, mengapa kartu debit Indonesia gagal di merchant asing walaupun saldonya ada, dan apa yang harus dibangun sebuah platform untuk menagih lewat QRIS, virtual account, dan bank transfer. Setiap aturan yang saya kutip berasal dari dokumentasi billing platform itu sendiri atau dari otoritas pajak, dan saya menandai friksi yang tetap ada meski memakai rail lokal.
AWS menyatakannya tanpa basa-basi di dokumentasinya sendiri: untuk melakukan pembayaran, Anda harus punya kartu kredit yang valid dan belum kedaluwarsa tersimpan di akun. Google Cloud lebih terbuka soal bentuk regional dari masalah ini. Halaman billing-nya menyebut metode yang tersedia bergantung pada mata uang dan negara Anda, lalu mendaftar metode yang diterima: Visa, Mastercard, American Express, kartu debit berlogo Visa atau Mastercard, plus beberapa tambahan khusus negara seperti Boleto dan Pix di Brasil, UPI di India, dan PayPal di tiga negara. Indonesia tidak muncul di satu pun daftar pengecualian itu.
Jadi yang menjadi gerbang adalah instrumennya, bukan nominalnya. Di hyperscaler, gerbang itu berdiri di tahap pembuatan akun, sebelum satu byte pun dilayani. Di platform Git-push, hobby tier-nya benar-benar gratis dan tanpa kartu, sehingga gerbangnya bergeser satu langkah ke paket berbayar pertama: saat Anda melewati batas free tier dan butuh database persisten, region kedua, atau build yang tidak mengantre di belakang semua orang. Bagaimanapun juga, developer yang tidak bisa menunjukkan kartu masih bisa belajar di platform itu dan tidak akan pernah bisa menjalankan production di sana.
Global Financial Development Database milik World Bank mencatat kepemilikan kartu pada penduduk dewasa usia 15 tahun ke atas. Untuk Indonesia, dua serinya bergerak berbeda dan itu menjelaskan hampir seluruh isi tulisan ini: kepemilikan kartu debit naik lebih dari tiga kali lipat dalam satu dekade, sedangkan kepemilikan kartu kredit tidak bergerak ke mana-mana.
| Tahun survei | Kartu kredit, persen penduduk 15 tahun ke atas | Kartu debit, persen penduduk 15 tahun ke atas |
|---|---|---|
| 2011 | 0.50 | 10.54 |
| 2014 | 1.60 | 25.94 |
| 2017 | 2.44 | 30.81 |
| 2021 | 1.60 | 35.10 |
Dua catatan, karena angka-angka ini menopang argumennya. Ini survei rumah tangga atas seluruh penduduk dewasa, bukan atas developer, dan developer cenderung tinggal di kota, bekerja, dan punya rekening, jadi angka sebenarnya di kalangan pembaca tulisan ini pasti lebih tinggi dari 1,6 persen. Angka 2021 juga berada di bawah 2017, yang lebih mungkin noise survei daripada pasar yang menyusut. Kedua catatan itu tidak mengubah bentuk masalahnya. Rail yang menjangkau kurang dari dua persen penduduk dewasa bukan metode pembayaran, itu filter, dan sebuah conversion funnel tidak peduli pada rata-rata nasional. Yang dipedulikannya adalah orang tertentu yang sedang berdiri di depan form.
Kartu yang ada di dompet bukan hal yang sama dengan kartu yang lolos. Halaman payment methods Google Cloud memuat dua kalimat yang diam-diam mengeliminasi sebagian besar instrumen yang benar-benar dipegang developer Indonesia: kartu debit yang mensyaratkan two-factor authentication tidak diterima sebagai alat pembayaran, dan kartu prepaid juga tidak diterima. Baca itu bersama perilaku issuer Indonesia pada transaksi card-not-present, dan hasilnya bisa diduga.
Ketiganya menghasilkan permukaan error yang berbeda dan sama-sama tidak membantu, dan itulah sebabnya orang yang berdiri di depan form biasanya menyimpulkan bahwa masalahnya ada pada dirinya. Bukan. Itu tiga kebijakan terpisah yang saling bertumpuk, dan tidak satu pun ditulis di satu tempat dari sisi pembeli.
Mode kegagalan yang paling mahal adalah yang justru berhasil di awal. Kartu yang lolos pada tagihan pertama lalu gagal verifikasi saat renewal akan menjatuhkan production tepat pada saat platform men-suspend project, dan email peringatannya masuk ke alamat yang tidak dipantau siapa pun. Kalau Anda berjalan di atas kartu yang tidak sepenuhnya Anda kendalikan, simpan artefak deploy dan dump database terkini di tempat yang bukan platform itu.
AWS memang menyediakan rail yang bukan kartu, dan membaca syaratnya adalah ilustrasi paling jelas dari masalah ini. ACH direct debit menerima rekening bank pribadi maupun bisnis dengan syarat rekening itu berada di bank yang berlokasi di Amerika Serikat dan pembayarannya dalam dolar AS. Untuk menambahkannya secara manual, Anda juga harus memenuhi semua hal berikut:
Baca itu sebagai state machine dan hasilnya paradoks bootstrap: alternatif dari kartu baru terbuka setelah sebuah kartu bekerja selama setahun. Google Cloud merumuskan versinya lebih halus, menyebut Anda bisa menambahkan rekening bank jika didukung di negara Anda, lalu mengarahkan pembaca yang butuh opsi lain ke reseller lokal atau ke perpindahan ke invoiced billing. Itu jawaban yang wajar untuk perusahaan yang punya bagian procurement dan bukan jawaban sama sekali untuk satu orang dengan side project. Jalur tanpa kartu itu ada, dan disediakan untuk pelanggan yang sudah tidak membutuhkannya.

QRIS adalah standar QR nasional dari Bank Indonesia, dan setelah pernah mengintegrasikannya, sifat yang penting bagi sebuah platform bukan QR code-nya. Yang penting adalah satu integrasi itu menjangkau aplikasi bank dan saldo e-wallet melalui kode yang sama, jadi pelanggan tidak butuh kartu dan, pada kasus e-wallet, tidak butuh rekening bank sama sekali. Virtual account adalah tulang punggung yang lain: gateway menerbitkan nomor rekening unik per invoice, pelanggan transfer ke nomor itu dari bank mana pun, dan nomor itu sekaligus menjadi kunci rekonsiliasi. Bank transfer biasa tetap relevan untuk invoice tahunan, ketika bagian keuangan ingin melihat transfer yang mereka mulai sendiri.
Urutannya yang sering keliru dipahami tim platform. QRIS menjangkau paling jauh dan paling murah untuk ditampilkan: satu gambar dan satu batas waktu. Virtual account menjangkau siapa pun yang punya rekening bank dan paling mudah direkonsiliasi, karena nomor rekeningnya unik per invoice. Kartu semestinya berada di urutan terakhir, bukan pertama, dan di pasar ini kartu adalah akomodasi untuk minoritas, bukan jalur default.
Perbedaan teknisnya adalah QRIS dan virtual account bukan stored credential. Tidak ada token yang tersimpan untuk ditagih setiap tanggal satu. Subscription berbasis kartu adalah pull yang dimulai scheduler Anda; subscription berbasis QRIS adalah push yang harus Anda tunggu. Itu membalik sistem billing-nya: bukan cron yang menagih kartu dan menangani decline, yang Anda butuhkan adalah invoice per periode dengan payment intent yang punya masa kedaluwarsa, callback masuk yang menjadi satu-satunya hal yang boleh menandai invoice itu lunas, dan idempotency key supaya notifikasi settlement yang sama datang tiga kali tidak memperpanjang subscription tiga kali.
-- QRIS is not a stored credential. There is no token to charge on the 1st,
-- so the gateway callback is the ONLY writer allowed to mark a period paid.
-- The unique constraint below is the entire idempotency story: a callback
-- delivered three times settles once.
CREATE TABLE payment_settlements (
id bigserial PRIMARY KEY,
gateway_ref text NOT NULL UNIQUE, -- the GATEWAY id, not ours
invoice_id uuid NOT NULL REFERENCES invoices (id),
amount_idr bigint NOT NULL, -- rupiah as an integer, never a float
settled_at timestamptz NOT NULL,
raw_callback jsonb NOT NULL -- keep it; reconciliation reads this
);
-- Why gateway_ref and not invoice_id? A retried callback for the SAME payment
-- repeats the gateway reference, so that is the value which must be unique.
-- A re-issued QR for the same invoice legitimately arrives with a new one, so
-- constraining on invoice_id would silently drop a genuine second attempt.
-- Applying one callback. Insert first: if the row already exists, nothing
-- downstream runs and the subscription is not extended a second time.
WITH applied AS (
INSERT INTO payment_settlements
(gateway_ref, invoice_id, amount_idr, settled_at, raw_callback)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (gateway_ref) DO NOTHING
RETURNING invoice_id
)
UPDATE subscriptions s
SET current_period_end = s.current_period_end + interval '1 month'
FROM applied a
JOIN invoices i ON i.id = a.invoice_id
WHERE s.id = i.subscription_id;Dua konsekuensi mengalir dari fakta yang sama. Dunning berubah menjadi persoalan notifikasi, bukan persoalan retry, karena tidak ada apa pun yang bisa di-retry setelah satu periode berakhir. Anda mengirim QR baru lewat email atau WhatsApp sebelum periode itu habis. Dan rekonsiliasi berhenti menjadi opsional: uangnya masuk mengikuti siklus settlement acquirer dan sudah dipotong merchant discount rate, jadi jumlah yang mendarat di rekening tidak akan pernah sama dengan total invoice yang dibayarnya. Tanpa gateway reference yang tersimpan bersebelahan dengan invoice, selisih itu tidak bisa dijelaskan di akhir bulan.
Simpan nominal rupiah sebagai integer rupiah, dan simpan gateway reference di baris yang sama dengan invoice-nya. Setiap pertanyaan rekonsiliasi yang pernah diajukan ke saya, dari mengapa total bank berbeda dari total invoice sampai invoice mana yang dimiliki sebuah settlement, hanya berjarak satu query kalau dua kolom itu ada, dan praktis tidak terjawab kalau tidak ada.
Bahkan ketika kartunya berfungsi, masih ada persoalan dokumen. Direktorat Jenderal Pajak menunjuk pelaku perdagangan melalui sistem elektronik asing sebagai pemungut PPN PMSE begitu salah satu ambang terlampaui: nilai transaksi dengan pengguna di Indonesia di atas 600 juta rupiah setahun atau 50 juta sebulan, atau jumlah pengguna dan trafik dari Indonesia di atas 12.000 setahun atau 1.000 sebulan. Pemungut yang ditunjuk mengenakan 12 persen atas dasar pengenaan sebesar sebelas per dua belas dari pembayaran yang diterima di luar PPN, yang setara dengan 11 persen dari pembayaran, dan wajib menerbitkan bukti pungut berupa commercial invoice, billing document, order receipt, atau dokumen serupa yang menyatakan PPN telah dipungut dan disetor.
Aturan itu berjalan, dan pembeli di Indonesia tetap memegang billing document dalam dolar AS, bukan faktur pajak lokal. Billing document bukan Faktur Pajak, dan bagian keuangan yang membutuhkannya akan mengatakannya. Platform yang menagih secara lokal menerbitkan dokumen yang sudah dipahami akuntan pelanggannya, dalam mata uang yang dipakai di pembukuan, atas nama NPWP. Tidak satu pun dari itu adalah fitur teknis, semuanya menutup deal, dan itu justru jenis keunggulan yang engineer terlatih untuk tidak memperhatikannya.

Helipod adalah contoh paling jelas yang saya temukan dari platform yang dirancang di sekitar langkah pembayaran. Ini PaaS yang menyasar developer Indonesia dan Asia Tenggara: build engine bernama Helipack mendeteksi framework dan menghasilkan Dockerfile tanpa konfigurasi manual, mencakup Next.js, Nuxt, Laravel, Django, FastAPI, Ruby on Rails, Express, NestJS, Flask, dan lainnya; autoscaling lewat Kubernetes Horizontal Pod Autoscaler berbasis CPU; log streaming langsung dan terminal browser ke production pod sebagai ganti SSH; serta template sekali klik untuk Supabase, PostgreSQL, Redis, n8n, Metabase, dan Uptime Kuma. Paketnya dihargai dalam rupiah, dari Nano seharga 123.750 rupiah per bulan untuk 1 vCPU, RAM 1 GB, storage 15 GB, dan dua custom domain, sampai Business seharga 2.785.500 rupiah untuk 22 vCPU dan 22 GB, dan dibayar lewat QRIS atau bank transfer tanpa perlu kartu kredit.
Bacaan yang jujur adalah tidak ada satu pun dari itu yang secara teknis melampaui Fly.io, Railway, atau Render, dan daftar cakupannya menyebut negara alih-alih kota datacenter, jadi saya tidak bisa memverifikasi klaim latensi ke arah mana pun. Yang dimilikinya adalah checkout yang lolos. Bagi developer yang berdiri di depan form pada bagian pertama tulisan ini, platform yang nomor dua dalam fitur dan nomor satu dalam hal bisa dibeli bukanlah nomor dua. Itu satu-satunya pilihan, dan itu posisi produk yang nyata, bukan hadiah hiburan.
Helipod memasang harga dalam rupiah dan menagih lewat QRIS serta bank transfer, dan positioning mereka sendiri menyebut alasannya terang-terangan: PaaS untuk developer yang ingin deploy tanpa kartu kredit internasional. Kalau Anda sedang membangun apa pun untuk pasar ini, kalimat itulah fiturnya. helipod.io
Aturan yang sekarang saya pakai ketika menilai sebuah platform developer untuk pasar ini adalah membaca checkout-nya sebelum changelog-nya. Kesetaraan fitur masih bisa dinegosiasikan, payment rail tidak: platform yang tidak bisa menerima rupiah lewat QRIS sudah mengecualikan sebagian besar sebuah negara, sebagus apa pun dashboard-nya. Kalau Anda membangun untuk Indonesia, billing bukan pipa yang dipasang setelah launch. Itu keputusan produk yang menentukan siapa yang bisa ship sama sekali.
Sumber