Versi 1 · Base URL https://b2b.neos.id/api/v1
API NEOS B2B dipakai untuk menjual pulsa dan paket data Telkomsel dari sistem Anda. Semua request dan respons berformat JSON (UTF-8). Transaksi memotong saldo deposit akun Anda; bila transaksi gagal, saldo otomatis dikembalikan.
Kirim API key di header setiap request:
X-Api-Key: neos_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Selain API key, IP sumber request harus terdaftar di IP whitelist. Request dari IP lain ditolak dengan HTTP 403 IP_NOT_WHITELISTED. Simpan API key hanya di server; jangan pernah memakainya dari aplikasi mobile atau browser.
Respons sukses:
{
"success": true,
"data": { ... }
}
Respons gagal (HTTP 4xx/5xx):
{
"success": false,
"error": { "code": "INSUFFICIENT_BALANCE", "message": "Saldo tidak cukup" }
}
/api/v1/balance{
"success": true,
"data": { "balance": 15250000, "currency": "IDR" }
}
/api/v1/products/pulsa?msisdn=081234567890| Parameter | Keterangan |
|---|---|
msisdn | Wajib. Nomor tujuan (format 08xx, 628xx, atau +628xx). |
{
"success": true,
"data": {
"msisdn": "081234567890",
"type": "PULSA",
"products": [
{ "product_code": "PULSA-10000", "name": "Pulsa 10.000", "category": "Pulsa Reguler", "nominal": 10000, "price": 10373 },
{ "product_code": "PULSA-50000", "name": "Pulsa 50.000", "category": "Pulsa Reguler", "nominal": 50000, "price": 50678 }
]
}
}
/api/v1/products/data?msisdn=081234567890Paket yang tersedia berbeda per nomor (termasuk promo khusus nomor tersebut), jadi selalu ambil daftar untuk nomor tujuan sebelum bertransaksi.
{
"success": true,
"data": {
"msisdn": "081234567890",
"type": "DATA",
"products": [
{
"product_code": "DATA-00110944",
"name": "Super Seru Promo 7 Hari",
"category": "Kamu Banget Nih",
"quota": "DATA National/Internet 7 GB Nasional 7 Days",
"validity": "7 hari",
"price": 22800
}
]
}
}
/api/v1/transaction| Field (JSON) | Keterangan |
|---|---|
ref_id | Wajib. ID transaksi unik dari sistem Anda (1–64 karakter: huruf, angka, . _ -). ref_id yang sama tidak akan diproses dua kali. |
msisdn | Wajib. Nomor tujuan. |
product_code | Wajib. Dari daftar produk, mis. PULSA-10000 atau DATA-00110944. |
POST /api/v1/transaction
Content-Type: application/json
X-Api-Key: neos_live_xxxx
{ "ref_id": "INV-1001", "msisdn": "081234567890", "product_code": "DATA-00110944" }
Respons HTTP 201 — transaksi diterima dan sedang diproses:
{
"success": true,
"data": {
"trx_id": "TX-1793900012345",
"ref_id": "INV-1001",
"type": "DATA",
"product_code": "DATA-00110944",
"product_name": "Super Seru Promo 7 Hari",
"msisdn": "081234567890",
"price": 22800,
"status": "PENDING",
"sn": null,
"message": "Transaksi sedang diproses",
"created_at": "2026-11-05 21:30:12",
"updated_at": "2026-11-05 21:30:12"
}
}
price adalah harga final yang dipotong dari saldo saat transaksi dibuat (harga terbaru, bisa berbeda dari daftar produk bila ada perubahan harga).SUCCESS / FAILED) dikirim lewat callback, atau cek manual lewat cek status.DUPLICATE_REF_ID beserta data transaksi yang sudah ada./api/v1/transaction/{ref_id}Bisa memakai ref_id Anda atau trx_id NEOS. Data sama dengan respons buat transaksi.
{
"success": true,
"data": {
"trx_id": "TX-1793900012345",
"ref_id": "INV-1001",
"status": "SUCCESS",
"sn": "DGPS261105213012345678901",
"message": "Transaksi sukses",
...
}
}
Saat status transaksi menjadi final, NEOS mengirim POST ke callback URL Anda:
POST https://api.perusahaan.co.id/neos/callback
Content-Type: application/json
X-Neos-Timestamp: 1793900042
X-Neos-Signature: 5f0c...e91a
{
"event": "transaction.updated",
"data": {
"trx_id": "TX-1793900012345",
"ref_id": "INV-1001",
"type": "DATA",
"product_code": "DATA-00110944",
"product_name": "Super Seru Promo 7 Hari",
"msisdn": "081234567890",
"price": 22800,
"status": "SUCCESS",
"sn": "DGPS261105213012345678901",
"message": "Transaksi sukses",
"created_at": "2026-11-05 21:30:12",
"updated_at": "2026-11-05 21:30:41"
}
}
X-Neos-Signature = HMAC-SHA256 (hex) dari timestamp + "." + body mentah dengan callback secret (menu Pengaturan). Tolak callback bila signature tidak cocok atau timestamp lebih dari 5 menit.
<?php
$body = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_NEOS_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_NEOS_SIGNATURE'] ?? '';
$hitung = hash_hmac('sha256', $ts . '.' . $body, CALLBACK_SECRET);
if (!hash_equals($hitung, $sig) || abs(time() - (int) $ts) > 300) {
http_response_code(401);
exit;
}
$data = json_decode($body, true)['data'];
// update transaksi berdasarkan $data['ref_id'] dan $data['status'] (idempoten)
http_response_code(200);
Balas HTTP 2xx dalam 15 detik. Bila tidak, callback diulang hingga 6 kali (1 menit, 5 menit, 15 menit, 1 jam, 2 jam). Callback bisa terkirim lebih dari sekali — proses secara idempoten berdasarkan ref_id. Riwayat pengiriman ada di menu Log.
| Status | Arti | Saldo |
|---|---|---|
| PENDING | Diterima, sedang diproses operator. | Sudah dipotong |
| SUCCESS | Berhasil. sn berisi nomor seri / referensi operator. | Tetap terpotong |
| FAILED | Gagal. Alasan di message. | Dikembalikan otomatis |
Sebagian besar transaksi selesai dalam hitungan detik. Bila operator belum memberi jawaban pasti, status tetap PENDING dan terus dicek otomatis — transaksi PENDING tidak boleh diulang dengan ref_id baru.
| HTTP | Kode | Arti |
|---|---|---|
| 401 | UNAUTHORIZED | API key kosong atau tidak valid |
| 403 | IP_NOT_WHITELISTED | IP sumber belum terdaftar |
| 403 | ACCOUNT_INACTIVE | Akun belum aktif / ditangguhkan |
| 403 | PRODUCT_DISABLED | Produk tidak aktif untuk akun Anda |
| 402 | INSUFFICIENT_BALANCE | Saldo tidak cukup |
| 409 | DUPLICATE_REF_ID | ref_id sudah dipakai (data transaksi lama ikut dikirim) |
| 422 | INVALID_MSISDN / INVALID_REF_ID / INVALID_PRODUCT | Parameter tidak valid |
| 422 | PRODUCT_UNAVAILABLE | Produk tidak tersedia untuk nomor tujuan saat ini |
| 404 | TRANSACTION_NOT_FOUND / NOT_FOUND | Transaksi / endpoint tidak ditemukan |
| 405 | METHOD_NOT_ALLOWED | Metode HTTP salah |
| 503 | SERVICE_UNAVAILABLE / PRODUCT_UNAVAILABLE | Layanan sementara tidak tersedia, coba lagi |
curl https://b2b.neos.id/api/v1/products/data?msisdn=081234567890 \
-H "X-Api-Key: $NEOS_API_KEY"
curl -X POST https://b2b.neos.id/api/v1/transaction \
-H "X-Api-Key: $NEOS_API_KEY" -H "Content-Type: application/json" \
-d '{"ref_id":"INV-1001","msisdn":"081234567890","product_code":"PULSA-10000"}'
<?php
function neos($method, $path, $body = null) {
$ch = curl_init('https://b2b.neos.id/api/v1' . $path);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_HTTPHEADER => ['X-Api-Key: ' . getenv('NEOS_API_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
return $res;
}
$produk = neos('GET', '/products/data?msisdn=081234567890');
$trx = neos('POST', '/transaction', [
'ref_id' => 'INV-1001',
'msisdn' => '081234567890',
'product_code' => $produk['data']['products'][0]['product_code'],
]);
echo $trx['data']['status']; // PENDING
const res = await fetch('https://b2b.neos.id/api/v1/transaction', {
method: 'POST',
headers: { 'X-Api-Key': process.env.NEOS_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ ref_id: 'INV-1001', msisdn: '081234567890', product_code: 'PULSA-10000' }),
});
const json = await res.json();