التوثيق

كل ما تحتاج لمعرفته

البداية

مرحباً بك في SmartPOS AI! سيساعدك هذا الدليل في تشغيل نظام نقطة البيع بسرعة.

الإعداد

SmartPOS AI حل سحابي، لذا لا حاجة لتثبيت برنامج. ببساطة:

  • أنشئ حسابك على smartposai.com/register
  • التحقق من عنوان بريدك الإلكتروني
  • إعداد الملف التعريفي لنشاطك التجاري
  • أضف منتجاتك الأولى

الإعدادات

بعد التسجيل، اضبط إعداداتك في المكتب الخلفي:

  • تفاصيل العمل: الاسم والعنوان والمعلومات الضريبية
  • معدلات الضرائب: قم بتكوين معدلات الضرائب الإقليمية
  • طرق الدفع: تمكين خيارات الدفع نقدًا وبطاقة وخيارات الدفع الأخرى
  • إعدادات الإيصال: تخصيص تخطيط الإيصال

مصادقة API

يوفر SmartPOS API وصولاً للقراءة فقط لمنتجاتك وإيصالاتك وورديتك. يتطلب وصول API الخطة الاحترافية أو أعلى.

الحصول على مفتاح API الخاص بك

  1. قم بتسجيل الدخول إلى المكتب الخلفي
  2. انتقل إلى الإعدادات ← API
  3. انقر على إنشاء مفتاح واجهة برمجة التطبيقات
  4. انسخ المفتاح فورًا — لن يظهر كاملاً مرة أخرى

قم بتضمين مفتاح API الخاص بك في رأس X-API-Key مع كل طلب:

# طلب نموذجي حليقة -X احصل على "https://yoursubdomain.smartposai.com/api/v1/products" \ -H "X-API-Key: spos_live_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

🔐 حافظ على أمان مفتاح API الخاص بك

لا تكشف مطلقًا عن مفتاح API الخاص بك في التعليمات البرمجية من جانب العميل أو المستودعات العامة. استخدم متغيرات البيئة لتخزين بيانات الاعتماد الحساسة. يمكنك إعادة إنشاء مفتاحك في أي وقت في الإعدادات ← API.

Base URL

تستخدم جميع نقاط نهاية واجهة برمجة التطبيقات نطاقك الفرعي كعنوان URL الأساسي:

https://{your-subdomain}.smartposai.com/api/v1/

API المنتجات

استرجاع كتالوج المنتجات ومستويات المخزون.

GET /api/v1/products

قم بإدراج جميع المنتجات ذات التصفية الاختيارية

معلمات الاستعلام

  • store_id — التصفية حسب المتجر (عدد صحيح)
  • category_id — التصفية حسب الفئة (عدد صحيح)
  • status — التصفية حسب الحالة: active أو inactive (الافتراضي: الكل)
  • limit — النتائج لكل صفحة (الافتراضي: 50، الحد الأقصى: 200)
  • offset — إزاحة الصفحات (الافتراضي: 0)

مثال للإجابة

{ "success": true, "data": [ { "id": 1, "sku": "ESP-001", "name": "Espresso", "price": "2.50", "cost": "0.80", "tax_rate": "20.00", "stock": 150, "category_id": 3, "status": "active", "image_url": null, "created_at": "2025-01-15 10:30:00" } ]، "الإجمالي": 84، "الحد": 50, "إزاحة": 0 }
GET /api/v1/products/{id}

احصل على منتج واحد بمستويات مخزون لكل متجر

مثال للإجابة

{ "success": true, "data": { "id": 1, "sku": "ESP-001", "name": "Espresso", "price": "2.50", "cost": "0.80", "tax_rate": "20.00", "stock": 150, "category_id": 3, "status": "active", "stores": [ { "store_id": 1, "store_name": "Main Store", "stock": 100 }, { "store_id": 2, "store_name": "Downtown", "stock": 50 } ] } }

API الإيصالات

الوصول للإيصالات المكتملة وعناصرها.

GET /api/v1/receipts

إدراج الإيصالات مع النطاق الزمني وتصفية المتجر

معلمات الاستعلام

  • start_date — تاريخ البدء بالتنسيق YYYY-MM-DD
  • end_date — تاريخ الانتهاء بالتنسيق YYYY-MM-DD
  • store_id — التصفية حسب المتجر (عدد صحيح)
  • limit — النتائج لكل صفحة (الافتراضي: 50، الحد الأقصى: 200)
  • offset — إزاحة الصفحات (الافتراضي: 0)

مثال للإجابة

{ "success": true, "data": [ { "id": 1042, "order_number": "ORD-20250130-0042", "total": "45.80", "subtotal": "38.17", "tax_total": "7.63", "discount_total": "0.00", "payment_method": "cash", "status": "completed", "customer_name": "John Doe", "created_at": "2025-01-30 14:22:05" } ]، "الإجمالي": 1042، "الحد": 50, "إزاحة": 0 }
GET /api/v1/receipts/{id}

احصل على إيصال واحد بجميع البنود

مثال للإجابة

{ "success": true, "data": { "id": 1042, "order_number": "ORD-20250130-0042", "total": "45.80", "subtotal": "38.17", "tax_total": "7.63", "discount_total": "0.00", "payment_method": "cash", "status": "completed", "customer_name": "John Doe", "created_at": "2025-01-30 14:22:05", "items": [ { "product_name": "Espresso", "quantity": 2, "price": "2.50", "discount": "0.00", "tax": "1.00", "total": "6.00" } ] } }

API الورديات

الوصول لبيانات ورديات الموظفين بما في ذلك تتبع النقد وإجمالي المبيعات.

GET /api/v1/shifts

تتغير القائمة مع التصفية حسب التاريخ والمتجر والحالة

معلمات الاستعلام

  • start_date — تاريخ البدء بالتنسيق YYYY-MM-DD
  • end_date — تاريخ الانتهاء بالتنسيق YYYY-MM-DD
  • store_id — التصفية حسب المتجر (عدد صحيح)
  • status — التصفية حسب الحالة: open أو Closed
  • limit — النتائج لكل صفحة (الافتراضي: 50، الحد الأقصى: 200)
  • offset — إزاحة الصفحات (الافتراضي: 0)

مثال للإجابة

{ "success": true, "data": [ { "id": 87, "user_name": "Ana M.", "store_name": "Main Store", "status": "closed", "opening_cash": "200.00", "closing_cash": "485.30", "total_sales": "312.50", "total_orders": 28, "opened_at": "2025-01-30 08:00:00", "closed_at": "2025-01-30 16:05:00" } ]، "الإجمالي": 87، "الحد": 50، "إزاحة": 0 }
GET /api/v1/shifts/{id}

احصل على تفاصيل الوردية بما في ذلك تفاصيل المبيعات

مثال للإجابة

{ "success": true, "data": { "id": 87, "user_name": "Ana M.", "store_name": "Main Store", "status": "closed", "opening_cash": "200.00", "closing_cash": "485.30", "expected_cash": "487.50", "difference": "-2.20", "total_sales": "312.50", "total_orders": 28, "opened_at": "2025-01-30 08:00:00", "closed_at": "2025-01-30 16:05:00", "notes": null } }

الأخطاء وحدود المعدل

يستخدم API رموز حالة HTTP القياسية. جميع استجابات الأخطاء تتضمن JSON مع رسالة وصفية.

رموز الحالة

  • 200 — النجاح
  • 401 — مفتاح API غير صالح أو مفقود
  • 403 — الميزة غير متوفرة في خطتك
  • 404 — لم يتم العثور على المورد
  • 500 — خطأ داخلي في الخادم

تنسيق الاستجابة للخطأ

{ "success": false, "error": "Invalid API key or inactive account." }

تحديد المعدل

تقتصر طلبات

API على 100 طلب في الدقيقة لكل مفتاح API. إذا تجاوزت هذا الحد، فستتلقى رمز الحالة 429. انتظر لحظة قبل إعادة المحاولة.

الويب هوكس

تتيح لك الويب هوكس استقبال إشعارات HTTP في الوقت الفعلي عند وقوع الأحداث في حساب SmartPOS AI الخاص بك. عند وقوع حدث، نرسل طلب POST مع محتوى JSON إلى رابطك المسجل.

متطلبات الخطة

تتطلب الويب هوكس خطة Professional أو أعلى. خطط Free و Starter ليس لديها وصول إلى الويب هوكس.

الأحداث المدعومة

  • order.created — تم إتمام إيصال/عملية بيع جديدة
  • order.deleted — تم إلغاء/حذف إيصال
  • product.created — تمت إضافة منتج جديد
  • product.updated — تم تعديل منتج (الاسم، السعر، المخزون، إلخ.)
  • product.deleted — تم حذف منتج
  • inventory.low_stock — وصل صنف في فرع إلى مستوى التنبيه أو أقل (يُرسل مرة واحدة، مع الفرع والمخزون والمستوى؛ يُفحص كل ساعة)
  • customer.created — تمت إضافة عميل جديد
  • customer.updated — تم تعديل سجل عميل
  • shift.opened — تم بدء وردية جديدة
  • shift.closed — تم إنهاء وردية
  • refund.created — تم إصدار استرداد
GET /api/v1/webhooks

عرض جميع الويب هوكس المسجلة

مثال الاستجابة

{ "success": true, "data": [ { "id": 1, "url": "https://example.com/webhook", "events": ["order.created", "product.updated"], "secret": "whsec_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4", "store_id": null, "max_retries": 3, "is_active": 1, "last_triggered_at": "2026-02-07 14:30:00", "failure_count": 0, "created_at": "2026-01-15 10:00:00" } ] }
POST /api/v1/webhooks

تسجيل نقطة نهاية ويب هوك جديدة

نص الطلب

{ "url": "https://example.com/webhook", "events": ["order.created", "shift.closed"], "max_retries": 3 }
DELETE /api/v1/webhooks/{id}

حذف ويب هوك بواسطة المعرف

تنسيق محتوى الويب هوك

عند وقوع حدث، نرسل طلب POST إلى رابطك بهذا التنسيق JSON (مثال: order.created؛ تختلف الحقول داخل data حسب الحدث):

{ "event": "order.created", "data": { "id": 1042, "receipt_number": "S01-2026-00042", "store_id": 1, "customer_id": null, "subtotal": 48.3, "discount": 2.5, "tax": 6.65, "total": 45.8, "payment_method": "cash", "items_count": 3, "points_earned": 0, "points_used": 0, "tip_amount": 0, "created_at": "2026-02-07T14:30:00+01:00" }, "timestamp": "2026-02-07T14:30:00+01:00", "webhook_id": 1 }

الإيصالات المدفوعة من طاولة (وضع المطعم) ترسل حقولاً أقل في data:

  • إغلاق طاولة: id، receipt_number، store_id، table_name، order_type (dine_in)، subtotal، discount، total، payment_method، items_count، created_at
  • دفع جزء من فاتورة مقسّمة: id، receipt_number، store_id، order_type (dine_in)، total، payment_method، is_split، split_number، created_at

رؤوس HTTP

كل تسليم ويب هوك يتضمن هذه الرؤوس HTTP:

  • Content-Type: application/json
  • User-Agent: SmartPOS-Webhook/1.0
  • X-SmartPOS-Event — اسم الحدث (مثل order.created)
  • X-SmartPOS-Signature — sha256= متبوعاً بتوقيع HMAC-SHA256 لنص الطلب (انظر أدناه)
  • X-SmartPOS-Delivery — معرف تسليم فريد (نفسه لكل محاولات التسليم الواحد)
  • X-SmartPOS-Version — إصدار التنسيق (حالياً 1.0؛ لا يُرسل مع اختبار ping)

التحقق من التوقيع (موصى به)

يتم توقيع كل ويب هوك باستخدام HMAC-SHA256 باستخدام المفتاح السري للويب هوك (يبدأ بـ whsec_؛ يمكنك عرضه أو إنشاء مفتاح جديد من المكتب الخلفي ← الإعدادات ← API ← الويب هوكس). يأتي رأس X-SmartPOS-Signature بالشكل sha256=<hex>. احسب التوقيع على نص الطلب الخام كما وصل تماماً (وليس على JSON بعد إعادة ترميزه) للتأكد من أن الطلب جاء فعلاً من SmartPOS AI.

// مثال Node.js const crypto = require('crypto'); function verifySignature(rawBody, signatureHeader, secret) { const expected = 'sha256=' + crypto .createHmac('sha256', secret) .update(rawBody) .digest('hex'); const received = Buffer.from(signatureHeader || ''); const wanted = Buffer.from(expected); return received.length === wanted.length && crypto.timingSafeEqual(received, wanted); }

🔐 استخدم دائماً مقارنة آمنة من حيث التوقيت

استخدم crypto.timingSafeEqual() (Node) أو hash_equals() (PHP) عند مقارنة التوقيعات. المقارنة العادية للسلاسل عرضة لهجمات التوقيت.

سياسة إعادة المحاولة

إذا لم تُرجع نقطة النهاية الخاصة بك رمز حالة 2xx خلال 10 ثوانٍ، تفشل المحاولة. تُعاد المحاولة الفاشلة فوراً بعد توقف قصير (0.5 ثانية، ثم 1 ثانية، ثم 1.5 ثانية…) حتى يبلغ إجمالي المحاولات قيمة max_retries للويب هوك (من 1 إلى 5، والافتراضي 3). لا تبدأ محاولة جديدة إلا إذا لم تمضِ 9 ثوانٍ بعد، لذلك تحصل نقطة النهاية التي لا ترد في الوقت المحدد (10 ثوانٍ) على محاولة واحدة فقط. لا توجد إعادة محاولات مؤجلة لاحقاً.

يُسجَّل كل تسليم. يمكنك عرض السجل وإعادة إرسال تسليم فاشل من المكتب الخلفي ← الإعدادات ← API ← الويب هوكس. تحمل جميع محاولات التسليم الواحد نفس معرف X-SmartPOS-Delivery؛ أما إعادة الإرسال اليدوية فتحصل على معرف جديد.

POST /api/v1/webhooks/{id}/test

إرسال محتوى اختبار (الحدث test.ping) إلى نقطة نهاية الويب هوك (مفيد للتحقق من معالج الويب هوك قبل البث المباشر)

موثوقية الويب هوك

إذا أرجع نقطة النهاية الخاصة بك رمز حالة غير 2xx، يتم وضع علامة فشل على التسليم. بعد 10 إخفاقات متتالية، يتم إلغاء تنشيط الويب هوك تلقائياً. يمكنك إعادة تنشيطه من الإعدادات ← API ← الويب هوكس.

وضع بدون إنترنت

SmartPOS AI يعمل حتى بدون اتصال بالإنترنت. إليك كيف يعمل:

  • يتم تخزين المعاملات محليًا باستخدام IndexedDB
  • تتم مزامنة البيانات تلقائيًا عند استعادة الاتصال
  • يتم تخزين المنتجات والأسعار مؤقتًا للوصول إليها دون الاتصال بالإنترنت
  • يمكن طباعة الإيصالات محليًا