Blog · 2 September 2026
Pembeli bilang sudah bayar, tetapi statusnya masih pending: urutan memeriksanya
Kalimat “sudah bayar kok, cek lagi” hampir selalu ditangani dengan cara yang salah, yaitu dengan meminta bukti transfer. Masalahnya, kalimat itu bisa berarti tiga hal yang letaknya berbeda-beda, dan hanya satu di antaranya yang benar-benar persoalan pembeli:
- Kasera Pay memang belum pernah mencatat pembayaran itu. Statusnya
pendingatauexpired. - Kasera Pay sudah mencatatnya sebagai
succeeded, tetapi sistem toko sendiri yang belum berubah, karena webhook-nya tidak sampai. - Keduanya sudah
succeeded, dan yang belum sampai adalah uangnya ke rekening bank. Ini bukan kesalahan siapa pun.
Satu pertanyaan memisahkan ketiganya: apa yang tertulis pada baris pembayaran itu di halaman Transaksi. Sebelum pertanyaan itu terjawab, membalas pembeli hanya menebak.
Langkah nol: menemukan barisnya
Penyebab paling sering dari “pembayarannya hilang” bukan pembayaran yang hilang, melainkan penyaring bawaan. Halaman Transaksi terbuka pada tampilan pembayaran dibayar dan menunggu, dan halaman itu menyebutkannya sendiri di bawah kotak penyaring. Artinya pembayaran yang sudah kedaluwarsa tidak ada di layar sama sekali pada tampilan bawaan, padahal justru status itulah yang sedang dicari. Tombol Tampilkan semua status yang membukanya.
Kotak pencarian juga lebih sempit daripada kelihatannya: yang dicari hanya keterangan dan nomor pesanan, sebagai pencocokan sebagian. Referensi sendiri dan id payreq_ tidak ikut dicari dari kotak itu. Untuk integrasi, yang menjawab pertanyaan “baris mana persisnya” adalah penyaring persis pada GET /v1/transactions, yaitu external_id dan merchant_ref, atau pengambilan langsung dengan GET /v1/transactions/:id. Rinciannya ada pada referensi daftar transaksi.
Kemungkinan pertama: statusnya pending atau expired
Kalau barisnya ditemukan dan statusnya bukan succeeded, uangnya tidak pernah masuk ke Kasera Pay. Penyebabnya hampir selalu salah satu dari ini.
- Tautannya sudah kedaluwarsa saat dibayar. Masa berlaku bawaan 60 menit, dan status kedaluwarsa dihitung dari waktu, bukan dari sebuah proses yang harus berjalan dulu. Baris yang tersimpan sebagai
pendingtetapi sudah lewatexpires_attampil dan terekspor sebagaiexpired. Pilihan masa berlaku dibahas terpisah pada artikel masa berlaku tagihan. - Yang dibayar adalah tautan yang lain. Satu pesanan bisa punya dua tautan ketika permintaan pembuatan diulang tanpa header
Idempotency-Key, misalnya karena koneksi terputus lalu dicoba lagi. Pembeli membayar tautan pertama, sementara yang dipantau tautan kedua, dan keduanya nyata. Mekanismenya ada pada artikel tagihan ganda dan Idempotency-Key. - QR-nya berasal dari tangkapan layar lama. Setiap permintaan pembayaran menerbitkan QRIS dinamisnya sendiri yang hanya berlaku untuk permintaan itu. QR yang disimpan pembeli dari pesanan bulan lalu, atau yang diteruskan dari teman, bukan QR pesanan yang sedang ditanyakan.
- Transfernya masuk ke rekening toko, bukan ke nomor Virtual Account. Kebiasaan lama menang: nomor Virtual Account disalin, lalu yang dipakai tetap rekening toko yang sudah tersimpan di aplikasi bank. Uangnya benar-benar pindah, tetapi tidak lewat jalur yang bisa dicocokkan, dan alasannya dijelaskan pada artikel Virtual Account dan transfer biasa.
- Uangnya memang tidak pernah keluar. Ini kemungkinan terakhir yang diperiksa, bukan yang pertama, dan yang membuatnya sulit adalah bahwa sebagian bukti transfer palsu memakai struk yang asli. Kalau pembeli justru melaporkan sebaliknya, yaitu pembayarannya ditolak, urutan pemeriksaannya berbeda dan ada di artikel pembayaran gagal di sisi pembeli.
Tidak satu pun dari kelimanya diselesaikan oleh tangkapan layar. Yang menyelesaikannya adalah menerbitkan tautan baru dengan Idempotency-Key yang baru, lalu menunggu status berubah sendiri.
Kemungkinan kedua: Kasera Pay sudah succeeded, sistem toko belum
Kalau status di halaman Transaksi sudah succeeded sementara pesanan di sistem toko masih tertulis belum bayar, yang tidak sampai adalah pemberitahuannya, bukan uangnya. Kasera Pay mengirim satu jenis peristiwa, yaitu payment.paid, dan mengulang pengirimannya dengan jeda menaik sampai 7 percobaan dalam kurang lebih 33 jam selama jawabannya bukan 2xx.
Yang layak diperiksa, berurutan:
- Alamatnya terjangkau dari luar. URL webhook wajib
httpsdan mengarah ke alamat publik. Alamat pengembangan yang sudah mati, atau endpoint di balik daftar izin IP, tidak pernah menerima apa pun. - Jawaban endpoint-nya. Apa pun selain 2xx dihitung belum diterima dan tetap dalam antrean percobaan. Sebaliknya, endpoint yang menjawab 200 padahal pemrosesannya gagal membuang satu-satunya pemberitahuan yang akan pernah datang, karena antreannya dianggap selesai.
- Kedaluwarsa tidak pernah dikirim. Hanya
payment.paidyang ada. Kalau yang ditunggu adalah kabar bahwa sebuah tagihan hangus, kabar itu tidak akan datang, dan pelepasan stok harus dijalankan sendiri dariexpires_at.
Selama perbaikannya berjalan, sumber kebenaran yang bisa dipakai hari itu juga adalah GET /v1/transactions/:id. Aturan penanganan webhook selengkapnya ada pada referensi webhook dan pada artikel webhook pembayaran yang aman.
Kemungkinan ketiga: sudah succeeded, uangnya belum di rekening
Ini yang paling sering disalahartikan sebagai kegagalan, padahal berjalan normal. Halaman Transaksi punya dua kolom, bukan satu: kolom Status menjawab apakah pembayar sudah membayar, dan kolom Dana cair menjawab apakah banknya sudah menyerahkan uangnya. Keduanya boleh berbeda, dan memang sering berbeda.
Sebuah pembayaran succeeded yang kolom Dana cair-nya masih Diproses berarti pembayarannya pasti, tetapi dananya baru siap dicairkan pada hari kerja berikutnya. Penjualan Jumat malam, Sabtu, dan Minggu baru siap Senin, dan hari libur nasional menggesernya lagi. Di atas itu masih ada jadwal pencairan yang dipilih sendiri dan biaya Rp 3.000 per pencairan. Urutan lengkapnya ada pada panduan pencairan dana.
Konsekuensi praktisnya: pertanyaan “kenapa uangnya belum ada di rekening” yang diajukan Sabtu siang atas pembayaran Sabtu pagi tidak punya masalah untuk diperbaiki.
Yang dibalas ke pembeli
Ketiga kemungkinan di atas menghasilkan tiga balasan yang berbeda, dan hanya kemungkinan pertama yang melibatkan pembeli sama sekali. Untuk kemungkinan pertama, balasan yang bekerja menyebut apa yang terjadi tanpa menuduh, dan langsung memberi jalan keluarnya:
Terima kasih sudah konfirmasi. Pembayaran untuk pesanan ORD-1042 tercatat kedaluwarsa jam 14.00, jadi pembayaran setelah jam itu tidak masuk ke tagihan tersebut. Berikut tautan baru untuk pesanan yang sama, berlaku 2 jam: https://pay.kasera.id/p/... Statusnya berubah otomatis begitu pembayaran diterima, jadi tidak perlu mengirim bukti transfer.
Kalimat terakhir yang menghentikan tangkapan layar berikutnya. Untuk kemungkinan kedua dan ketiga, pembeli cukup diberi tahu bahwa pembayarannya sudah diterima, karena memang sudah, dan sisanya urusan internal.
Kenapa bukti transfer tidak pernah menutup persoalan ini
Bukti transfer menjawab pertanyaan yang salah. Pertanyaannya bukan “apakah pembeli mengirim uang”, melainkan “apakah pesanan ini sudah dibayar”, dan sebuah struk tidak bisa menjawab yang kedua: struk yang asli sekalipun bisa berasal dari transfer ke rekening lain, dari pesanan lain, atau dari nominal lain. Enam bentuk yang benar-benar dipakai, tiga di antaranya memakai struk asli, dibahas pada artikel bukti transfer palsu.
Mengurangi kejadiannya
Tiga kebiasaan menutup sebagian besar kasus ini sebelum sempat menjadi percakapan. Pertama, masa berlaku tautan disesuaikan dengan lama pembeli biasanya membayar, bukan diperpanjang asal aman. Kedua, setiap pembuatan tagihan memakai Idempotency-Key, sehingga satu pesanan tidak pernah punya dua tautan hidup. Ketiga, pembukuan ditutup setiap hari, bukan setiap akhir bulan, karena selisih yang ditemukan hari itu masih bisa ditelusuri ke satu pesanan, dan urutan penutupannya ada pada panduan rekonsiliasi harian toko online.