Kontrak API Idempoten perlu dirancang agar alur pembayaran tetap konsisten meskipun terjadi retry dari klien atau gateway. Dalam dua paragraf pertama ini saya langsung menjelaskan bahwa kontrak harus menjamin bahwa setiap permintaan pembayaran dapat diidentifikasi ulang (idempotency key) dan hasilnya dapat dibaca ulang tanpa efek samping ketika retry terjadi.

Untuk menjaga retry tetap terkendali, kontrak juga wajib mengembalikan status transaksi yang deterministik, menyertakan masa berlaku idempotency key, serta memberikan error kode yang bisa diprediksi.

Dasar Kontrak Idempoten untuk Endpoint Pembayaran

Kontrak API Idempoten untuk endpoint pembayaran berfokus pada empat elemen wajib: idempotency key, status transaksi, expiry key, dan error deterministik.

Idempotency key yang dapat diverifikasi

Setiap permintaan pembayaran harus mengenalkan idempotency key unik, biasanya berupa kombinasi ID klien dan timestamp. Penyedia bayar memvalidasi format dan menyimpan key bersama payload untuk mencegah duplikasi. Bila menerima key yang sudah ada, API mengembalikan status yang terakhir sekali ditetapkan tanpa memproses ulang logika pembayaran.

Status transaksi konsisten

Respons harus menyertakan status transaksi seperti pending, confirmed, atau failed. Penyedia wajib mencatat status final pertama kali permintaan berhasil demi kepatuhan idempoten. Status yang jelas memudahkan klien memutuskan apakah harus retry, menunggu, atau membatalkan.

Expiry dan error deterministik

Idempotency key harus memiliki durasi berlaku (misalnya 5 menit) sehingga penyedia tidak menyimpan metadata selamanya. Setelah habis, klien perlu membuat permintaan baru dengan key berbeda. Error juga wajib deterministik—kode seperti PAYMENT_DECLINED atau INSUFFICIENT_FUNDS memberikan informasi yang bisa diandalkan untuk keputusan retry. Hindari error generik yang membuat klien tidak tahu apakah retry aman.

Autentikasi, Otorisasi, dan Implikasi pada Idempoten B2B

Pada integrasi B2B, idempoten tidak hanya bergantung pada key dan status, tapi juga identitas pemanggil. Otorisasi harus memeriksa apakah kombinasi client_id dan scope memiliki hak melakukan pembayaran dan juga membuat idempotency key baru.

Token yang dimiliki klien menempelkan metadata B2B: misalnya apakah request berasal dari merchant utama atau sub-account. Penyedia perlu memisahkan storage idempotency per tenant agar request dari merchant berbeda tidak bercampur. Autentikasi yang lemah bisa menyebabkan key digunakan ulang oleh actor yang salah.

Kebijakan Retry: Eksponensial dengan Circuit Breaker

Retry perlu dikontrol agar tidak mengakibatkan beban berlebih. Gunakan pola eksponensial backoff dengan batas retry tetap, misalnya 3 kali percobaan dengan delay 1s, 2s, 4s. Klien harus memperhitungkan status dari respons untuk memutuskan retry. Jika respons menyatakan duplicate atau processing, jangan langsung retry tanpa menunggu.

Untuk melengkapi, terapkan circuit breaker di sisi klien atau gateway. Circuit breaker memantau rasio kegagalan dan menahan retry sementara ketika sistem pembayaran sedang bermasalah. Setelah cool-down, breaker kembali mencoba secara bertahap.

  • Trigger breaker: persentase error deterministik (misalnya > 50% dari permintaan 30 detik terakhir).
  • Recovery: setelah breaker terbuka selama periode tertentu, coba satu permintaan untuk memastikan sistem stabil.
  • Integrasi: logika retry klien harus menunggu breaker kembali ke status closed.

Contoh Payload dan Validasi Provider

Berikut contoh payload yang mengilustrasikan kontrak:

{
  "idempotency_key": "b2b-merchant123-20241002-01",
  "amount": 150000,
  "currency": "IDR",
  "payment_method": "virtual_account",
  "metadata": {
    "order_id": "order-5566"
  }
}

Respons yang sesuai:

{
  "transaction_id": "txn-789",
  "status": "processing",
  "expires_at": "2024-10-02T08:25:00Z",
  "duplicate": false,
  "error_code": null
}

Jika key terdeteksi duplikat, provider mengembalikan:

{
  "transaction_id": "txn-789",
  "status": "processing",
  "duplicate": true,
  "error_code": null
}

Validasi sisi penyedia wajib mencakup:

  • Pemeriksaan format dan panjang idempotency key.
  • Verifikasi bahwa key belum kadaluarsa.
  • Pemastian bahwa jumlah dan metode pembayaran konsisten dengan transaksi sebelumnya.
  • Penerapan mekanisme locking atau database constraint untuk mencegah race condition saat menyimpan key.

Observabilitas dan Debugging Retry Gagal

Untuk memantau kegagalan retry, pantau metrik berikut:

  • Rasio duplicate response per endpoint.
  • Jumlah retry yang mencapai batas maksimum per detik.
  • Distribusi error_code deterministik (misalnya PROCESSING_TIMEOUT).

Log harus mencatat idempotency key, transaction_id, dan status akhir agar bisa membandingkan aktivitas klien vs penyedia. Gunakan tracing untuk menelusuri kenapa retry masih muncul: apakah karena timeout gateway, atau karena status masih pending?

Debugging tip: ketika melihat retry terus berlangsung, cek apakah circuit breaker belum terbuka, apakah klien mengirim key baru setiap retry (harus tetap sama), dan apakah penyedia mengembalikan error deterministik yang bisa memicu backoff yang benar.

Kesimpulan

Kontrak API Idempoten yang matang menghadirkan key unik, status transaksi konsisten, expiry, dan error deterministik. Dipadukan dengan otentikasi B2B yang membatasi scope, retry eksponensial dengan circuit breaker, validasi provider, serta observabilitas, kontrak ini memungkinkan alur pembayaran tetap aman dan terukur meski terjadi kegagalan.