Dokumentasi API
Dengan LisansX REST API, Anda dapat menarik daftar produk dan stok ke situs Anda sendiri, melakukan pemesanan, dan menerima kode pengiriman secara instan. Autentikasi, endpoint, serta contoh PHP, Node.js, dan Python tersedia di bawah ini.
Kunci API hanya diberikan kepada reseller. Siapa pun dapat membaca dokumentasi ini; untuk mengirim permintaan diperlukan paket reseller yang aktif. Kunci Anda dibuat saat pengajuan reseller Anda disetujui.
Autentikasi
Setiap permintaan ditandatangani dengan tiga header. Karena tanda tangan mencakup stempel waktu, metode HTTP, path, dan body mentah sekaligus, permintaan tidak dapat diubah selama pengiriman maupun diputar ulang.
| Header | Nilai |
|---|---|
X-Api-Key | Kunci API Anda |
X-Timestamp | Detik Unix — harus berada dalam rentang ±300 detik dari waktu server |
X-Signature | Tanda tangan hex yang dibuat dengan rumus di bawah ini |
signingKey = sha256_hex(api_secret) signature = hmac_sha256_hex(signingKey, timestamp + "\n" + METHOD + "\n" + path + "\n" + rawBody)
- path: path beserta string kueri, jika ada (
/api/v1/products?limit=50). Parameter kueri juga termasuk dalam tanda tangan — tandatangani persis URL yang Anda kirimkan. - rawBody: JSON yang Anda kirim apa adanya; string kosong untuk permintaan GET.
- Jangan melakukan serialisasi ulang body setelah menandatanganinya — perbedaan sekecil apa pun akan merusak tanda tangan.
Endpoint
| Metode | Path | Deskripsi |
|---|---|---|
| GET | /api/v1/products |
Semua produk yang dijual, dengan harga reseller Anda |
| GET | /api/v1/products/{id} |
Detail satu produk dan status stok |
| POST | /api/v1/order |
Buat pesanan — mengembalikan kode pengiriman jika berhasil |
| GET | /api/v1/order/{order_no} |
Status pesanan dan kode yang telah dikirim |
| GET | /api/v1/balance |
Saldo Anda saat ini |
Batas permintaan per menit ditetapkan per akun reseller. Jika terlampaui, 429 rate_limited akan dikembalikan. Semua respons kesalahan menggunakan format {"success": false, "error": "...", "message": "..."}.
Contoh Integrasi
Siap disalin dan ditempel
<?php
final class LisansXClient
{
public function __construct(
private string $baseUrl,
private string $apiKey,
private string $apiSecret
) { $this->baseUrl = rtrim($baseUrl, '/'); }
public function request(string $method, string $path, ?array $body = null): array
{
$method = strtoupper($method);
$bodyRaw = $body !== null ? json_encode($body, JSON_UNESCAPED_UNICODE) : '';
$ts = (string)time();
// Kunci penandatanganan = hasil hex SHA-256 dari secret mentah
$signingKey = hash('sha256', $this->apiSecret);
$signature = hash_hmac('sha256', $ts . "\n" . $method . "\n" . $path . "\n" . $bodyRaw, $signingKey);
$ch = curl_init($this->baseUrl . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'X-Api-Key: ' . $this->apiKey,
'X-Timestamp: ' . $ts,
'X-Signature: ' . $signature,
'Content-Type: application/json',
],
]);
if ($body !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyRaw);
$raw = curl_exec($ch);
return json_decode((string)$raw, true) ?: ['success' => false, 'error' => 'invalid_response'];
}
}
// --- Penggunaan ---
$api = new LisansXClient('https://lisansx.net', 'KUNCI_API_ANDA', getenv('LISANSX_SECRET'));
$products = $api->request('GET', '/api/v1/products');
$order = $api->request('POST', '/api/v1/order', ['product_id' => 1, 'qty' => 1]);
if (!empty($order['success'])) {
foreach ($order['data']['codes'] as $code) {
echo "Teslim edilen kod: $code\n";
}
} else {
error_log('LisansX hatasi: ' . ($order['message'] ?? 'bilinmiyor'));
}
Kesalahan Umum
401 invalid_signature- Anda mungkin melewatkan penurunan kunci penandatanganan sebagai
sha256(secret). 401 invalid_timestamp- Jam server Anda tidak sinkron. Sinkronkan dengan NTP.
403 ip_not_allowed- Pembatasan IP telah ditetapkan dan permintaan Anda berasal dari IP yang tidak ada dalam daftar.
409 replayed_request- Permintaan POST bertanda tangan yang sama diterima untuk kedua kalinya (perlindungan replay). Tandatangani setiap permintaan dengan timestamp baru; jika Anda membuat dua pesanan untuk produk yang sama dalam detik yang sama, tambahkan kolom
"nonce"yang unik ke body (mis. nomor pesanan Anda sendiri). 429 rate_limited- Anda telah melampaui batas per menit; sebarkan permintaan Anda dari waktu ke waktu.
409 out_of_stock- Produk tidak tersedia atau tidak tersedia dalam jumlah yang diminta (kolom
availablemenunjukkan sisa jumlah). Pesanan tidak dibuat dan saldo tidak dipotong. Periksa stok denganGET /api/v1/products/{id}sebelum menerima pembayaran dari pelanggan Anda; webhookstock.changedmemberi tahu Anda seketika saat produk habis atau tersedia kembali. 409 price_changed- Jika Anda mengirim
"max_unit_price"opsional bersama pesanan dan harga satuan saat ini melebihinya, pesanan tidak dibuat;unit_pricemenunjukkan harga saat ini. 402 delivery_failed- Pesanan telah dibuat tetapi produk tidak dapat dikirim (mis. habis di sumber pada saat terakhir). Jumlahnya dikembalikan ke saldo Anda secara otomatis.