Dokumentasi API Reseller Kembali ke situs
Dokumentasi resmi

PERKASA FAST OTP API Documentation

Integrasi programatik untuk reseller: cek katalog, buat pesanan, ambil OTP, dan kelola saldo dari sistem Anda sendiri.

Halaman ini hanya memuat endpoint yang sudah aktif. Kunci API diterbitkan oleh admin untuk akun reseller yang disetujui.

Pendahuluan

Tersedia

API 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
  1. Minta kunci API kepada admin untuk akun reseller Anda.
  2. Pastikan saldo mencukupi. Isi saldo dari menu Isi Saldo di dashboard.
  3. Panggil GET /balance untuk memastikan kunci berfungsi.
  4. Ambil layanan dengan /applications, negara dengan /countries, server dengan /products, dan harga dengan /prices.
  5. Buat pesanan dengan POST /order/create, lalu cek OTP dengan /order/status.

Autentikasi

Tersedia

Kirim kunci API pada setiap request melalui header Authorization dengan skema Bearer:

HTTP
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

Tersedia

Kunci 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

Tersedia
Base URL
https://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 memuat meta.
  • Respons gagal berbentuk {"error": {"code": "...", "message": "..."}}.
  • Semua harga dalam Rupiah penuh (bilangan bulat, currency: "IDR"). Waktu dalam WIB (Asia/Jakarta), format Y-m-d H:i:s.

Country API

Tersedia

Daftar negara yang masih memiliki stok untuk satu layanan.

Endpoint
GET https://perkasafastotp.biz.id/api/v1/countries?service={slug}&provider={provider}
  • service (wajib): slug layanan dari /applications.
  • provider (opsional): jalur provider, misalnya provider_1. Default: jalur aktif.
Respons 200
{
  "data": [
    { "country_code": "ID", "name": "Indonesia", "stock": 5 }
  ]
}

Application API

Tersedia

Daftar layanan (aplikasi tujuan OTP) yang sedang aktif dan ditampilkan.

Endpoint
GET https://perkasafastotp.biz.id/api/v1/applications
Respons 200
{
  "data": [
    { "slug": "whatsapp", "name": "WhatsApp", "category": "social" }
  ]
}

Product API

Tersedia

Server (offer) yang tersedia untuk layanan dan negara tertentu. Hanya server dengan stok di atas nol yang ditampilkan.

Endpoint
GET https://perkasafastotp.biz.id/api/v1/products?service={slug}&country={code}&provider={provider}
Respons 200
{
  "data": [
    { "id": "o1", "stock": 5, "recommended": true }
  ]
}

Gunakan id sebagai nilai offer saat membuat pesanan.

Price API

Tersedia

Harga jual untuk setiap server. Parameter sama dengan Product API.

Endpoint
GET https://perkasafastotp.biz.id/api/v1/prices?service={slug}&country={code}&provider={provider}
Respons 200
{
  "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

Tersedia

Saldo akun reseller saat ini.

Endpoint
GET https://perkasafastotp.biz.id/api/v1/balance
Respons 200
{
  "data": { "balance": 96500, "currency": "IDR" }
}

Profile API

Tersedia

Informasi akun dan kunci API yang sedang dipakai.

Endpoint
GET https://perkasafastotp.biz.id/api/v1/profile
Respons 200
{
  "data": {
    "id": 2,
    "username": "reseller01",
    "status": "active",
    "api_key": { "id": 1, "name": "Sistem utama", "prefix": "pfo_live_26a9f50" }
  }
}

Create Order

Tersedia

Membuat pesanan dan langsung memotong saldo sebesar harga jual. Saldo dipotong tepat sekali walaupun request diulang.

Endpoint
POST https://perkasafastotp.biz.id/api/v1/order/create
Body (JSON)
{
  "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 201 berisi pesanan dengan status awal, biasanya pending.
Respons 201
{
  "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

Tersedia

Memeriksa status pesanan dan mengambil OTP. Saat pesanan masih menunggu, cek ulang setiap beberapa detik. Server membatasi frekuensi pengecekan ke provider.

Endpoint
GET https://perkasafastotp.biz.id/api/v1/order/status?id={order_id}
  • Status pending dan awaiting_otp: menunggu SMS masuk.
  • Status completed: OTP tersedia di otp_code.
  • Status cancelled atau expired: saldo sudah dikembalikan (refunded: true).
  • Status reserving, uncertain, atau review: pesanan sedang diverifikasi. Saldo tetap ditahan dan tidak hilang.

Cancel Order

Tersedia

Membatalkan pesanan yang belum menerima OTP. Saldo dikembalikan setelah pembatalan dikonfirmasi provider.

Endpoint
POST https://perkasafastotp.biz.id/api/v1/order/cancel
Body (JSON)
{ "id": "ORDDC1D21F8813E" }

Jika pembatalan ditolak (misalnya OTP sudah masuk), respons 422 cancel_failed dan field retry_after bila provider meminta jeda.

Order History

Tersedia

Daftar pesanan terbaru milik akun Anda, dari yang paling baru.

Endpoint
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.
Respons 200
{
  "data": [ { "id": "ORDDC1D21F8813E", "status": "cancelled", "price": 3500, "...": "..." } ],
  "meta": { "page": 1, "per_page": 20, "total": 1 }
}

Error Codes

Tersedia
HTTP code → arti
400  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 nanti

Rate Limits

Tersedia

Maksimal 60 request per menit untuk setiap kunci API. Jika terlampaui, respons 429 rate_limited sampai jendela waktu berikutnya.

Webhook

Belum tersedia

Notifikasi 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 tersedia

Callback URL untuk reseller belum tersedia.

Code Examples

Tersedia

Contoh di bawah membuat pesanan lalu mengambil status. Ganti pfo_live_XXXX dengan kunci Anda.

cURL

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
<?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
<?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

JavaScript
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+)

Node.js
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

Python
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

Tersedia

Apakah 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.