Pukul sembilan pagi, tim finance membuka dashboard payment gateway. Ada transaksi bertanda settlement sejak kemarin malam, tapi saldo rekening perusahaan belum bertambah. Di sisi lain, seorang pelanggan mengirim tangkapan layar mutasi bank: dananya sudah keluar. Dua orang melihat dua kebenaran berbeda, dan keduanya benar. Yang salah adalah anggapan bahwa satu kata status mewakili satu peristiwa.
Uang tidak berpindah dalam satu lompatan. Dia bergerak lewat beberapa tahap, dan setiap tahap punya status sendiri, dokumen sendiri, dan waktu penyelesaian sendiri. Artikel ini memetakan alur itu dari awal sampai akhir, termasuk arti setiap status yang biasanya cuma muncul sebagai badge warna di dashboard.
Pihak yang terlibat
Sebelum masuk ke langkah, kenali dulu siapa yang memegang uang di setiap titik.
| Pihak | Perannya |
|---|---|
| Merchant | kamu, yang menagih pembayaran |
| Payment gateway | penerjemah antara sistemmu dan jaringan pembayaran |
| Acquirer | bank atau lembaga yang mengelola akun merchant di jaringan kartu |
| Issuer | bank penerbit kartu atau sumber dana pelanggan |
| Switching | jaringan penghubung antar bank, untuk QRIS dan transfer |
| Penyedia e-wallet | dompet digital pelanggan, misalnya GoPay atau OVO |
Payment gateway tidak menyimpan uang pelanggan. Dia memindahkan instruksi, menerjemahkan format, dan menagih biaya. Uangnya bergerak di antara bank, switching, dan dompet digital, lalu masuk ke akun merchant lewat mekanisme settlement.
Langkah 1: membuat nominal
Semua dimulai dari satu permintaan berisi nominal. Di sinilah kesalahan paling mahal biasanya terjadi, karena nominal yang salah tidak bisa diperbaiki setelah pelanggan membayar.
Yang dikirim ke payment gateway biasanya mencakup identitas transaksi dan rinciannya:
{
"order_id": "INV-2026-11-0042",
"gross_amount": 150000,
"currency": "IDR",
"payment_type": "bank_transfer",
"customer": { "name": "Budi", "email": "[email protected]" },
"item_details": [
{ "id": "JASA-01", "price": 120000, "quantity": 1, "name": "Jasa pasang" },
{ "id": "MAT-07", "price": 30000, "quantity": 1, "name": "Material" }
],
"expiry": { "unit": "hour", "value": 24 }
}
Empat hal yang perlu diperhatikan di blok itu.
order_id harus unik dan kamu yang menentukan. Kalau sistemmu mengirim ulang permintaan dengan order_id yang sama, gateway yang baik akan mengembalikan transaksi yang sudah ada, bukan membuat transaksi baru. Untuk itu, simpan juga kunci idempotensi di sisi kamu.
gross_amount harus sama dengan jumlah price × quantity pada item_details. Beberapa gateway menolak permintaan yang tidak cocok, sebagian lain menerimanya dan menyulitkan rekonsiliasi nanti.
expiry menentukan sampai kapan pelanggan boleh membayar. Nomor virtual account dan kode QR yang kedaluwarsa bukan kegagalan sistem, itu perilaku yang kamu minta sendiri.
payment_type menentukan kanal. Sebagian gateway meminta ini di awal, sebagian lain membiarkan pelanggan memilih di halaman mereka.
Setelah permintaan diterima, transaksi lahir dengan status pending. Uangnya belum ada di mana pun. Yang ada hanya janji bahwa nominal ini sah dan bisa dibayar sampai batas waktu tertentu.
Langkah 2: memilih kanal pembayaran
Setiap kanal punya cara kerja, waktu, dan biaya berbeda. Perbedaan ini menjelaskan kenapa dua transaksi dengan nominal sama bisa masuk rekening di hari yang berbeda.
| Kanal | Cara bayar | Ciri khas |
|---|---|---|
| Virtual account | transfer ke nomor khusus per transaksi | cepat terverifikasi, biaya tetap per transaksi |
| QRIS | pindai kode dengan aplikasi bank atau e-wallet | murah, cocok untuk nominal kecil |
| E-wallet | dialihkan ke aplikasi dompet digital | pelanggan harus punya saldo, konfirmasi di aplikasi |
| Kartu kredit atau debit | isi data kartu, kadang dengan 3DS | ada otorisasi dan settlement terpisah |
| Gerai retail | bayar tunai di Alfamart atau Indomaret | cocok untuk pelanggan tanpa rekening, settlement lebih lambat |
| Paylater | cicilan lewat penyedia pembiayaan | risiko dan biaya ditanggung pihak ketiga |
Virtual account adalah yang paling mudah dipahami. Gateway membuat nomor rekening unik untuk satu transaksi, biasanya di bawah satu nama penampung. Ketika pelanggan mentransfer, bank penerima mengenali nomornya dan mengirim notifikasi kembali ke gateway. Tidak ada pencocokan manual, karena nomor itu sendiri yang menjadi identitas transaksi.
Langkah 3: otorisasi
Di sini jalur kartu dan non-kartu berpisah. Untuk transfer bank, QRIS, dan e-wallet, tidak ada otorisasi terpisah: pelanggan membayar, selesai. Untuk kartu kredit, ada dua peristiwa yang sering dianggap satu.
Authorize berarti issuer menyatakan dana pelanggan tersedia dan menyisihkannya. Saldo pelanggan sudah berkurang atau terblokir, tapi uang belum berpindah ke merchant. Status ini muncul sebagai authorize atau capture tergantung gateway.
Capture berarti instruksi pengambilan dana benar-benar dikirim. Pada banyak gateway, capture dan authorize terjadi bersamaan untuk transaksi e-commerce biasa. Pada model authorize dulu, capture menyusul ketika barang dikirim, dan ada batas waktu beberapa hari sebelum otorisasi kedaluwarsa.
Kesalahan umum di sini: menganggap status capture sebagai tanda uang sudah masuk. Belum. Capture hanya berarti pengambilan dana disetujui. Uangnya bergerak di tahap settlement.
Langkah 4: pelanggan membayar
Pelanggan menyelesaikan pembayaran di kanal yang dipilih. Dari sudut sistemmu, ini periode menunggu yang paling menegangkan, karena kamu tidak punya kendali apa pun di sini.
Yang bisa kamu lakukan cuma dua: memberi instruksi yang jelas dan menunggu notifikasi. Tiga hal yang wajib benar di tahap ini:
- Halaman atau instruksi pembayaran menampilkan nominal, nomor tujuan, dan batas waktu yang persis sama dengan data transaksi.
- Sistemmu tidak menganggap pesanan lunas hanya karena pelanggan menekan tombol "sudah bayar".
- Ada mekanisme untuk memeriksa status langsung ke gateway, sebagai cadangan kalau notifikasi tidak masuk.
Langkah 5: notifikasi
Setelah pembayaran terverifikasi, gateway mengirim notifikasi ke endpoint milikmu. Ini webhook, dan isinya biasanya lebih lengkap dari yang kamu butuhkan:
{
"order_id": "INV-2026-11-0042",
"status_code": "200",
"transaction_status": "settlement",
"payment_type": "bank_transfer",
"gross_amount": "150000.00",
"transaction_id": "8f2c1b7a-...",
"settlement_time": "2026-11-10 09:12:44",
"fraud_status": "accept",
"signature_key": "..."
}
Empat aturan yang tidak boleh dilanggar saat menangani webhook:
Verifikasi tanda tangan. Endpoint webhook itu alamat publik. Tanpa pemeriksaan signature_key, siapa pun bisa mengirim notifikasi palsu dan membuat pesanan lunas.
Jangan percaya status 200 di body. Di sebagian gateway, status_code adalah kode HTTP yang mereka sertakan di dalam payload, bukan hasil akhir. Yang menentukan adalah transaction_status.
Tangani notifikasi berulang. Gateway akan mengirim ulang kalau endpoint-mu lambat atau membalas error. Proses yang sama bisa masuk dua kali, jadi operasinya harus idempoten: periksa apakah transaksi itu sudah pernah ditandai lunas sebelum mengubah apa pun.
Simpan payload mentah. Saat ada sengketa enam bulan kemudian, payload asli adalah satu-satunya bukti yang tidak bisa diperdebatkan.
Pola penanganan webhook yang rapi sebenarnya bagian dari pekerjaan API biasa, dan saya pernah menulis soal bentuk respons dan idempotensi di delapan pola REST API.
Langkah 6: settlement
Inilah kata yang paling sering disalahpahami. Settlement bukan berarti uang sudah ada di rekening bankmu.
Settlement berarti dana sudah berpindah dari issuer ke acquirer atau ke rekening penampung payment gateway, dan transaksi sudah masuk hitungan untuk dibayarkan kepadamu. Pada titik ini status transaksi berubah dari pending atau capture menjadi settlement, dan saldo merchant di dashboard bertambah.
Kenapa rekening bank belum bertambah? Karena pencairan dilakukan terpisah, biasanya sekali sehari, mengikuti jadwal dan jam cut-off. Transaksi yang lunas setelah cut-off masuk ke batch hari berikutnya.
Tiga hal yang terjadi bersamaan dengan settlement:
Potongan biaya. MDR (merchant discount rate) dipotong di sini, bukan saat transaksi dibuat. Untuk QRIS di Indonesia, besaran MDR diatur regulator dan berbeda antara merchant umum dan usaha mikro. Untuk kartu, MDR mengikuti kesepakatan dengan acquirer. Karena itu, angka gross_amount di laporan selalu lebih besar dari nominal yang masuk rekening.
Perubahan status yang tidak selalu seragam. Sebagian gateway menandai transaksi kartu sebagai capture dulu, baru settlement setelah batch selesai. Sebagian lagi langsung settlement untuk transfer dan QRIS. Jangan membuat logika bisnis yang mengandalkan satu urutan pasti lintas kanal.
Pembentukan laporan settlement. Setiap batch menghasilkan berkas berisi daftar transaksi, nominal kotor, potongan, dan nominal bersih. Berkas inilah yang nanti dicocokkan dengan mutasi bank.
Settlement dan pencairan adalah dua peristiwa berbeda dengan tanggal berbeda. Kalau dashboard menunjukkan settlement hari ini dan rekening masih kosong, itu normal selama jadwal pencairan belum jatuh. Yang tidak normal adalah kalau selisihnya lebih dari satu siklus pencairan.
Langkah 7: pencairan ke rekening
Pencairan, atau payout, adalah perpindahan dana dari saldo merchant di payment gateway ke rekening bank yang kamu daftarkan.
Yang menentukan kapan uangmu tiba:
- Jadwal. Umumnya harian untuk merchant yang sudah terverifikasi, dengan opsi instan berbiaya tambahan.
- Cut-off. Transaksi setelah jam tertentu masuk batch besok.
- Hari kerja. Settlement yang jatuh di akhir pekan atau libur bergeser ke hari kerja berikutnya.
- Biaya transfer. Beberapa penyedia membebankan biaya per pencairan, terutama untuk pencairan instan.
- Status rekening. Rekening yang belum terverifikasi atau sedang dibekukan menahan pencairan.
Untuk perencanaan arus kas, satu patokan praktis: uang yang kamu pegang hari ini adalah settlement dari transaksi dua sampai tiga hari lalu, bukan transaksi hari ini.
Semua status dan artinya
Nama status berbeda antar penyedia, jadi tabel ini memakai istilah yang paling umum. Yang penting adalah memahami kelasnya: status yang berarti belum ada uang, status yang berarti uang sedang bergerak, dan status yang berarti uang sudah masuk hitungan.
| Status | Arti | Uang di mana | Tindakanmu |
|---|---|---|---|
pending | transaksi dibuat, menunggu pembayaran | belum ada di mana pun | tampilkan instruksi, jangan anggap lunas |
authorize | dana pelanggan disisihkan issuer | di sisi issuer, terblokir | kirim barang atau tunggu capture |
capture | pengambilan dana disetujui | di issuer, menuju acquirer | boleh diproses, belum masuk rekening |
settlement | dana masuk hitungan pembayaran | saldo merchant di gateway | siapkan pencairan dan rekonsiliasi |
expire | batas waktu habis sebelum dibayar | tidak ada | tutup pesanan, izinkan pelanggan mengulang |
cancel | dibatalkan sebelum dibayar | tidak ada | tutup pesanan |
deny | ditolak issuer atau sistem antifraud | tidak ada | minta pelanggan memakai kanal lain |
failure | pembayaran gagal teknis | tidak ada | izinkan percobaan ulang dengan transaksi baru |
refund | dana dikembalikan sebagian atau seluruhnya | keluar dari saldo merchant | catat pengurangan, kirim bukti ke pelanggan |
partial_refund | sebagian dana dikembalikan | sebagian keluar | sesuaikan nilai pesanan |
chargeback | pelanggan menyanggah transaksi lewat issuer | ditahan atau ditarik kembali | kirim bukti transaksi sebelum tenggat |
partial_chargeback | sengketa atas sebagian nominal | sebagian ditahan | sama, dengan nominal lebih kecil |
Satu catatan penting: expire, cancel, deny, dan failure sama-sama berarti tidak ada uang, tapi penyebabnya berbeda dan berpengaruh ke pengalaman pelanggan. Menyamakan semuanya menjadi satu pesan "pembayaran gagal" membuat pelanggan mengulang kesalahan yang sama.
Contoh perhitungan uang
Angka di bawah ini contoh, bukan tarif resmi penyedia mana pun. Yang perlu kamu perhatikan adalah urutan pengurangannya.
| Tahap | Nominal |
|---|---|
| Nilai transaksi | Rp150.000 |
| MDR 0,7 persen | Rp1.050 |
| Yang masuk saldo merchant | Rp148.950 |
| Biaya pencairan | Rp2.500 |
| Yang masuk rekening bank | Rp146.450 |
Kalau transaksi ini di-refund penuh, saldo merchant berkurang Rp148.950, dan potongan MDR umumnya tidak kembali. Kalau berubah menjadi chargeback, ada biaya sengketa tambahan yang besarnya berbeda tiap penyedia. Dua hal itulah yang membuat refund dan chargeback tidak pernah netral bagi arus kas.
Kesalahan yang paling sering terjadi
Dari pengalaman memperbaiki integrasi yang bermasalah, enam pola ini muncul berulang.
- Menandai pesanan lunas saat pelanggan menekan "sudah bayar". Selalu tunggu notifikasi atau verifikasi langsung ke gateway.
- Menganggap
captureberarti dana masuk. Dana masuk saat settlement, dan bisa dicairkan setelah jadwal payout. - Tidak menyimpan
order_idsendiri. Kalau identitas transaksi ditentukan gateway, rekonsiliasi jadi menyakitkan. - Webhook tanpa verifikasi tanda tangan. Ini lubang keamanan paling langsung di seluruh alur.
- Tidak menutup transaksi
expire. Pesanan menggantung, stok terkunci, dan laporan penjualan membengkak. - Tidak merekonsiliasi harian. Selisih kecil yang dibiarkan akan menjadi selisih besar yang tidak bisa ditelusuri asalnya.
Checklist implementasi
Sebelum integrasi dianggap selesai, pastikan semuanya ada:
order_idbuatan sendiri, unik, dan disimpan sebelum permintaan dikirim ke gateway.- Kunci idempotensi pada pembuatan transaksi dan pada pemrosesan webhook.
- Verifikasi tanda tangan atau token pada setiap notifikasi.
- Pemeriksaan status langsung ke API gateway sebagai cadangan webhook.
- Batas waktu pembayaran yang konsisten antara data transaksi dan instruksi ke pelanggan.
- Pencatatan payload mentah setiap notifikasi, termasuk yang gagal diproses.
- Ledger internal yang mencatat nilai kotor, potongan, nilai bersih, refund, dan chargeback sebagai baris terpisah.
- Job rekonsiliasi harian yang mencocokkan laporan settlement gateway dengan mutasi bank.
- Halaman status pesanan yang memakai istilah manusia, bukan nama status mentah dari API.
Penutup
Alur pembayaran bukan satu tombol yang mengubah pesanan menjadi lunas. Dia rangkaian peristiwa dengan pemilik berbeda di setiap tahap: sistemmu membuat nominal, gateway menerjemahkan instruksi, issuer memindahkan dana, acquirer menghitung settlement, dan bank baru mengirim uang ke rekeningmu beberapa hari kemudian.
Kalau kamu membangun integrasi sendiri, mulailah dari dua hal yang paling sering diabaikan: idempotensi dan rekonsiliasi. Keduanya tidak terlihat di demo, tapi keduanya yang menentukan apakah laporan keuanganmu bisa dipercaya saat transaksi sudah ribuan sehari.







