Cara Handle Refund, Cancel, dan Expired Order di API OTP

Developer 10 Jul 2026 · OTPZap Team

Dalam integrasi API OTP, bagian tersulit sering bukan create order, tetapi settlement setelah order berjalan. Order bisa sukses, OTP bisa masuk, user bisa cancel, provider bisa gagal, atau order bisa expired. Jika flow ini tidak dirancang dengan rapi, sistem reseller bisa mengalami double refund, saldo tidak cocok, atau order terlihat aktif padahal sudah selesai.

Artikel ini membahas cara menangani refund, cancel, expired, failed, dan success secara aman untuk developer. Prinsip utamanya adalah idempotency, status terminal yang jelas, dan ledger saldo yang bisa diaudit.

Pahami status order

Setiap sistem bisa punya nama status berbeda, tetapi secara konsep biasanya ada tiga kelompok. Pertama, status aktif seperti pending atau waiting. Kedua, status berhasil seperti OTP received atau success. Ketiga, status terminal gagal seperti cancelled, expired, atau failed.

Begitu order masuk status terminal, sistem kamu harus berhenti melakukan aksi yang bisa mengubah saldo lebih dari sekali. Terminal berarti sudah ada keputusan akhir.

Jangan anggap cancel selalu sama dengan refund penuh

Cancel bisa berarti beberapa hal. User membatalkan sebelum OTP masuk, order gagal dari sisi server, aplikasi tidak mengirim OTP, atau order sudah terlalu lama. Pada beberapa produk, refund bisa penuh. Pada produk lain, ada aturan settlement tertentu. Karena itu backend reseller harus mengikuti response API dan aturan produk, bukan membuat asumsi sendiri.

Gunakan ledger, bukan hanya update balance

Setiap perubahan saldo harus masuk balance log. Minimal simpan user_id, tipe add/subtract, amount, before, after, ref order, note, dan waktu. Dengan ledger, kamu bisa audit jika user komplain atau jika ada bug worker.

Update langsung ke kolom balance tanpa log akan membuat masalah sulit dilacak. Ledger adalah sumber bukti.

Desain idempotency refund

Refund harus punya guard. Contohnya, simpan refund_key berdasarkan order_ref. Saat proses refund berjalan, sistem cek apakah refund_key sudah pernah dipakai. Jika sudah, jangan tambah saldo lagi. Ini melindungi dari double click, retry worker, timeout, dan request paralel.

Prinsip yang sama berlaku untuk cancel. Jika user klik cancel dua kali, response kedua boleh mengatakan order sudah cancelled, tetapi saldo tidak boleh bertambah dua kali.

Flow aman untuk cancel

  1. Load order lokal berdasarkan user dan order_ref.
  2. Cek apakah status sudah terminal.
  3. Jika belum terminal, panggil API cancel.
  4. Reload status order dari API jika perlu.
  5. Hitung settlement berdasarkan response/aturan.
  6. Ambil lock atau guard refund.
  7. Tulis balance log refund satu kali.
  8. Update status lokal ke terminal.

Flow expired order

Expired order sebaiknya diproses oleh worker berkala. Worker mencari order aktif yang sudah melewati batas waktu, mengecek status terakhir ke API, lalu menyelesaikan order. Jangan hanya mengandalkan frontend user membuka halaman. Jika user menutup browser, settlement tetap harus berjalan.

Flow failed order

Failed berarti order tidak bisa dilanjutkan. Penyebabnya bisa stok kosong, layanan tidak tersedia, atau sistem target tidak mengirim OTP. Untuk reseller, yang penting adalah menampilkan pesan yang jelas dan memastikan saldo sesuai hasil settlement.

Flow success

Jika OTP diterima dan order success, jangan izinkan refund otomatis untuk order tersebut kecuali ada aturan khusus. Tandai order sebagai selesai, simpan OTP jika diperlukan, dan hentikan polling. Jika ada request cancel setelah success, response harus jelas bahwa order sudah selesai.

Audit yang wajib ada

FAQ

Kenapa double refund bisa terjadi?

Biasanya karena request cancel dikirim lebih dari sekali, worker retry setelah timeout, atau tidak ada guard unik di proses refund.

Apakah frontend boleh langsung mengubah saldo?

Tidak. Frontend hanya meminta aksi. Semua perubahan saldo harus dilakukan backend setelah validasi dan logging.

Bagaimana kalau API timeout saat cancel?

Jangan langsung refund berdasarkan asumsi. Cek status order lagi, lalu settle berdasarkan kondisi terbaru.

Dengan flow yang idempotent dan ledger yang rapi, integrasi OTP API jauh lebih tahan terhadap retry, timeout, dan komplain user. OTPZap menyediakan status order dan flow cancel/refund yang bisa dijadikan dasar untuk membangun sistem reseller yang lebih aman.