ping!
Ke aplikasi
Developer · API internal

Pembayaran QRIS

Buat dan pulihkan satu top-up aktif tanpa menggandakan pembayaran atau mengkreditkan saldo sebelum konfirmasi provider.

Unduh OpenAPI 3.1
Di halaman ini

Sebelum mengirim request

Nominal top-up saat ini Rp 10.000–Rp 1.000.000. UI polling setiap 5 detik selama CREATING/PENDING. Hanya status PAID terkonfirmasi yang menambah saldo; totalAmount adalah nominal bayar, requestedAmount adalah nominal kredit.

Kontrak nyata, nilai contoh

Endpoint, field, dan status HTTP mengikuti implementasi. Nilai ID, nomor, OTP, waktu, saldo, serta quote di contoh adalah ilustrasi, bukan data akun atau pilihan yang bisa langsung dibeli. Ganti dengan data dari instalasimu. Halaman ini tidak mengirim request atau menjalankan transaksi.

JavaScript dijalankan pada origin aplikasi setelah login. Contoh cURL memakai PING_ORIGIN dan cookie jar PING_COOKIE_JAR dari panduan autentikasi. Sukses memakai { ok: true, data }; create juga HTTP 200, bukan 201. Semua endpoint di halaman ini memerlukan sesi aktif dan dapat mengembalikan 401, 403, atau 500.

Baca pembayaran aktif

GET/api/payments/klikqrisSession cookie

Source : app/api/payments/klikqris/route.ts

Membaca pembayaran CREATING/PENDING terakhir dari database. Bentuk data adalah { payment: Payment | null }, bukan Payment langsung. Gunakan endpoint detail untuk pemeriksaan provider.

GET /api/payments/klikqris · JavaScript
const response = await fetch("/api/payments/klikqris", {
  credentials: "same-origin",
  cache: "no-store",
});
const body = await response.json();

if (!response.ok || !body.ok) {
  throw Object.assign(
    new Error(body.error?.message ?? "Request gagal"),
    { code: body.error?.code, status: response.status },
  );
}

const data = body.data;

Buat top-up QRIS

POST/api/payments/klikqrisSession cookie

Source : app/api/payments/klikqris/route.ts

Membuat top-up idempotent. Satu pembayaran belum selesai per akun. Respons Payment bisa masih CREATING dengan materi QR null. Pembayaran aktif dengan nominal sama dapat dikembalikan alih-alih membuat transaksi kedua.

Perhatikan sebelum mengirim

Menjalankan request ini membuat transaksi pembayaran nyata pada instalasi yang terhubung provider. Respons hilang tidak boleh memicu pembuatan transaksi baru; pulihkan melalui GET pembayaran aktif/detail.

Buat top-up QRIS
Body JSONTipeWajibKeterangan
amountintegerYaRupiah utuh, antara 10000 dan 1000000.
clientRequestIdstring · uuidYaUUID untuk satu top-up. Jangan ganti UUID karena respons jaringan hilang.
POST /api/payments/klikqris · JavaScript
const response = await fetch("/api/payments/klikqris", {
  method: "POST",
  credentials: "same-origin",
  cache: "no-store",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    "amount": 10000,
    "clientRequestId": "f41c29d8-967d-469d-ae4f-0114c38bf715"
  }),
});
const body = await response.json();

if (!response.ok || !body.ok) {
  throw Object.assign(
    new Error(body.error?.message ?? "Request gagal"),
    { code: body.error?.code, status: response.status },
  );
}

const data = body.data;
Buat top-up QRIS
Kode errorHTTPTindakan
VALIDATION_ERROR400Periksa tipe, field wajib, format UUID, dan field tambahan.
IDEMPOTENCY_CONFLICT409Pulihkan pembayaran awal. UUID baru hanya untuk niat transaksi baru.
CONFLICT409Baca pembayaran aktif, jangan terus membuat top-up baru.
PAYMENT_NOT_CONFIGURED503Pemilik instalasi harus menyiapkan KlikQRIS; bukan mengganti data dengan demo.
PAYMENT_PROVIDER_ERROR502Baca pembayaran aktif atau detail dengan ID yang sama.

Periksa pembayaran

GET/api/payments/klikqris/{id}Session cookie

Source : app/api/payments/klikqris/[id]/route.ts

Membaca pembayaran milik sesi dan melakukan poll-through terbatas untuk pembayaran aktif. UI polling 5 detik, sedangkan klaim pemeriksaan provider dibatasi sekitar 10 detik. Respons langsung Payment, bukan { payment }.

Periksa pembayaran
ParameterTipeWajibKeterangan
id (path)string · uuidYaUUID pembayaran milik pengguna bersesi.
GET /api/payments/klikqris/{id} · JavaScript
const response = await fetch("/api/payments/klikqris/5d81627b-4c2b-4cab-bd07-2a5ed675fe5f", {
  credentials: "same-origin",
  cache: "no-store",
});
const body = await response.json();

if (!response.ok || !body.ok) {
  throw Object.assign(
    new Error(body.error?.message ?? "Request gagal"),
    { code: body.error?.code, status: response.status },
  );
}

const data = body.data;
Periksa pembayaran
Kode errorHTTPTindakan
VALIDATION_ERROR400Periksa tipe, field wajib, format UUID, dan field tambahan.
NOT_FOUND404Periksa ID dan akun; ID resource tidak memberi akses lintas pengguna.
PAYMENT_PROVIDER_ERROR502Baca pembayaran aktif atau detail dengan ID yang sama.
CONFLICT409Baca pembayaran aktif, jangan terus membuat top-up baru.

Schema · Payment

Schema · Payment
FieldTipeWajibKeterangan
idstring · uuidYaSesuai tipe yang ditampilkan.
requestedAmountintegerYaJumlah top-up yang dikreditkan jika PAID terkonfirmasi.
totalAmountinteger | nullYaTotal yang harus dibayar ke provider; bisa berbeda dari requestedAmount.
statusCREATING | PENDING | PAID | EXPIRED | FAILEDYaSesuai tipe yang ditampilkan.
qrisUrlstring | nullYaMateri QR dari provider; tersedia hanya untuk pembayaran aktif.
qrisImagestring | nullYaSesuai tipe yang ditampilkan.
paymentUrlstring | nullYaSesuai tipe yang ditampilkan.
expiresAtstring | nullYaTimestamp provider tanpa zona waktu, disimpan apa adanya. Bukan waktu ISO UTC.
createdAtstring · date-timeYaISO 8601 dengan zona waktu.
paidAtstring | null · date-timeYaISO 8601 dengan zona waktu.
messagestring | nullYaSesuai tipe yang ditampilkan.

Schema · ActivePayment

Schema · ActivePayment
FieldTipeWajibKeterangan
paymentPayment | nullYaPembayaran aktif, atau null jika tidak ada.
Ping! · Panduan yang tumbuh bersama produknya.Bantuan