Skip to main content

Autentikasi & Signature

Setiap request ke API harus menyertakan 3 parameter ini di dalam body request:

ParameterKeterangan
api_idAPI ID anda yang sudah di setting di pengaturan
timestampWaktu saat request dikirim, dalam format UNIX timestamp
signatureSignature untuk validasi request, dihasilkan dari kombinasi parameter dan secret key
Toleransi timestamp ±30 detik

timestamp divalidasi ketat — hanya diterima jika selisihnya maksimal 30 detik dari waktu server IsiKuota. Pastikan jam server Anda tersinkronisasi via NTP, kalau tidak semua request akan gagal dengan SESSION_EXPIRED meski signature benar.

Signature sekali pakai & rate limit
  • Setiap signature hanya bisa dipakai satu kali — mengirim ulang signature yang sama (retry naif) akan ditolak dengan DUPLICATE_TRANSACTION. Selalu generate timestamp + signature baru untuk setiap request, termasuk saat retry.

Cara Mendapatkan API Key​

  1. Login ke Dashboard IsiKuota
  2. Buka Pengaturan → API
  3. Salin api_id, api_key, dan secret_key
danger

Jangan pernah membagikan api_key dan secret_key kepada siapapun. Simpan dengan aman di environment variables atau konfigurasi server Anda.


Cara Membuat Signature​

Signature berfungsi seperti tanda tangan digital

  1. Membuktikan bahwa request benar-benar dikirim oleh Anda (autentikasi)
  2. Isi body request tidak dimodifikasi dalam perjalanan (integritas)

Server akan menolak request yang signature-nya tidak cocok.

Formula Signature:​

hash_hmac('sha256', 
api_id|api_key|timestamp|body_hash
, SecretKey)

Penjelasan Per Langkah​

Langkah 1 — Komponen Signature:

ParameterKeterangan
api_idAPI ID Anda
api_keyAPI Key Anda
timestampWaktu saat request dikirim UNIX timestamp (detik)
body_hashSHA-256 dari raw body request. Jika request tidak memiliki body, gunakan hash dari string kosong: hash('sha256', '')

Langkah 2 — Gabungkan keempat komponen dengan karakter | (pipe):

api_id|api_key|timestamp|body_hash

Langkah 3 — Buat HMAC-SHA256 dari string di atas menggunakan SecretKey Anda:

$bodyHash = hash('sha256', $canonicalBody);
$stringToSign = implode('|', [$api_id, $api_key, $timestamp, $bodyHash]);
$signature = hash_hmac('sha256', $stringToSign, 'your_secret_key');

Langkah 4 — Urutkan parameter bisnis dari A ke Z

Sebelum di-hash, semua parameter bisnis harus diurutkan berdasarkan nama kunci secara alfabetis menggunakan ksort. Ini memastikan urutan kunci selalu konsisten antara sisi Anda dan server IsiKuota.

ksort($businessParams);
// Sebelum: customer_no, code, cmd
// Sesudah: cmd, code, customer_no ✓
warning

Jika urutan berbeda, body_hash yang dihasilkan akan berbeda dan signature akan ditolak server.


Langkah 5 — Encode menjadi JSON string lalu hitung body_hash

Jadikan parameter bisnis yang sudah diurutkan sebagai JSON tanpa spasi tambahan, lalu hash dengan SHA-256.

$canonicalBody = json_encode($businessParams, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// Hasil: {"cmd":"prepaid","code":"TSEL5","customer_no":"08123456789"}

$body_hash = hash('sha256', $canonicalBody);

Jika tidak ada parameter bisnis (seperti saat cek saldo), gunakan string kosong: hash('sha256', '').


Contoh Kode Lengkap​

<?php
header('Content-Type: application/json');

$api_id = 'your_api_id';
$api_key = 'your_api_key';
$secret_key = 'your_secret_key';
$timestamp = time();

// Parameter bisnis (tanpa api_id, timestamp, signature)
$businessParams = [
'cmd' => 'prepaid',
'code' => 'TSEL5',
'customer_no' => '08123456789',
'ref_id' => "TRX12345asdxxx", // Opsional, untuk id unik di sistem Anda
'testing' => true, // Opsional, untuk mode testing (tidak memproses transaksi nyata)
];

// Urutkan A ke Z
ksort($businessParams);

// Jadikan JSON (kosong jika tidak ada parameter bisnis)
$canonicalBody = empty($businessParams)
? ''
: json_encode($businessParams, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

// Hitung signature
$bodyHash = hash('sha256', $canonicalBody);
$stringToSign = implode('|', [$api_id, $api_key, $timestamp, $bodyHash]);
$signature = hash_hmac('sha256', $stringToSign, $secret_key);

// Kirim request
$payload = array_merge($businessParams, [
'api_id' => $api_id,
'timestamp' => $timestamp,
'signature' => $signature,
]);

$ch = curl_init('https://api.isikuota.com/v1/transaction');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = json_decode(curl_exec($ch), true);
// print_r($response);
echo json_encode($response, JSON_PRETTY_PRINT);

Cek Saldo (Tanpa Parameter Bisnis)​

Untuk endpoint yang tidak punya parameter tambahan, canonicalBody cukup diisi string kosong:

$bodyHash = hash('sha256', ''); // string kosong
$stringToSign = implode('|', [$api_id, $api_key, $timestamp, $bodyHash]);
$signature = hash_hmac('sha256', $stringToSign, $secret_key);

Signature Salah? Cek Ini​

ErrorPenyebab Umum
INVALID_SIGNATUREParameter bisnis tidak diurutkan A–Z, atau secret_key salah
UNAUTHORIZEDapi_id tidak ditemukan
INVALID_API_KEYapi_key salah
SESSION_EXPIREDtimestamp berbeda lebih dari 30 detik dari waktu server — pastikan jam server Anda tersinkronisasi (NTP)
IP_NOT_ALLOWEDIP server Anda tidak ada di whitelist IP akun
DUPLICATE_TRANSACTIONsignature yang sama dikirim ulang — signature hanya bisa dipakai satu kali (proteksi replay attack), buat signature baru untuk setiap request
TOO_MANY_REQUESTSMelebihi batas 1000 request/menit per api_id
Checklist debugging
  • Parameter bisnis sudah diurutkan A ke Z (ksort)
  • api_key yang dipakai di stringToSign, bukan api_id
  • timestamp dalam detik, bukan milidetik
  • JSON tidak ada spasi tambahan (JSON_UNESCAPED_SLASHES)