Langsung ke konten
Berita & Update
November 3, 2026 17

Cara Mencegah Transaksi Ganda di Aplikasi Buatan AI

Tombol Simpan sudah dinonaktifkan, tetapi transaksi masih bisa tercatat dua kali. Pahami penyebabnya, lalu gunakan contoh prompt dan skenario uji untuk memeriksa perlindungan di server.

Cara Mencegah Transaksi Ganda di Aplikasi Buatan AI

Dokumentasi Stripe menjelaskan bahwa permintaan ke API pembayaran bisa diulang dengan aman menggunakan kunci idempotensi. Tujuannya sederhana: ketika koneksi bermasalah, percobaan ulang tidak membuat operasi yang sama dijalankan lagi. Masalah ini juga perlu kamu pikirkan saat membuat aplikasi kasir, pencatat pembayaran, atau pemesanan dengan AI.

Bayangkan contoh berikut. Kasir menekan tombol Bayar, lalu layar terus menampilkan indikator proses. Kasir mencoba lagi karena belum melihat hasilnya. Ternyata permintaan pertama sudah berhasil, hanya balasannya yang terlambat sampai. Jika aplikasi memperlakukan percobaan kedua sebagai transaksi baru, penjualan dan pengurangan stok bisa tercatat dua kali.

Meminta AI menonaktifkan tombol setelah diklik merupakan awal yang masuk akal. Namun, perlindungan transaksi perlu bekerja juga ketika permintaan sudah meninggalkan browser.

1. Bedakan transaksi yang diulang dari transaksi baru

Idempotensi berarti pengulangan operasi yang sama tidak menambah efek baru setelah operasi itu berhasil. Untuk pencatatan penjualan, hasil yang kamu inginkan adalah satu transaksi dan satu kali pengurangan stok, meskipun aplikasi mengirim ulang permintaannya.

Menurut dokumentasi Stripe, percobaan ulang atas operasi yang sama perlu memakai kunci idempotensi yang sama dan parameter yang sesuai. Membuat kunci baru pada setiap percobaan justru membuat server kehilangan penanda bahwa permintaan tersebut merupakan pengulangan.

Dalam aplikasi buatanmu, bayangkan kunci ini sebagai nomor percobaan penyimpanan. Aplikasi membuatnya untuk satu operasi, mempertahankannya saat mengulang operasi tersebut, lalu memakai kunci berbeda untuk transaksi berikutnya.

Jangan menentukan duplikasi hanya dari nominal, nama pelanggan, atau jarak waktu. Sebagai contoh hipotetis, dua pembeli bisa sama-sama membeli kopi seharga Rp20.000 dalam satu menit. Keduanya tetap transaksi sah. Sebaliknya, satu penjualan yang dikirim ulang karena koneksi putus harus dikenali sebagai operasi yang sama.

Jika pengguna mengubah isi transaksi setelah kegagalan, aplikasi juga perlu aturan yang jelas. Jangan menggunakan kembali kunci lama untuk isi yang berbeda secara diam-diam. Stripe, misalnya, membandingkan parameter dan menolak penggunaan kunci yang sama dengan parameter berbeda.

2. Lindungi pencatatan di server, bukan hanya tombol

Tombol yang dinonaktifkan dan indikator proses membantu pengguna memahami bahwa aplikasi sedang bekerja. Keduanya tetap perlu dibuat. Namun, dua permintaan dapat tiba hampir bersamaan, atau permintaan lama dikirim ulang setelah koneksi terganggu.

Dokumentasi PostgreSQL menjelaskan bahwa aturan unique constraint menjaga keunikan nilai suatu kolom atau gabungan kolom. Prinsip ini bisa diterapkan pada identitas operasi agar database menolak pencatatan ganda. Kuncinya juga harus wajib terisi, sebab aturan unik secara bawaan masih dapat mengizinkan beberapa nilai kosong atau NULL.

Karena itu, jangan berhenti pada pola memeriksa apakah transaksi sudah ada, lalu menyimpannya jika belum ada. Saat permintaan datang bersamaan, keduanya bisa sama-sama melewati pemeriksaan awal. Minta AI memakai pengaman keunikan di database dan menangani benturan tersebut dengan benar.

Perubahan yang saling bergantung juga perlu disimpan bersama. Menurut tutorial transaksi PostgreSQL, transaksi database memungkinkan beberapa perubahan diperlakukan sebagai satu kesatuan: semuanya berhasil, atau semuanya dibatalkan. Untuk aplikasi kasir, penerapannya dapat mencakup pencatatan penjualan, detail barang, perubahan stok, dan hasil pemrosesan kunci operasi.

Transaksi database tidak otomatis menyelesaikan semua masalah akses bersamaan. Pemeriksaan dan pengurangan stok tetap perlu dirancang agar tidak saling menimpa. Hasil transaksi lama juga hanya boleh diberikan kepada pengguna yang berhak mengaksesnya.

Jika aplikasi terhubung ke layanan pembayaran, ada jalur lain yang perlu diperiksa: webhook, yaitu pemberitahuan dari layanan tersebut ke server aplikasimu. Stripe menyatakan bahwa event yang sama dapat dikirim lebih dari sekali. Server perlu memverifikasi tanda tangannya, lalu memastikan pemberitahuan yang sudah berhasil diproses tidak mengubah saldo, stok, atau status pesanan lagi.

Verifikasi tanda tangan membuktikan keaslian pemberitahuan, bukan bahwa pemberitahuan itu belum pernah diproses. Ikuti mekanisme deduplikasi resmi penyedia pembayaran yang kamu gunakan. Perilaku Stripe tidak boleh langsung diasumsikan sama untuk semua penyedia.

3. Contoh prompt agar AI memperbaiki akar masalahnya

Prompt seperti “jangan sampai transaksi dobel” masih menyisakan banyak keputusan. Jelaskan transaksi yang dilindungi, kondisi pengulangannya, dan hasil yang harus tetap konsisten. Pendekatan ini melanjutkan pembahasan tentang tujuan, konteks, dan cara mengecek hasil dalam prompt.

Berikut contoh prompt untuk pencatatan penjualan internal. Sesuaikan nama fitur dan aturan bisnisnya sebelum digunakan.

Periksa alur penyimpanan penjualan pada aplikasi ini. Telusuri tombol Bayar, endpoint server, tabel penjualan, detail barang, dan perubahan stok sebelum mengubah kode. Jelaskan penyebab transaksi yang sama dapat diproses lebih dari sekali.

Perbaiki agar satu operasi penyimpanan yang dikirim ulang hanya menghasilkan satu penjualan dan satu kali pengurangan stok. Gunakan identitas operasi yang tetap sama saat retry, wajib terisi, dan ditegakkan unik oleh database sesuai cakupan pengguna atau toko. Jangan mengenali duplikasi hanya dari nominal, pelanggan, atau waktu.

Pastikan pencatatan penjualan, detail barang, pengurangan stok, dan penanda operasi berhasil tersimpan secara atomik. Tangani dua permintaan bersamaan dengan aman. Permintaan ulang setelah berhasil harus mengembalikan hasil transaksi yang sama kepada pengguna yang berhak, tanpa mengulangi efeknya. Jika masih diproses, tampilkan status yang jelas. Tolak kunci yang sama dengan isi berbeda.

Tetap nonaktifkan tombol selama proses dan tampilkan umpan balik. Jika respons terputus, jangan langsung menyatakan transaksi gagal atau membuat transaksi baru. Sediakan cara mengecek hasil operasi sebelumnya. Setelah selesai, jalankan pengujian klik berulang, permintaan bersamaan, respons terputus setelah penyimpanan berhasil, kegagalan di tengah penyimpanan, dan dua transaksi sah dengan isi sama tetapi identitas berbeda. Laporkan pengujian yang benar-benar dijalankan beserta hasilnya, serta yang belum bisa diuji.

Untuk aplikasi dengan pembayaran eksternal, tambahkan instruksi berikut:

Periksa juga pembuatan pembayaran dan penerimaan webhook berdasarkan dokumentasi resmi penyedia. Gunakan mekanisme idempotensi yang didukung, verifikasi keaslian webhook, dan cegah efek berulang dari pemberitahuan duplikat. Jika status pembayaran belum jelas akibat timeout, cek status operasi yang sama sebelum mencoba pembayaran baru. Gunakan lingkungan uji, bukan uang sungguhan. Jelaskan cara menangani pembayaran yang berhasil ketika pencatatan database lokal gagal.

Bagian terakhir penting. Pembatalan transaksi database lokal tidak otomatis membatalkan pembayaran yang sudah berhasil di sistem lain. Aplikasi perlu mencocokkan status keduanya dan menyediakan penanganan ketika hasilnya berbeda.

4. Uji hasilnya dengan skenario yang bisa diperiksa

Jangan menerima perubahan hanya karena tombol kini menampilkan tulisan Memproses. Minta AI menunjukkan hasil uji pada data pengujian. Untuk aplikasi seperti contoh aplikasi kasir, periksa daftar penjualan, detail barang, dan stok setelah setiap skenario.

  • Klik Bayar berulang saat proses masih berjalan. Hanya satu penjualan boleh terbentuk untuk operasi tersebut.
  • Kirim dua permintaan dengan identitas operasi yang sama secara bersamaan. Efek penjualan dan stok tetap terjadi sekali. Pengujian ini perlu dilakukan pada endpoint, bukan hanya lewat tombol.
  • Simulasikan respons terputus setelah server berhasil menyimpan. Saat mencoba ulang dengan identitas yang sama, aplikasi menemukan hasil sebelumnya tanpa membuat penjualan baru.
  • Simulasikan kegagalan di tengah penyimpanan. Jangan sampai penjualan tersimpan sebagian atau stok berkurang tanpa penjualan yang lengkap.
  • Buat dua penjualan sah dengan isi dan nominal yang sama, tetapi identitas operasi berbeda. Keduanya harus tetap dapat diproses.
  • Gunakan identitas operasi yang sama dengan isi berbeda. Server harus menolaknya dengan pesan yang jelas.
  • Jika ada pembayaran eksternal, kirim ulang webhook pada lingkungan uji. Saldo, stok, dan status pesanan tidak boleh menerima efek tambahan. Webhook dengan tanda tangan tidak valid juga harus ditolak.

Daftar ini adalah sasaran pengujian, bukan klaim bahwa aplikasi tertentu sudah lulus. Bila AI tidak dapat mensimulasikan permintaan bersamaan atau kegagalan jaringan, minta AI menyebutkan batasnya secara terbuka.

Sebelum memakai aplikasi untuk transaksi sungguhan, kamu perlu bukti bahwa pengulangan satu operasi tidak menambah efek, sementara dua transaksi sah tetap bisa diproses. Tampilan yang rapi belum menjawab kedua pertanyaan itu.

Sumber

Artikel Terkait

Mau bikin aplikasi seperti ini?

Ceritakan kebutuhanmu satu prompt — AI TanpaNgoding membangun aplikasi web lengkap dengan admin panel, database, dan siap publish.