Quickstart
Buat request pertama menggunakan sesi yang sudah ada, kemudian pahami alur katalog → quote → order tanpa menjalankan pembelian secara tidak sengaja.
Unduh OpenAPI 3.1Di halaman ini
Siapkan lingkungan yang tepat
- Jalankan instalasi sendiri atau gunakan staging yang kamu kelola. Provider harus dikonfigurasi dan katalog disinkron sebelum quote tersedia.
- Masuk melalui /login dengan akun uji. Sesi milik akun itu akan menentukan akses resource.
- Mulai dari request GET. Jangan menguji pembelian, pembatalan, penyelesaian, atau top-up pada akun produksi tanpa memahami dampaknya.
01 · Baca akun yang sedang login
Jalankan contoh ini dari frontend pada origin aplikasi, atau DevTools browser setelah login. Tidak perlu API key. Request ini tidak membuat order atau pembayaran.
const response = await fetch("/api/me", {
credentials: "same-origin",
cache: "no-store",
});
const body = await response.json();
if (!response.ok || !body.ok) {
throw new Error(body.error?.message ?? "Request gagal");
}
const { user, balance, held, available } = body.data;02 · Ambil ID dan harga dari server
Untuk mengembangkan source Ping!, gunakan wrapper api yang sudah memeriksa envelope dan melempar RequestError. Isi pilihan layanan/negara dari kedua array katalog, lalu ambil quote saat pengguna memilih. ID di contoh referensi bukan ID katalog yang valid pada instalasimu.
import { api, quoteKey } from "@/lib/ping/client";
import type { Country, Quote, Service } from "@/lib/ping/types";
const [services, countries] = await Promise.all([
api<Service[]>("/api/catalog/services"),
api<Country[]>("/api/catalog/countries"),
]);
async function loadQuote(serviceId: string, countryId: string) {
return api<Quote>(quoteKey(countryId, serviceId));
}Tangani katalog kosong dan quote tidak tersedia sebagai keadaan nyata. Jangan mengganti katalog akun dengan demo-data. Jumlah qualitative_stock bukan stok kuantitatif yang dijamin.
03 · Kirim hanya setelah konfirmasi
Pemanggilan buyNumber menahan saldo dan dapat membeli nomor nyata. Buat clientRequestId satu kali saat niat pembelian dimulai, simpan bersama intent/payload pending, dan teruskan UUID yang sama untuk pemulihan request tersebut. Jangan memanggil fungsi dari render atau effect otomatis.
import { usePing } from "@/lib/ping/client";
import type { Quote } from "@/lib/ping/types";
const { buyNumber } = usePing();
async function submitConfirmedOrder(
quote: Quote,
optionId: string,
clientRequestId: string,
) {
const option = quote.options.find((item) => item.id === optionId);
if (!option) throw new Error("Pilih harga yang tersedia");
return buyNumber(
quote.countryId,
quote.serviceId,
clientRequestId,
option,
);
}Panggil usePing pada bagian atas client component atau custom hook, lalu gunakan fungsi di event handler konfirmasi. Nonaktifkan tombol selama request berjalan. Jika harga berubah, ambil quote baru dan minta persetujuan ulang; jangan menurunkan proteksi dengan menghapus expectedPriceIdr.
04 · Pantau detail, bukan hanya daftar
Gunakan useOrder(id) di client component untuk polling 5 detik, action cancel/complete, dan revalidasi cache. Hook berjalan di AccountProvider untuk akun nyata atau PreviewProvider untuk review UI. Jangan mengimpor store preview sebagai sumber data produksi.
import { useOrder } from "@/lib/ping/client";
const { data: order, error, cancel, complete } = useOrder(orderId);
const preparing = order?.isPreparing ?? false;
const smsCode = order?.code;
const showComplete = order?.canComplete ?? false;
const allowCancel = order?.canCancel ?? false;