توثيق API

باستخدام LisansX REST API يمكنك جلب قائمة المنتجات والمخزون إلى موقعك الخاص، وتقديم الطلبات واستلام رموز التسليم فورًا. تجد أدناه المصادقة ونقاط النهاية وأمثلة بلغات PHP وNode.js وPython.

تُمنح مفاتيح API للموزّعين فقط. يمكن للجميع الاطلاع على التوثيق؛ أما إرسال الطلبات فيتطلب باقة موزّع نشطة. يُنشأ مفتاحك عند الموافقة على طلب الانضمام كموزّع.

المصادقة

يُوقَّع كل طلب باستخدام ثلاث ترويسات. ولأن التوقيع يشمل الطابع الزمني وطريقة HTTP والمسار والمحتوى الخام معًا، فلا يمكن تعديل الطلب أثناء النقل أو إعادة إرساله.

الترويسةالقيمة
X-Api-Keyمفتاح API الخاص بك
X-Timestampثوانٍ بتوقيت Unix — يجب أن يكون ضمن ±300 ث من توقيت الخادم
X-Signatureتوقيع بصيغة hex يُنشأ وفق الصيغة أدناه
signingKey = sha256_hex(api_secret)
signature  = hmac_sha256_hex(signingKey, timestamp + "\n" + METHOD + "\n" + path + "\n" + rawBody)
  • path: المسار مع سلسلة الاستعلام إن وُجدت (/api/v1/products?limit=50). معلمات الاستعلام جزء من التوقيع أيضًا — وقِّعوا العنوان نفسه الذي ترسلون الطلب إليه تمامًا.
  • rawBody: نص JSON الذي ترسلونه كما هو حرفيًا؛ وسلسلة فارغة في طلبات GET.
  • لا تُعيدوا تسلسل نص الطلب بعد توقيعه — فأدنى اختلاف يُفسد التوقيع.

نقاط النهاية

الطريقةالمسارالوصف
GET /api/v1/products جميع المنتجات المعروضة للبيع بأسعار الموزّع الخاصة بكم
GET /api/v1/products/{id} تفاصيل منتج واحد وحالة المخزون
POST /api/v1/order إنشاء طلب — تُعاد رموز التسليم عند النجاح
GET /api/v1/order/{order_no} حالة الطلب والرموز المُسلَّمة
GET /api/v1/balance رصيدكم الحالي

يُحدَّد حدّ الطلبات في الدقيقة لكل حساب موزّع. عند تجاوزه يُعاد 429 rate_limited. جميع ردود الأخطاء بالتنسيق {"success": false, "error": "...", "message": "..."}.

أمثلة التكامل

جاهزة للنسخ واللصق

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

        // مفتاح التوقيع = تجزئة SHA-256 بصيغة hex للـ secret الخام
        $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'];
    }
}

// --- الاستخدام ---
$api = new LisansXClient('https://lisansx.net', 'YOUR_API_KEY', 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'));
}

الأخطاء الشائعة

401 invalid_signature
ربما أغفلتم اشتقاق مفتاح التوقيع بصيغة sha256(secret).
401 invalid_timestamp
ساعة الخادم لديكم غير متزامنة. يُرجى مزامنتها عبر NTP.
403 ip_not_allowed
يوجد تقييد لعناوين IP، وطلبكم صادر من عنوان IP غير مدرج في القائمة.
409 replayed_request
وصل طلب POST الموقَّع نفسه مرة ثانية (حماية من إعادة الإرسال). وقِّعوا كل طلب بطابع زمني جديد؛ وإذا كنتم ستقدّمون طلبين للمنتج نفسه في الثانية نفسها، فأضيفوا إلى نص الطلب حقل "nonce" فريدًا (مثل رقم الطلب الخاص بكم).
429 rate_limited
لقد تجاوزتم الحدّ المسموح في الدقيقة؛ يُرجى توزيع طلباتكم على فترات زمنية.
409 out_of_stock
المنتج غير متوفر في المخزون أو غير متوفر بالكمية المطلوبة (يُبيّن الحقل available الكمية المتبقية). لا يُنشأ أي طلب ولا يُخصم أي رصيد. تحقّقوا من المخزون عبر GET /api/v1/products/{id} قبل تحصيل الدفع من عميلكم؛ ويُعلمكم الـ webhook stock.changed فورًا عند نفاد المنتج أو عودته.
409 price_changed
إذا أرسلتم الحقل الاختياري "max_unit_price" مع الطلب وكان سعر الوحدة الحالي يتجاوزه، فلن يُنشأ الطلب؛ ويُبيّن unit_price السعر الحالي.
402 delivery_failed
أُنشئ الطلب لكن تعذّر تسليم المنتج (مثلًا نفد من المصدر في اللحظة الأخيرة). يُعاد المبلغ تلقائيًا إلى رصيدكم.
راسلنا عبر Telegram فتح طلب دعم