API-Dokumentation

Mit der LisansX REST API können Sie die Produktliste und Lagerbestände in Ihre eigene Website übernehmen, Bestellungen aufgeben und Liefercodes sofort erhalten. Authentifizierung, Endpunkte sowie Beispiele in PHP, Node.js und Python finden Sie unten.

API-Schlüssel werden nur an Wiederverkäufer vergeben. Die Dokumentation ist für alle einsehbar; zum Senden von Anfragen ist ein aktives Wiederverkäuferpaket erforderlich. Ihr Schlüssel wird erstellt, sobald Ihre Wiederverkäuferbewerbung genehmigt wurde.

Authentifizierung

Jede Anfrage wird mit drei Headern signiert. Da die Signatur Zeitstempel, HTTP-Methode, Pfad und Rohdaten des Bodys gemeinsam abdeckt, kann eine Anfrage unterwegs weder verändert noch erneut abgespielt werden.

HeaderWert
X-Api-KeyIhr API-Schlüssel
X-TimestampUnix-Sekunden — muss innerhalb von ±300 s der Serverzeit liegen
X-SignatureHex-Signatur, erzeugt mit der folgenden Formel
signingKey = sha256_hex(api_secret)
signature  = hmac_sha256_hex(signingKey, timestamp + "\n" + METHOD + "\n" + path + "\n" + rawBody)
  • path: der Pfad sowie ggf. der Query-String (/api/v1/products?limit=50). Auch Query-Parameter sind Teil der Signatur – signieren Sie genau die URL, die Sie aufrufen.
  • rawBody: exakt das JSON, das Sie senden; bei GET-Anfragen ein leerer String.
  • Serialisieren Sie nicht erneut Sie den Body nach dem Signieren – schon die kleinste Abweichung macht die Signatur ungültig.

Endpunkte

MethodePfadBeschreibung
GET /api/v1/products Alle verfügbaren Produkte zu Ihren Händlerpreisen
GET /api/v1/products/{id} Details und Lagerstatus eines einzelnen Produkts
POST /api/v1/order Bestellung erstellen – liefert bei Erfolg die Lieferungscodes
GET /api/v1/order/{order_no} Bestellstatus und gelieferte Codes
GET /api/v1/balance Ihr aktuelles Guthaben

Das Anfragelimit pro Minute wird je Händlerkonto festgelegt. Bei Überschreitung wird 429 rate_limited zurückgegeben. Alle Fehlerantworten haben das Format {"success": false, "error": "...", "message": "..."}.

Integrationsbeispiele

Sofort einsatzbereit per Copy & Paste

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

        // Signaturschlüssel = SHA-256-Hex-Digest des rohen Secrets
        $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'];
    }
}

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

Häufige Fehler

401 invalid_signature
Möglicherweise haben Sie das Ableiten des Signaturschlüssels als sha256(secret) übersprungen.
401 invalid_timestamp
Die Uhrzeit Ihres Servers weicht ab. Synchronisieren Sie sie per NTP.
403 ip_not_allowed
Es ist eine IP-Beschränkung eingerichtet und Ihre Anfrage stammt von einer IP, die nicht auf der Liste steht.
409 replayed_request
Dieselbe signierte POST-Anfrage ist ein zweites Mal eingegangen (Replay-Schutz). Signieren Sie jede Anfrage mit einem neuen Zeitstempel; wenn Sie in derselben Sekunde zwei Bestellungen für dasselbe Produkt aufgeben, fügen Sie dem Body ein eindeutiges Feld "nonce" hinzu (z. B. Ihre eigene Bestellnummer).
429 rate_limited
Sie haben das Limit pro Minute überschritten; verteilen Sie Ihre Anfragen zeitlich.
409 out_of_stock
Das Produkt ist nicht auf Lager oder nicht in der gewünschten Menge verfügbar (das Feld available gibt die verbleibende Menge an). Es wird keine Bestellung erstellt und kein Guthaben abgebucht. Prüfen Sie den Bestand mit GET /api/v1/products/{id}, bevor Sie die Zahlung Ihres eigenen Kunden entgegennehmen; der Webhook stock.changed benachrichtigt Sie sofort, wenn ein Produkt ausverkauft oder wieder verfügbar ist.
409 price_changed
Wenn Sie mit der Bestellung den optionalen Wert "max_unit_price" gesendet haben und der aktuelle Stückpreis diesen übersteigt, wird keine Bestellung erstellt; unit_price gibt den aktuellen Preis an.
402 delivery_failed
Die Bestellung wurde erstellt, das Produkt konnte jedoch nicht geliefert werden (z. B. weil es an der Quelle im letzten Moment ausverkauft war). Der Betrag wird Ihrem Guthaben automatisch erstattet.
Über Telegram schreiben Support-Ticket eröffnen