Documentação da API

Com a API REST da LisansX, você pode importar a lista de produtos e o estoque para o seu próprio site, fazer pedidos e receber os códigos de entrega instantaneamente. Autenticação, endpoints e exemplos em PHP, Node.js e Python estão abaixo.

As chaves de API são fornecidas somente a revendedores. Qualquer pessoa pode consultar a documentação; para enviar requisições, é necessário um pacote de revendedor ativo. Sua chave é criada quando sua solicitação de revendedor é aprovada.

Autenticação

Cada requisição é assinada com três cabeçalhos. Como a assinatura abrange em conjunto o timestamp, o método HTTP, o caminho e o corpo bruto, a requisição não pode ser alterada no trajeto nem reenviada.

CabeçalhoValor
X-Api-KeySua chave de API
X-TimestampSegundos Unix — deve estar dentro de ±300 s do horário do servidor
X-SignatureAssinatura hex gerada com a fórmula abaixo
signingKey = sha256_hex(api_secret)
signature  = hmac_sha256_hex(signingKey, timestamp + "\n" + METHOD + "\n" + path + "\n" + rawBody)
  • path: o caminho e a string de consulta, se houver (/api/v1/products?limit=50). Os parâmetros de consulta também fazem parte da assinatura — assine exatamente o endereço que você solicita.
  • rawBody: exatamente o JSON que você envia; uma string vazia em requisições GET.
  • Não serialize novamente o corpo após assiná-lo — até a menor diferença invalida a assinatura.

Endpoints

MétodoCaminhoDescrição
GET /api/v1/products Todos os produtos à venda, com seus preços de revendedor
GET /api/v1/products/{id} Detalhes de um produto e status do estoque
POST /api/v1/order Criar um pedido — retorna os códigos de entrega em caso de sucesso
GET /api/v1/order/{order_no} Status do pedido e códigos entregues
GET /api/v1/balance Seu saldo atual

O limite de requisições por minuto é definido por conta de revendedor. Quando excedido, é retornado 429 rate_limited. Todas as respostas de erro usam o formato {"success": false, "error": "...", "message": "..."}.

Exemplos de Integração

Prontos para copiar e colar

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

        // Chave de assinatura = digest hex SHA-256 do secret bruto
        $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'];
    }
}

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

Erros Comuns

401 invalid_signature
Talvez você não tenha derivado a chave de assinatura como sha256(secret).
401 invalid_timestamp
O relógio do seu servidor está dessincronizado. Sincronize-o com NTP.
403 ip_not_allowed
Há uma restrição de IP definida e sua requisição vem de um IP que não está na lista.
409 replayed_request
A mesma requisição POST assinada chegou pela segunda vez (proteção contra repetição). Assine cada requisição com um novo timestamp; se for fazer dois pedidos do mesmo produto no mesmo segundo, adicione ao corpo um campo "nonce" único (ex.: o seu próprio número de pedido).
429 rate_limited
Você excedeu o limite por minuto; distribua suas requisições ao longo do tempo.
409 out_of_stock
O produto está fora de estoque ou não está disponível na quantidade solicitada (o campo available informa a quantidade restante). Nenhum pedido é criado e nenhum saldo é cobrado. Verifique o estoque com GET /api/v1/products/{id} antes de receber o pagamento do seu cliente; o webhook stock.changed avisa instantaneamente quando um produto esgota ou volta ao estoque.
409 price_changed
Se você enviou o campo opcional "max_unit_price" com o pedido e o preço unitário atual o excede, nenhum pedido é criado; unit_price informa o preço atual.
402 delivery_failed
O pedido foi criado, mas o produto não pôde ser entregue (ex.: esgotou na origem no último momento). O valor é reembolsado automaticamente ao seu saldo.
Enviar mensagem pelo Telegram Abrir Chamado de Suporte