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.

HeaderNilai
X-Api-KeyKunci API Anda
X-TimestampDetik Unix — harus berada dalam rentang ±300 detik dari waktu server
X-SignatureTanda 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

MetodePathDeskripsi
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 available menunjukkan sisa jumlah). Pesanan tidak dibuat dan saldo tidak dipotong. Periksa stok dengan GET /api/v1/products/{id} sebelum menerima pembayaran dari pelanggan Anda; webhook stock.changed memberi 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_price menunjukkan 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.
Kirim Pesan via Telegram Buat Tiket Dukungan