Blog · 6 September 2026
Pindah dari payment gateway lain tanpa menghentikan penjualan: urutan yang tidak butuh jadwal malam
Migrasi payment gateway tidak perlu jadwal pergantian pada satu malam tertentu, dan sebagian besar rencana migrasi yang gagal justru gagal karena dijadwalkan seperti itu. Alasannya sederhana: sebuah permintaan pembayaran adalah objek per pesanan, bukan setelan global. Tidak ada saklar yang harus dibalik serentak. Pesanan nomor 1041 boleh selesai di gateway lama sementara pesanan 1042 sudah terbit di gateway baru, pada menit yang sama, tanpa satu pun pembeli mengetahui ada yang berpindah.
Artinya batas migrasi adalah pesanan, bukan jam. Yang perlu disusun bukan jadwal pemadaman, melainkan urutan: apa yang boleh berjalan berdampingan, apa yang harus selesai lebih dulu, dan apa yang memang tidak ikut pindah sama sekali.
Empat hal berpindah, dan hanya satu di antaranya berupa kode
Membaca migrasi sebagai satu pekerjaan adalah sumber kekacauan pertama. Yang berpindah ada empat, dan keempatnya punya sifat yang berbeda.
Pembuatan pembayaran. Panggilan dari server ke penyedia untuk menerbitkan satu pembayaran. Ini satu-satunya bagian yang benar-benar berupa kode, dan bagian yang paling mudah dari keempatnya.
Halaman yang dilihat pembeli. Berubah tampilannya, dan pada pesanan yang sedang berjalan tidak boleh berubah di tengah jalan. Tautan yang sudah dikirim ke pembeli harus tetap hidup sampai kedaluwarsa.
Notifikasi pembayaran. Webhook. Bagian yang paling sering dianggap pergantian tunggal, padahal justru bagian yang paling aman dijalankan ganda.
Jalur uangnya. Bagian yang sama sekali tidak punya masa tumpang tindih. Pembayaran yang masuk lewat gateway lama dicairkan lewat gateway lama, selamanya. Saldo di sana harus habis sebelum akunnya ditutup, dan itu pekerjaan minggu terakhir, bukan minggu pertama.
Langkah 1: gladi bersih di mode tes, sebelum satu pesanan pun dialihkan
Di Kasera Pay, mode tes berjalan di samping mode live memakai key yang berbeda: key live berawalan kp_live_ dan key tes berawalan kp_test_. Tidak ada lingkungan terpisah yang perlu disiapkan dan tidak ada URL berbeda yang perlu dihafal, jadi integrasi bisa ditulis penuh sebelum ada satu rupiah pun yang bergerak. Pembayaran tes bisa dijadikan berhasil atau kedaluwarsa lewat endpoint simulasi, yang berarti dua jalur yang paling sering terlewat, yaitu pembayaran yang tidak jadi dibayar dan tautan yang habis masa berlakunya, bisa dijalankan berkali-kali tanpa menunggu.
Endpoint webhook juga terpisah per mode dan masing-masing punya signing secret sendiri, jadi handler baru bisa diuji sampai benar tanpa menyentuh apa pun yang sedang melayani pembeli sungguhan. Rinciannya ada di dokumentasi mode tes.
Langkah 2: satu lapis adaptor, dua implementasi
Sebelum menulis panggilan pertama, pisahkan dulu pembuatan pembayaran menjadi satu antarmuka kecil di dalam kode: satu fungsi yang menerima pesanan dan mengembalikan tautan pembayaran, dan satu fungsi yang menerima notifikasi lalu menandai pesanan lunas. Gateway lama menjadi implementasi pertama, gateway baru implementasi kedua, dan pilihan di antara keduanya menjadi satu baris konfigurasi.
Tanpa lapis ini, migrasi berubah menjadi pencarian nama penyedia di seluruh kode, dan bagian yang tertinggal biasanya bukan halaman checkout melainkan tempat-tempat kecil: email konfirmasi, halaman status pesanan, skrip pengingat, laporan admin. Dengan lapis ini, pengalihan sebagian pesanan pada langkah 4 menjadi mungkin sama sekali.
Bentuk permintaan pembuatan pembayaran di sisi Kasera Pay seperti ini:
curl https://pay.kasera.id/v1/transactions \
-H "Authorization: Bearer kp_live_..." \
-H "Idempotency-Key: ORD-1042-create" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"description": "Kaos komunitas",
"external_id": "ORD-1042",
"payment_methods": ["qris", "va_bca"]
}'Tiga hal yang biasanya perlu dipetakan dari istilah gateway lama. Pertama, pilihan metode: di banyak penyedia namanya channel pembayaran, dan di sini bentuknya array kode pada payment_methods, satu kode berarti langsung ke metode itu dan beberapa kode berarti pembeli memilih. Kedua, nomor pesanan: tempatnya external_id, yang disimpan, dikembalikan, dan bisa difilter di endpoint daftar. Ketiga, tanda tangan notifikasi: header Kasera-Signature-V1, berisi timestamp dan HMAC SHA-256 atas timestamp beserta body mentah. Daftar field lengkapnya ada di dokumentasi membuat permintaan pembayaran.
Langkah 3: dua webhook hidup bersamaan
Ini langkah yang paling sering ditakuti tanpa alasan. Handler webhook lama tidak perlu dimatikan untuk memasang yang baru, karena keduanya adalah URL yang berbeda dan penyedia yang berbeda mengirim ke URL masing-masing. Selama masa tumpang tindih, kedua handler hidup, dan setiap pembayaran hanya membangunkan salah satunya.
Dua detail memudahkan urutan pemasangannya. Endpoint webhook bisa ditambahkan tanpa URL lebih dulu, hanya untuk mendapatkan signing secret-nya, sehingga handler bisa dibangun dan dirilis sebelum ada alamat yang menunggu. Dan memindahkan URL sebuah endpoint ke domain baru tidak mengganti secret-nya, jadi perpindahan domain tidak menuntut rilis ulang kode verifikasi. Tersedia sampai lima endpoint per mode, masing-masing dengan URL, nama, dan secret sendiri, jadi toko dan sistem gudang bisa menerima salinannya sendiri-sendiri.
Tiga hal yang wajib benar sejak pengiriman pertama: tanda tangan diverifikasi atas body mentah sebelum payload dipakai, jawaban 2xx hanya diberikan setelah pemrosesan benar-benar berhasil, dan URL webhook tidak boleh berupa pengalihan. Percobaan ulang berjalan sampai tujuh kali dalam sekitar 33 jam, dan tombol “Kirim event percobaan” di dashboard membuktikan endpoint bisa dijangkau sebelum ada pembayaran sungguhan yang bergantung padanya. Kesalahan handler yang paling mahal dibahas di tulisan tentang webhook yang aman.
Langkah 4: alihkan sebagian pesanan lebih dulu
Pengalihan pertama sebaiknya bukan seluruh toko, melainkan potongan yang bisa diawasi satu per satu: satu produk, satu kanal penjualan, atau pesanan dari staf sendiri. Potongan itu menghasilkan pembayaran sungguhan dengan uang sungguhan, yang merupakan satu-satunya cara menguji rantai terakhir, yaitu pencairan ke rekening bank.
Kecepatan menaikkan porsi ditentukan oleh batas harian, bukan oleh kesiapan kode. Secara bawaan sebuah akun boleh membuat 100 permintaan pembayaran per hari dengan total nominal Rp 50.000.000 per hari, dan yang dihitung adalah permintaan yang dibuat, bukan yang dibayar. Toko yang menerbitkan lebih dari 100 pesanan sehari perlu mengurus kenaikan batas sebelum porsinya dinaikkan, bukan sesudah pembeli menemukan penolakan. Arti kedua angka itu dan cara meminta kenaikannya ada di tulisan tentang batas harian dan cara menaikkannya. Batas lain yang perlu dicocokkan lebih dulu: nominal per pembayaran berkisar Rp 10.000 sampai Rp 10.000.000, sehingga pesanan besar yang biasa lewat di gateway lama perlu dipecah atau dibicarakan sebelum dialihkan.
Nomor pesanan harus sama di kedua sisi, dan di sinilah tagihan ganda lahir
Selama masa tumpang tindih ada dua sistem yang bisa menerbitkan pembayaran untuk satu nomor pesanan yang sama. Itu bukan masalah selama nomor pesanan dikirim ke kedua sisi apa adanya, sehingga rekap mana pun bisa disatukan dengan satu kunci. Pada Kasera Pay tempatnya external_id, dengan merchant_ref maksimal 64 karakter untuk nomor internal kedua seperti nomor invoice.
Yang perlu diketahui dan sering disalahpahami: tidak satu pun dari kedua field itu mencegah duplikat. Dua create dengan external_id yang sama menghasilkan dua permintaan pembayaran, dan keduanya bisa dibayar. Satu-satunya yang mencegah duplikat adalah header Idempotency-Key. Migrasi adalah tempat paling subur bagi kesalahan ini, karena pekerjaan migrasi penuh dengan skrip yang dijalankan ulang, antrean yang diproses dua kali, dan penerbitan ulang tautan untuk pesanan yang sudah punya tautan. Kuncinya harus deterministik per pesanan, misalnya nomor pesanan ditambah keperluannya, bukan nilai acak baru pada setiap percobaan. Key acak per percobaan melewati perlindungan itu tanpa satu pun pesan galat, dan bentuk kegagalannya diuraikan di tulisan tentang idempotency pada pembayaran.
Yang memang tidak ikut pindah
Riwayat pembayaran. Tidak ada impor riwayat, dan tidak ada gunanya memaksakannya. Data lama dibaca dari dashboard lama, jadi ekspornya sebaiknya diunduh dan disimpan sebelum akun ditutup.
Pengembalian dana atas pembayaran lama. Dikerjakan di penyedia tempat uangnya masuk, memakai prosedur penyedia itu. Kewajiban itu tidak berpindah bersama integrasinya, dan jangka waktunya yang biasanya menentukan kapan akun lama boleh ditutup.
Instruksi pembayaran berulang. Kartu tersimpan atau token pelanggan tidak bisa dipindahkan antar penyedia, dan Kasera Pay memang tidak menyimpan instruksi debet berulang sama sekali. Penagihan langganan karena itu perlu disusun ulang sebagai penerbitan tagihan per periode, bukan dipindahkan apa adanya.
Saldo yang belum dicairkan. Cairkan sampai habis di penyedia lama sebelum menutup akun, dan periksa apakah ada ambang minimum pencairan yang menahan sisa kecil.
Urutan mematikan integrasi lama
Mematikan yang lama punya urutan sendiri, dan urutannya bukan kebalikan dari memasang yang baru. Pertama, hentikan pembuatan pembayaran baru di gateway lama, cukup lewat konfigurasi adaptor tadi. Kedua, biarkan handler lama tetap hidup sampai tautan terakhir yang pernah terbit melewati masa berlakunya, karena tautan yang beredar masih bisa dibayar dan notifikasinya masih akan datang. Ketiga, selesaikan kewajiban pengembalian dana yang masih mungkin muncul. Keempat, cairkan sisa saldo. Baru setelah itu akunnya ditutup dan kredensial lama dicabut.
Satu hal yang sebaiknya tidak dilakukan pada hari yang sama dengan pengalihan terakhir: menghapus URL webhook lama. Sebuah notifikasi bisa datang belakangan, dan menghapus alamatnya berarti membuang satu-satunya pemberitahuan yang akan pernah dikirim untuk pembayaran itu.
Rekonsiliasi selama masa tumpang tindih
Selama satu atau dua bulan, penjualan harian datang dari dua sumber, dan penjumlahan yang benar harus menyebut sumbernya masing-masing. Dua hal yang biasanya mengejutkan pada bulan pertama. Pertama, bentuk biayanya berbeda, jadi persentase biaya bulan berjalan bukan rata-rata sederhana dari keduanya: di sini biayanya MDR 0,7% yang diteruskan tanpa markup ditambah Rp 250 per transaksi berhasil, dengan biaya pencairan Rp 3.000 per pencairan. Kedua, ritme uang masuknya berbeda, sehingga satu baris mutasi bank pada bulan peralihan bisa berasal dari penyedia mana pun. Urutan menutup buku harian dengan dua sumber catatan mengikuti panduan yang sama seperti biasa, ada di panduan rekonsiliasi harian toko online.
Satu catatan istilah yang menghemat waktu saat memetakan status antar penyedia: di sini status sebuah permintaan pembayaran hanya ada tiga, yaitu pending, succeeded, dan expired. Kata “paid” bukan status, melainkan nama event webhook payment.paid. Pemetaan status yang keliru pada bulan peralihan menghasilkan pesanan yang dianggap lunas padahal tautannya baru terbit, dan itu jenis kesalahan yang baru ketahuan saat barang sudah dikirim.
Pertanyaan yang sering muncul
Apakah penjualan harus dihentikan saat pindah payment gateway?
Tidak. Sebuah permintaan pembayaran adalah objek per pesanan, bukan setelan global, jadi tidak ada saklar yang harus dibalik pada satu waktu tertentu. Pesanan yang sudah terbit di gateway lama tetap dibayar dan diselesaikan di sana, sedangkan pesanan baru mulai diterbitkan di gateway baru. Kedua integrasi berjalan berdampingan selama masa peralihan, dan yang berubah hanyalah pesanan mana yang diarahkan ke mana.
Bagaimana kalau pembeli membayar tautan lama setelah migrasi selesai?
Pembayaran itu tetap masuk ke gateway lama dan tetap sah, karena tautannya diterbitkan di sana. Karena itu integrasi lama tidak boleh dimatikan pada hari yang sama dengan create terakhir: tautan yang sudah beredar masih punya masa berlaku, dan handler lama masih harus bisa menerima notifikasinya sampai tautan terakhir kedaluwarsa. Yang dimatikan lebih dulu adalah pembuatan pembayaran baru, bukan penerimaannya.
Bisakah pembayaran lama dipindahkan ke gateway baru?
Tidak bisa, dan tidak perlu. Sebuah pembayaran yang sudah lunas melekat pada penyedia tempat uangnya masuk, termasuk pencairannya, pengembalian dananya, dan sengketa kartunya. Yang dipindahkan adalah alur pembuatan pembayaran ke depan. Riwayat lama tetap dibaca dari dashboard lama, jadi akun lama sebaiknya ditutup belakangan, bukan pada hari peralihan.
Berapa lama masa tumpang tindih yang wajar?
Ditentukan oleh tiga angka, bukan oleh selera: masa berlaku tautan terpanjang yang pernah diterbitkan, jangka waktu pengembalian dana yang dijanjikan ke pembeli, dan untuk pembayaran kartu, jangka sengketa yang bisa muncul berbulan-bulan kemudian. Masa berlaku tautan biasanya selesai dalam hitungan hari, sedangkan kewajiban pengembalian dana dan sengketa kartu yang menentukan kapan akun lama benar-benar bisa ditutup.