Lewati ke konten

Idempotensi

Buat request yang membuat atau memindahkan uang aman diulang dengan header Idempotency-Key di API Baiyar.


Request yang timeout belum tentu gagal; server mungkin sudah memprosesnya. Agar retry tidak membuat pembayaran kedua, kirim header Idempotency-Key sepanjang 1–255 karakter. Kamu bisa memakai UUID atau nomor order dengan nomor percobaan. Header ini wajib untuk:

  • POST /v1/payments
  • POST /v1/payment-links
  • POST /v1/payment-links/{id}/cancel
  • POST /v1/payments/{id}/cancel
  • POST /v1/webhook-deliveries/{id}/resend
  • POST /v1/invoices, dan POST /v1/invoices/{id}/issue, /void, dan /resend (supaya ulangan tidak mengirim email dua kali ke pelanggan)
POST /v1/payments
Idempotency-Key: order-1001-attempt-1
Request Hasil
Key digunakan untuk pertama kali Request diproses dan hasilnya disimpan selama 24 jam
Key dan body yang sama dikirim lagi Hasil tersimpan dikembalikan dengan header Idempotent-Replayed: true; operasi tidak dijalankan ulang
Key yang sama dikirim dengan body atau rute berbeda 409 idempotency_key_reused
Key yang sama dikirim saat request pertama masih diproses 409 idempotency_in_progress dengan header Retry-After. Kirim ulang request yang sama setelah jeda tersebut
Request pertama gagal sebelum menimbulkan efek Key tidak disimpan. Kamu bisa mencoba lagi dengan key yang sama

Buat key sebelum percobaan pertama, simpan bersama ordermu, dan pakai key serta body yang sama di setiap pengulangan:

import { randomUUID } from "node:crypto";
// dibuat sekali, disimpan bersama order di databasemu
const idempotencyKey = `order-${order.id}-${randomUUID()}`;
async function createPayment(body, attempts = 3) {
for (let attempt = 1; ; attempt++) {
try {
const response = await fetch("https://api.baiyar.com/v1/payments", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BAIYAR_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey,
},
body: JSON.stringify(body),
});
if (response.status < 500 || attempt === attempts) return response;
} catch (error) {
if (attempt === attempts) throw error; // timeout atau koneksi terputus
}
await new Promise((resolve) => setTimeout(resolve, 2 ** attempt * 500));
}
}

Jika Baiyar menerima request pertama, retry akan mengembalikan pembayaran yang sama di data dengan Idempotent-Replayed: true; pembayaran kedua tidak dibuat. meta.request_id menunjukkan ID retry, bukan ID request pertama.

  • Buat satu key untuk setiap operasi. Gunakan kembali hanya saat me-retry operasi yang sama. Order baru atau pembayaran baru memerlukan key baru.
  • Simpan key bersama order di database sebelum mengirim request agar aplikasi bisa memakainya lagi setelah restart.
  • Request baca (GET) tidak memerlukan key.
  • Key disimpan selama 24 jam. Setelah itu, key yang sama dapat memulai request baru.