PERKASA FAST OTP API Documentation
Integrasi programatik untuk reseller: cek katalog, buat pesanan, ambil OTP, dan kelola saldo dari sistem Anda sendiri.
Pendahuluan
TersediaAPI reseller memungkinkan sistem Anda membeli nomor virtual (NOKOS) dan menerima kode OTP secara otomatis. Semua transaksi memakai saldo akun reseller yang sama dengan saldo di dashboard, dan setiap harga dihitung di server.
Memulai
Tersedia- Minta kunci API kepada admin untuk akun reseller Anda.
- Pastikan saldo mencukupi. Isi saldo dari menu Isi Saldo di dashboard.
- Panggil
GET /balanceuntuk memastikan kunci berfungsi. - Ambil layanan dengan
/applications, negara dengan/countries, server dengan/products, dan harga dengan/prices. - Buat pesanan dengan
POST /order/create, lalu cek OTP dengan/order/status.
Autentikasi
TersediaKirim kunci API pada setiap request melalui header Authorization dengan skema Bearer:
Authorization: Bearer pfo_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx- Tanpa header yang valid, respons
401 unauthorized. - Kunci yang salah, dicabut, atau milik akun yang nonaktif, respons
401 invalid_api_key. - Jangan membagikan kunci di sisi browser atau repositori publik.
API Key
TersediaKunci berformat pfo_live_ diikuti 48 karakter hex. Kunci ditampilkan sekali saat diterbitkan; sistem hanya menyimpan hash-nya. Jika kunci hilang, minta admin mencabut dan menerbitkan kunci baru.
- Satu akun dapat memiliki beberapa kunci, misalnya satu per sistem.
- Kunci yang dicabut langsung tidak dapat dipakai lagi.
- Setiap kunci mencatat waktu terakhir dipakai dan jumlah request.
Base URL & Format
Tersediahttps://perkasafastotp.biz.id/api/v1- Request GET memakai query string, misalnya
?service=whatsapp&country=ID. - Request POST memakai body JSON dengan header
Content-Type: application/json. - Respons sukses berbentuk
{"data": ...}. Daftar paginasi juga memuatmeta. - Respons gagal berbentuk
{"error": {"code": "...", "message": "..."}}. - Semua harga dalam Rupiah penuh (bilangan bulat,
currency: "IDR"). Waktu dalam WIB (Asia/Jakarta), formatY-m-d H:i:s.
Country API
TersediaDaftar negara yang masih memiliki stok untuk satu layanan.
GET https://perkasafastotp.biz.id/api/v1/countries?service={slug}&provider={provider}service(wajib): slug layanan dari/applications.provider(opsional): jalur provider, misalnyaprovider_1. Default: jalur aktif.
{
"data": [
{ "country_code": "ID", "name": "Indonesia", "stock": 5 }
]
}Application API
TersediaDaftar layanan (aplikasi tujuan OTP) yang sedang aktif dan ditampilkan.
GET https://perkasafastotp.biz.id/api/v1/applications{
"data": [
{ "slug": "whatsapp", "name": "WhatsApp", "category": "social" }
]
}Product API
TersediaServer (offer) yang tersedia untuk layanan dan negara tertentu. Hanya server dengan stok di atas nol yang ditampilkan.
GET https://perkasafastotp.biz.id/api/v1/products?service={slug}&country={code}&provider={provider}{
"data": [
{ "id": "o1", "stock": 5, "recommended": true }
]
}Gunakan id sebagai nilai offer saat membuat pesanan.
Price API
TersediaHarga jual untuk setiap server. Parameter sama dengan Product API.
GET https://perkasafastotp.biz.id/api/v1/prices?service={slug}&country={code}&provider={provider}{
"data": [
{ "id": "o1", "price": 3500, "currency": "IDR" }
]
}Kirim nilai price yang sama saat membuat pesanan. Jika harga berubah sebelum pesanan dikirim, server menolak dengan 409 price_changed dan menyertakan new_price.
Balance API
TersediaSaldo akun reseller saat ini.
GET https://perkasafastotp.biz.id/api/v1/balance{
"data": { "balance": 96500, "currency": "IDR" }
}Profile API
TersediaInformasi akun dan kunci API yang sedang dipakai.
GET https://perkasafastotp.biz.id/api/v1/profile{
"data": {
"id": 2,
"username": "reseller01",
"status": "active",
"api_key": { "id": 1, "name": "Sistem utama", "prefix": "pfo_live_26a9f50" }
}
}Create Order
TersediaMembuat pesanan dan langsung memotong saldo sebesar harga jual. Saldo dipotong tepat sekali walaupun request diulang.
POST https://perkasafastotp.biz.id/api/v1/order/create{
"service": "whatsapp",
"provider": "provider_1",
"country": "ID",
"offer": "o1",
"price": 3500
}Idempotency-Key(header, opsional, 8-64 karakter huruf/angka/_/-): kirim ulang request yang sama dengan kunci yang sama. Server mengembalikan pesanan yang sudah dibuat (idempotent_replay: true) tanpa memotong saldo lagi. Gunakan referensi unik per transaksi di sistem Anda.- Respons sukses
201berisi pesanan dengan status awal, biasanyapending.
{
"data": {
"id": "ORDDC1D21F8813E",
"status": "pending",
"service": "WhatsApp",
"country_code": "ID",
"country_name": "Indonesia",
"number": "628111",
"otp_code": null,
"price": 3500,
"currency": "IDR",
"refunded": false,
"can_cancel": false,
"created_at": "2026-10-31 00:56:41",
"expires_at": null,
"completed_at": null
},
"state": "ok"
}Check OTP
TersediaMemeriksa status pesanan dan mengambil OTP. Saat pesanan masih menunggu, cek ulang setiap beberapa detik. Server membatasi frekuensi pengecekan ke provider.
GET https://perkasafastotp.biz.id/api/v1/order/status?id={order_id}- Status
pendingdanawaiting_otp: menunggu SMS masuk. - Status
completed: OTP tersedia diotp_code. - Status
cancelledatauexpired: saldo sudah dikembalikan (refunded: true). - Status
reserving,uncertain, ataureview: pesanan sedang diverifikasi. Saldo tetap ditahan dan tidak hilang.
Cancel Order
TersediaMembatalkan pesanan yang belum menerima OTP. Saldo dikembalikan setelah pembatalan dikonfirmasi provider.
POST https://perkasafastotp.biz.id/api/v1/order/cancel{ "id": "ORDDC1D21F8813E" }Jika pembatalan ditolak (misalnya OTP sudah masuk), respons 422 cancel_failed dan field retry_after bila provider meminta jeda.
Order History
TersediaDaftar pesanan terbaru milik akun Anda, dari yang paling baru.
GET https://perkasafastotp.biz.id/api/v1/orders?page={page}&per_page={per_page}page: mulai dari 1. Default 1.per_page: 1-50. Default 20.
{
"data": [ { "id": "ORDDC1D21F8813E", "status": "cancelled", "price": 3500, "...": "..." } ],
"meta": { "page": 1, "per_page": 20, "total": 1 }
}Error Codes
Tersedia400 invalid_json Body bukan JSON yang valid
401 unauthorized Header Authorization tidak ada
401 invalid_api_key Kunci salah, dicabut, atau akun nonaktif
402 insufficient_balance Saldo tidak cukup
403 account_inactive Akun tidak aktif
404 service_not_found Slug layanan tidak ditemukan
404 order_not_found ID pesanan tidak ditemukan milik akun ini
409 price_changed Harga berubah; lihat new_price
409 idempotency_in_progress Idempotency-Key sedang diproses
422 invalid_* Parameter tidak valid (country, offer, price, provider, service, order_id)
422 order_rejected Pesanan ditolak (misalnya stok habis)
422 order_failed Pesanan gagal diproses dan saldo dikembalikan; data berisi pesanan
422 cancel_failed Pembatalan belum bisa dilakukan
429 rate_limited Melebihi batas request
500 order_status_unknown Status belum pasti; cek /orders sebelum mengulang
503 provider_unavailable Provider sedang gangguan; coba lagi nantiRate Limits
TersediaMaksimal 60 request per menit untuk setiap kunci API. Jika terlampaui, respons 429 rate_limited sampai jendela waktu berikutnya.
Webhook
Belum tersediaNotifikasi otomatis untuk reseller belum tersedia. Untuk saat ini, gunakan Check OTP secara berkala.
Endpoint POST /webhook/pakasir hanya untuk gateway pembayaran, bukan untuk reseller.
Callback
Belum tersediaCallback URL untuk reseller belum tersedia.
Code Examples
TersediaContoh di bawah membuat pesanan lalu mengambil status. Ganti pfo_live_XXXX dengan kunci Anda.
cURL
curl -s -X POST "https://perkasafastotp.biz.id/api/v1/order/create" \
-H "Authorization: Bearer pfo_live_XXXX" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ref-000123" \
-d '{"service":"whatsapp","provider":"provider_1","country":"ID","offer":"o1","price":3500}'PHP Native
<?php
$ctx = stream_context_create(['http' => [
'method' => 'GET',
'header' => "Authorization: Bearer pfo_live_XXXX\r\n",
'ignore_errors' => true,
]]);
$json = json_decode(file_get_contents('https://perkasafastotp.biz.id/api/v1/balance', false, $ctx), true);
echo $json['data']['balance'];PHP cURL
<?php
$ch = curl_init('https://perkasafastotp.biz.id/api/v1/order/status?id=ORDDC1D21F8813E');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer pfo_live_XXXX'],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($res['data']['otp_code'] ?? null);JavaScript Fetch
const res = await fetch('https://perkasafastotp.biz.id/api/v1/order/create', {
method: 'POST',
headers: {
Authorization: 'Bearer pfo_live_XXXX',
'Content-Type': 'application/json',
'Idempotency-Key': 'ref-000123',
},
body: JSON.stringify({ service: 'whatsapp', provider: 'provider_1', country: 'ID', offer: 'o1', price: 3500 }),
});
const json = await res.json();Node.js (18+)
const res = await fetch('https://perkasafastotp.biz.id/api/v1/order/status?id=ORDDC1D21F8813E', {
headers: { Authorization: `Bearer ${process.env.PFO_API_KEY}` },
});
const { data } = await res.json();
console.log(data.status, data.otp_code);Python Requests
import requests
r = requests.post(
'https://perkasafastotp.biz.id/api/v1/order/create',
headers={'Authorization': 'Bearer pfo_live_XXXX', 'Idempotency-Key': 'ref-000123'},
json={'service': 'whatsapp', 'provider': 'provider_1', 'country': 'ID', 'offer': 'o1', 'price': 3500},
timeout=30,
)
print(r.status_code, r.json())FAQ
TersediaApakah saldo API sama dengan saldo dashboard? Ya. Keduanya memakai saldo akun yang sama.
Bagaimana jika request pembelian terputus? Kirim ulang dengan Idempotency-Key yang sama. Jika server belum pernah menerima request itu, pesanan dibuat; jika sudah, pesanan lama dikembalikan tanpa potongan baru.
Kenapa pesanan gagal dengan saldo dikembalikan? Provider menolak atau tidak dapat memproses pesanan. Saldo dikembalikan otomatis dan tercatat di riwayat saldo.
Pertanyaan lain dapat diajukan melalui halaman Bantuan.
