Blog · Terbit
Menagih ulang pembeli yang tautannya kedaluwarsa: nomor Virtual Account lama yang masih bisa dibayar berjam-jam kemudian, satu pintu yang hanya bisa ditutup sebelum jamnya habis, dan slot jatah yang tidak pernah kembali
Menerbitkan ulang bukan memperpanjang. Tagihan pengganti adalah permintaan pembayaran yang benar-benar baru: id baru, kode QR atau nomor Virtual Account baru, dan penghitung waktu yang mulai dari nol. Tidak ada operasi yang menghidupkan kembali tautan yang sudah mati, dan masa berlaku hanya bisa ditentukan pada saat tagihan dibuat.
Yang membuat urutannya penting bukan itu, melainkan satu hal yang jarang disadari sampai uangnya datang dua kali: tagihan yang sudah kedaluwarsa masih bisa berubah menjadi berhasil, dan pada titik itu ia sudah tidak bisa lagi dibatalkan. Jadi keputusan yang sesungguhnya bukan cara menerbitkan ulang, melainkan kapan.
Urutannya lebih dulu, alasannya sesudah
- Periksa status tagihan lamanya sebelum menyentuh apa pun. Yang menentukan langkah berikutnya hanya satu hal: masih
pending, atau sudahexpired. - Kalau masih menunggu dan nomornya sudah beredar di chat, batalkan lebih dulu, baru terbitkan penggantinya. Ini satu-satunya kesempatan menutup pintu yang dibahas di bawah.
- Kalau sudah kedaluwarsa, terbitkan penggantinya dan catat di sistem sendiri bahwa satu pesanan kini punya dua baris yang keduanya masih mungkin berakhir berhasil.
- Kirim tautan penggantinya dengan satu kalimat yang menyatakan nomor lama tidak berlaku. Tanpa kalimat itu, pembeli yang membuka chat dari atas akan membayar nomor yang pertama ditemukan.
Pintu yang hanya dimiliki tagihan kedaluwarsa
Status akhir biasanya berarti selesai. Ada satu pengecualian, dan pengecualian itulah yang membuat penagihan ulang berisiko: pembayaran yang sebenarnya sudah diterima sesaat sebelum penghitung berhenti, lalu konfirmasinya baru sampai setelahnya, tetap memindahkan tagihan dari expired menjadi succeeded. Uang menang atas jam, karena memberi tahu penjual bahwa dirinya tidak dibayar padahal uangnya sudah masuk adalah kesalahan yang jauh lebih mahal daripada menutup tagihan terlambat.
Satu hal lain memperpanjang jarak buta itu. Kedaluwarsa tidak dikabarkan lewat webhook sama sekali: satu-satunya event yang dikirim adalah payment.paid saat pembayaran terkonfirmasi, dan tidak ada event apa pun yang menandai tagihan yang mati. Sistem penjual hanya bisa mengetahuinya dari expires_at yang sudah dipegang sejak tagihan dibuat. Pemilihan masa berlakunya sendiri dibahas terpisah di tulisan tentang masa berlaku tagihan.
Membatalkan hanya bisa sebelum jamnya habis
Tagihan yang dibatalkan tidak punya pintu itu. Begitu statusnya canceled, tidak ada peristiwa apa pun yang mengubahnya, termasuk uang yang benar-benar datang. Itu yang membuat pembatalan terlihat seperti jawaban untuk nomor lama yang beredar.
Masalahnya, pembatalan punya syarat waktu yang tidak bisa ditawar: hanya permintaan yang masih menunggu yang bisa dibatalkan. Permintaan pembatalan atas tagihan yang sudah kedaluwarsa dijawab 409 not_cancelable, dan itu bukan galat sementara yang perlu dicoba ulang. Konsekuensinya satu kalimat: pintu kedaluwarsa menjadi berhasil hanya bisa ditutup sebelum tagihannya kedaluwarsa, tidak pernah sesudahnya. Perbandingan lengkap kedua jalur mengakhiri tagihan ada di tulisan tentang membatalkan tagihan.
Dari situ turun aturan praktis yang berlawanan dengan dugaan pertama. Penjual yang tahu pembeli sudah tidak akan membayar, dan tahu nomornya sudah beredar, sebaiknya membatalkan lebih awal alih-alih menunggu jam enam puluh menit berjalan sampai habis. Menunggu bukan sikap netral: menunggu adalah memilih membiarkan pintunya terbuka.
Satu pesanan, dua baris, dan pembukuan yang tetap masuk akal
Setelah penerbitan ulang, satu pesanan diwakili dua permintaan pembayaran. Keduanya nyata, keduanya punya id sendiri, dan keduanya muncul di daftar transaksi. external_id dan merchant_ref membantu mencocokkan keduanya ke pesanan yang sama, tetapi keduanya label: label tidak menjamin keunikan dan tidak pernah menggabungkan dua permintaan menjadi satu pembayaran. Kebiasaan penamaan yang menyelamatkan rekonsiliasi adalah menuliskan percobaannya, misalnya ORD-1042-2 untuk penerbitan kedua, sehingga dua baris yang berdekatan bisa dibaca tanpa membuka keduanya.
Kalau keduanya benar-benar berakhir succeeded, yang terjadi bukan kesalahan sistem melainkan pembeli yang membayar dua kali, dan penyelesaiannya keputusan manusia: mengembalikan salah satunya atau menyimpannya sebagai saldo untuk pesanan berikutnya. Bentuk kejadiannya dibahas di tulisan tentang pembayaran yang masuk dua kali.
Kunci idempotency wajib baru, justru supaya tidak berlipat
Header Idempotency-Key adalah satu-satunya hal yang membuat dua permintaan create dianggap satu pembayaran, dan kuncinya disimpan permanen. Mengirim penerbitan ulang dengan kunci lama dan isi yang sama tidak menghasilkan tagihan baru: yang dijawab adalah tagihan lama yang statusnya sudah kedaluwarsa, sehingga yang sampai ke pembeli adalah tautan yang langsung mati. Karena itu kunci penerbitan ulang wajib baru, dan bentuk yang aman adalah menurunkannya dari percobaan penerbitan, bukan dari nomor pesanan. Pembahasan kuncinya, termasuk bentuk yang justru membuka celah tagihan ganda, ada di tulisan tentang Idempotency-Key.
Jatah sebelum verifikasi: satu slot hangus, satu bagian kembali
Pada akun yang verifikasinya belum selesai, penerbitan ulang punya harga yang tidak terlihat di mana pun pada layar penjualan. Jatah sebelum verifikasi berlaku seumur akun dan tidak pernah reset, dan dua komponennya berperilaku berlawanan atas tagihan yang sama:
- Jumlah permintaan, bawaan 10. Yang dihitung adalah setiap permintaan yang pernah dibuat kecuali yang
canceled. Yang kedaluwarsa dan yang gagal tetap dihitung. Satu tagihan yang dibiarkan mati lalu diterbitkan ulang berarti dua slot terpakai untuk satu pesanan, dan slot yang pertama tidak pernah kembali. Melewatinya dijawab429 unverified_count_cap. - Total nominal, bawaan Rp 1.000.000. Yang dihitung hanya uang yang diterima atau masih mungkin diterima. Tagihan yang kedaluwarsa, gagal, atau dibatalkan melepaskan kembali bagiannya, jadi nominal tagihan mati tidak menumpuk. Melewatinya dijawab
429 unverified_amount_cap.
Gabungan keduanya memberi alasan kedua untuk membatalkan lebih awal, dan kali ini alasan yang bisa dihitung: pada akun baru, membatalkan sebelum jamnya habis adalah satu-satunya cara mengembalikan slot jumlahnya. Sepuluh slot habis lebih cepat dari dugaan siapa pun yang menagih ulang dua atau tiga kali per pembeli. Angka dan semantik penghitungannya ada di referensi batas API.
Kapan berhenti menerbitkan ulang
Pembeli yang sama melewatkan tenggat dua kali bukan pembeli yang lalai, melainkan tanda bahwa bentuk tagihannya salah untuk cara jualannya. Dua jalan keluar menghapus siklus penagihan ulang alih-alih mempercepatnya.
Yang pertama, meminta masa berlaku yang lebih panjang saat tagihan dibuat. Bawaannya 60 menit dan plafonnya 24 jam, dan angka yang lebih panjang masuk akal persis pada kasus yang paling sering kedaluwarsa: nomor Virtual Account yang dibayar di mesin ATM atau esok paginya, bukan saat itu juga.
Yang kedua, berhenti memakai tautan yang punya tenggat. Pada halaman pembayaran yang dipakai berulang, penghitung waktu baru mulai berjalan ketika pembeli menekan bayar, bukan ketika penjual membuat tagihannya, sehingga kedaluwarsa sebelum dibaca tidak lagi mungkin. Cara menyiapkannya ada di panduan halaman pembayaran yang dipakai berulang. Yang hilang darinya adalah nominal yang dikunci per pesanan, jadi ini pertukaran, bukan peningkatan.
Ringkasnya
- Menerbitkan ulang selalu berarti tagihan baru dengan id, nomor, dan jam sendiri.
- Tagihan kedaluwarsa masih bisa menjadi berhasil karena konfirmasi terlambat; tagihan yang dibatalkan tidak akan pernah, dan membatalkan hanya diterima selama status masih
pending. - Penerbitan ulang wajib memakai Idempotency-Key baru, diturunkan dari percobaannya.
- Pada akun belum terverifikasi, tagihan kedaluwarsa menghabiskan satu slot selamanya sementara bagian nominalnya kembali.
- Dua kali kedaluwarsa pada pembeli yang sama berarti bentuk tagihannya yang diganti.
Pertanyaan yang sering muncul
Apakah masa berlaku tagihan yang sudah lewat bisa diperpanjang?
Tidak. Tidak ada operasi yang memperpanjang permintaan pembayaran yang sudah kedaluwarsa, dan tidak ada yang menghidupkannya kembali. Yang tersedia hanya menerbitkan permintaan pembayaran baru, yang membawa id, kode QR atau nomor Virtual Account, dan penghitung waktunya sendiri. Masa berlaku hanya bisa ditentukan saat tagihan dibuat, dengan bawaan 60 menit dan plafon 24 jam.
Pembeli sudah menerima nomor Virtual Account yang lama lewat chat. Apakah nomor itu masih bisa dibayar?
Selama tagihan lamanya masih menunggu, tentu saja. Setelah kedaluwarsa, nomor itu tidak lagi menerima pembayaran baru, tetapi ada satu keadaan yang tetap berakibat uang: pembayaran yang sebenarnya sudah masuk sesaat sebelum penghitung berhenti dan konfirmasinya baru tiba sesudahnya tetap memindahkan tagihan lama menjadi succeeded. Karena itu tagihan pengganti dan tagihan lama sebaiknya dianggap dua baris yang keduanya masih mungkin berakhir berhasil sampai hari itu ditutup.
Kenapa membatalkan tagihan lama ditolak dengan 409 not_cancelable?
Karena hanya permintaan yang masih menunggu yang bisa dibatalkan. Begitu statusnya berpindah menjadi expired, pembatalan tidak lagi diterima, dan itu bukan galat yang perlu dicoba ulang. Akibatnya satu keputusan waktu: membatalkan adalah tindakan yang hanya tersedia sebelum jamnya habis, bukan setelahnya.
Apakah menerbitkan ulang memakai jatah akun yang belum terverifikasi?
Ya, dan dua jatah yang ada berperilaku berlawanan atas tagihan yang sama. Jatah jumlah permintaan seumur akun menghitung setiap permintaan yang pernah dibuat kecuali yang canceled, sehingga tagihan yang dibiarkan kedaluwarsa memakai satu slot selamanya. Jatah nominalnya hanya menghitung uang yang diterima atau masih mungkin diterima, sehingga tagihan yang kedaluwarsa melepaskan kembali bagiannya. Membatalkan sebelum jamnya habis adalah satu-satunya cara mengembalikan slot jumlahnya.
Boleh memakai Idempotency-Key yang sama supaya tagihannya tidak berlipat?
Justru sebaliknya. Kunci yang sama dengan isi permintaan yang sama menjawab tagihan yang lama, yang statusnya sudah kedaluwarsa, sehingga yang terkirim ke pembeli adalah tautan mati. Kunci diturunkan dari percobaan penerbitan, bukan dari nomor pesanan, misalnya nomor pesanan digabung nomor urut penerbitannya.