Figure 1. Dokumentasi error handling resmi Stripe
(https://d37ugbyn3rpeym.cloudfront.net/docs/og-image/error-low-level.ogimage.png)

Bayangkan kamu menekan tombol bayar, lalu sinyal internet hilang saat layar berputar. Koneksi pulih beberapa detik kemudian dan aplikasi mengulang proses otomatis. Tagihan berhasil dibuat, tetapi saldo di mobile banking terpotong dua kali untuk satu tiket yang sama. Server sudah selesai mengeksekusi permintaan pertama, sementara responsnya gagal sampai ke klien. Aplikasi menyangka pembayaran gagal lalu mengirim ulang permintaan sama; di celah ini idempotency bekerja seperti pada Figure 1.

Apa Itu Idempotency?

Kata idempotent berasal dari matematika: operasi yang diterapkan berkali-kali tidak lagi mengubah hasil. HTTP mengadopsinya lewat RFC 9110: metode request idempotent kalau efek beberapa request identik sama dengan efek satu request saja. Spesifikasi IETF ini terbit 2022 dan menjadi acuan resmi semantik HTTP modern. Idempotent tidak berarti bebas efek samping; server tetap boleh mencatat request di log. Respons tiap pengulangan boleh berbeda; yang konsisten hanya efek akhirnya.

Metode HTTP: Mana yang Aman Diulang?

Standar HTTP sudah memilah metode berdasarkan sifat idempotent sejak awal:

  • GET, HEAD, OPTIONS, TRACE: metode safe pembaca data, aman sekaligus idempotent.
  • PUT: idempotent karena mengganti resource dengan isi sama, berapa kali pun dikirim.
  • DELETE: idempotent karena pengulangannya tak menciptakan penghapusan kedua.
  • POST dan PATCH: tak masuk daftar metode idempotent RFC 9110; pengulangannya bisa mengulang efek sampingnya.

Idempotency Key: Pengaman Operasi POST

Masalah POST dijawab dengan penanda pengulangan. Klien membuat idempotency key, misalnya UUID v4, lalu mengirimnya di header Idempotency-Key pada permintaan pertama. Server menyimpan status code dan body respons pertama dengan key itu. Ketika key sama datang lagi, server mengembalikan respons tersimpan tanpa operasi ulang, seperti pada Figure 2. Header Idempotent-Replayed: true pada jawaban menandai replay bagi klien.

Figure 2. Diagram alur retry dengan idempotency key, ilustrasi penulis
(https://docs.stripe.com/api/idempotent_requests)

Aturan mainnya terperinci. Stripe menyimpan key minimal 24 jam, jadi pengulangan dengan key dan parameter sama sebaiknya dilakukan dalam 24 jam pertama. Key lama dengan parameter baru ditolak lewat error agar kekeliruan tak merambat. Permintaan dengan key yang masih diproses bisa menerima status 409; developer disarankan menunggu lalu mengulang dengan key sama. Setelah window berlalu tanpa kepastian hasil, Stripe mengarahkan ke rekonsiliasi Dashboard dan webhook.

Praktik Stripe: Konvensi yang Bisa Ditiru

Stripe menetapkan konvensi konkret untuk integrasinya. Key maksimal 255 karakter, sebaiknya V4 UUID atau string acak ber-entropy tinggi, tanpa data pribadi seperti email. SDK Stripe bisa membuat key dan mengulang request otomatis dengan exponential backoff agar server tak dibanjiri percobaan. GET dan DELETE sudah idempotent sejak desain sehingga tak butuh key; POST di API v1 menerima key. Key yang dipertahankan lintas percobaan membuat satu payment intent hanya membuat satu tagihan.

Idempotency dalam Sistem Pesan: Kasus Kafka

Pola serupa hidup di sistem pesan. Dokumentasi desain Apache Kafka membedah message delivery semantics, termasuk at most once dan at least once. Producer sebelum versi 0.11.0.0 yang gagal menerima konfirmasi hanya bisa mengirim ulang pesan, sehingga delivery berjalan at-least-once: pesan tak hilang tetapi boleh tiba ganda. Sejak 0.11.0.0 tersedia opsi idempotent delivery; broker mengenali producer lewat ID dan nomor urut, lalu membuang duplikat di log. Identitas pengirim dan pengenalan pengulangan bekerja seperti idempotency key pada payment API.

Perbandingan Praktis

Perbedaannya terasa saat implementasi tanpa key diadu dengan berkey:

Aspek Tanpa idempotency key Dengan idempotency key
Pengalaman pelanggan Saldo terpotong dua kali, keluhan berdatangan Pengulangan aman, saldo terpotong sekali
Duplikasi transaksi Satu niat beli menciptakan dua tagihan Respons pertama di-replay, tagihan tetap satu
Beban ops Log dicocokkan manual, refund diurus satu-satu Respons tersimpan per key, kasus ganda menyusut
Kepercayaan merchant Merchant ragu pada gateway yang salah menagih Retry otomatis layak dipasang, hasil prediktabel
Audit Jejak retry dan double submit campur aduk Key memetakan satu operasi dari awal ke akhir

Kelebihan dan Keterbatasan

Jaring pengaman ini murah dipasang, tetapi punya syarat. Key baru pada tiap percobaan justru membuka pintu tagihan kedua; key harus dipertahankan lintas retry dan restart proses. Server juga menanggung biaya penyimpanan respons beserta aturan pembersihannya. Window retensi terbatas, sehingga operasi yang belum jelas hasilnya butuh rekonsiliasi webhook. Idempotency juga bukan pengganti pengaman lain seperti unique constraint di database.

Kesimpulan

Idempotency mengubah pengulangan dari ancaman menjadi rutinitas terkendali. Definisinya sederhana, wujudnya satu header, dan dampaknya terlihat di tagihan pelanggan. HTTP menyediakan fondasinya; Stripe dan Kafka menunjukkan pola serupa di pembayaran dan sistem pesan. Kalau kamu membangun API dengan POST yang menyentuh uang, pasang header Idempotency-Key di proyek berikutnya dan uji dengan koneksi yang sengaja diputus. Respons lama datang kembali tanpa tagihan kedua, dan pelanggan cukup menyesali koneksi yang drop.

Penulis: Emmanuel Daniel Widhiarto, S.Kom – FDP Scholar

Referensi

Stripe. (2026). Idempotent requests. https://docs.stripe.com/api/idempotent_requests

Stripe. (2026). Advanced error handling. https://docs.stripe.com/error-low-level

MDN Web Docs. (2026). HTTP request methods. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods

IETF. (2022). HTTP Semantics (RFC 9110). https://www.rfc-editor.org/rfc/rfc9110

Apache Kafka. (2026). Apache Kafka documentation. https://kafka.apache.org/documentation/