Documentazione API

Con l'API REST di LisansX puoi importare l'elenco dei prodotti e le disponibilità sul tuo sito, effettuare ordini e ricevere immediatamente i codici di consegna. Di seguito trovi autenticazione, endpoint ed esempi in PHP, Node.js e Python.

Le chiavi API vengono rilasciate solo ai rivenditori. Chiunque può consultare la documentazione; per inviare richieste è necessario un pacchetto rivenditore attivo. La tua chiave viene creata quando la tua richiesta di diventare rivenditore viene approvata.

Autenticazione

Ogni richiesta è firmata con tre intestazioni. Poiché la firma copre insieme timestamp, metodo HTTP, percorso e corpo grezzo, la richiesta non può essere alterata durante il transito né riprodotta.

IntestazioneValore
X-Api-KeyLa tua chiave API
X-TimestampSecondi Unix — deve rientrare in ±300 s rispetto all'ora del server
X-SignatureFirma esadecimale generata con la formula seguente
signingKey = sha256_hex(api_secret)
signature  = hmac_sha256_hex(signingKey, timestamp + "\n" + METHOD + "\n" + path + "\n" + rawBody)
  • path: il percorso più la stringa di query, se presente (/api/v1/products?limit=50). Anche i parametri di query fanno parte della firma: firmi esattamente l'URL che richiede.
  • rawBody: il JSON esatto che invia; una stringa vuota per le richieste GET.
  • Non riserializzi il corpo dopo averlo firmato: anche la minima differenza invalida la firma.

Endpoint

MetodoPercorsoDescrizione
GET /api/v1/products Tutti i prodotti in vendita, ai Suoi prezzi rivenditore
GET /api/v1/products/{id} Dettagli di un singolo prodotto e disponibilità
POST /api/v1/order Crea un ordine: in caso di successo restituisce i codici di consegna
GET /api/v1/order/{order_no} Stato dell'ordine e codici consegnati
GET /api/v1/balance Il Suo saldo attuale

Il limite di richieste al minuto è definito per ciascun account rivenditore. Se superato, viene restituito 429 rate_limited. Tutte le risposte di errore usano il formato {"success": false, "error": "...", "message": "..."}.

Esempi di integrazione

Pronti da copiare e incollare

<?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();

        // Chiave di firma = digest esadecimale SHA-256 del secret grezzo
        $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'];
    }
}

// --- Utilizzo ---
$api = new LisansXClient('https://lisansx.net', 'LA_TUA_CHIAVE_API', 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'));
}

Errori comuni

401 invalid_signature
Potrebbe aver tralasciato di derivare la chiave di firma come sha256(secret).
401 invalid_timestamp
L'orologio del Suo server non è sincronizzato. Lo sincronizzi tramite NTP.
403 ip_not_allowed
È impostata una restrizione IP e la Sua richiesta proviene da un IP non presente nell'elenco.
409 replayed_request
La stessa richiesta POST firmata è arrivata una seconda volta (protezione contro il replay). Firmi ogni richiesta con un nuovo timestamp; se effettua due ordini per lo stesso prodotto nello stesso secondo, aggiunga al corpo un campo "nonce" univoco (ad es. il Suo numero d'ordine).
429 rate_limited
Ha superato il limite al minuto; distribuisca le richieste nel tempo.
409 out_of_stock
Il prodotto non è disponibile o non nella quantità richiesta (il campo available indica la quantità rimanente). Nessun ordine viene creato e nessun importo viene addebitato sul saldo. Verifichi la disponibilità con GET /api/v1/products/{id} prima di incassare il pagamento dal Suo cliente; il webhook stock.changed La avvisa immediatamente quando un prodotto si esaurisce o torna disponibile.
409 price_changed
Se ha inviato con l'ordine il parametro facoltativo "max_unit_price" e il prezzo unitario attuale lo supera, l'ordine non viene creato; unit_price indica il prezzo attuale.
402 delivery_failed
L'ordine è stato creato ma il prodotto non è stato consegnato (ad es. si è esaurito alla fonte all'ultimo momento). L'importo viene rimborsato automaticamente sul Suo saldo.
Scrivici su Telegram Apri un ticket di assistenza