> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scanova.io/llms.txt
> Use this file to discover all available pages before exploring further.

# إرسال أحداث الخادم

> أرسل تحويلات الشراء والتسجيل والعملاء المحتملين من الخادم لديك إلى Scanova، مع أمثلة برمجية بلغات cURL وNode.js وPython وPHP.

استخدم واجهة أحداث الخادم للإبلاغ عن التحويلات التي تقع على الخادم لديك: عمليات الشراء، وعمليات التسجيل المؤكدة، والعملاء المحتملين، وأي إجراء خلفي تريد نسبه إلى مسح رمز QR.

## نقطة الوصول

```
POST https://track.scanova.io/server-events
```

**الترويسات المطلوبة:**

```http theme={null}
Content-Type: application/json
X-API-Key: YOUR_SITE_API_KEY
```

## الحقول المطلوبة

| الحقل             | الوصف                                                              |
| ----------------- | ------------------------------------------------------------------ |
| `site_id`         | معرّف موقع التتبع لديك من لوحة التحكم                              |
| `event_name`      | اسم حدث التحويل (مثل `purchase` أو `signup` أو `lead`)             |
| `scan_session_id` | معرّف جلسة المسح من متصفح الزائر. وهو ما يربط التحويل بمسح رمز QR. |

## أمثلة

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://track.scanova.io/server-events" \
      -H "Content-Type: application/json" \
      -H "X-API-Key: YOUR_API_KEY" \
      -d '{
        "site_id": "YOUR_SITE_ID",
        "event_name": "purchase",
        "event_id": "550e8400-e29b-41d4-a716-446655440000",
        "scan_session_id": "7ad26d4f-3181-4ef8-b6ca-b8f59499dd43",
        "conversion_value": { "amount": 49.99, "currency": "USD" },
        "properties": { "order_id": "ord_9876", "plan": "pro" }
      }'
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    import crypto from 'node:crypto';

    async function trackConversion({ scanSessionId, orderId, amount }) {
      const response = await fetch('https://track.scanova.io/server-events', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-API-Key': process.env.SCANOVA_API_KEY,
        },
        body: JSON.stringify({
          site_id: process.env.SCANOVA_SITE_ID,
          event_name: 'purchase',
          event_id: crypto.randomUUID(),   // generate once and persist for retries
          scan_session_id: scanSessionId,
          conversion_value: { amount, currency: 'USD' },
          properties: { order_id: orderId },
        }),
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(`Tracking failed: ${response.status} — ${JSON.stringify(error)}`);
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import os
    import uuid
    import requests

    def track_conversion(scan_session_id: str, order_id: str, amount: float):
        response = requests.post(
            "https://track.scanova.io/server-events",
            headers={
                "Content-Type": "application/json",
                "X-API-Key": os.environ["SCANOVA_API_KEY"],
            },
            json={
                "site_id": os.environ["SCANOVA_SITE_ID"],
                "event_name": "purchase",
                "event_id": str(uuid.uuid4()),  # generate once, persist for retries
                "scan_session_id": scan_session_id,
                "conversion_value": {"amount": amount, "currency": "USD"},
                "properties": {"order_id": order_id},
            },
            timeout=10,
        )
        response.raise_for_status()
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    <?php
    function trackConversion(string $scanSessionId, string $orderId, float $amount): void {
        $payload = json_encode([
            'site_id'          => getenv('SCANOVA_SITE_ID'),
            'event_name'       => 'purchase',
            'event_id'         => sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
                                    mt_rand(0, 0xffff), mt_rand(0, 0xffff),
                                    mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
                                    mt_rand(0, 0x3fff) | 0x8000,
                                    mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)),
            'scan_session_id'  => $scanSessionId,
            'conversion_value' => ['amount' => $amount, 'currency' => 'USD'],
            'properties'       => ['order_id' => $orderId],
        ]);

        $ch = curl_init('https://track.scanova.io/server-events');
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_HTTPHEADER     => [
                'Content-Type: application/json',
                'X-API-Key: ' . getenv('SCANOVA_API_KEY'),
            ],
        ]);

        $response = curl_exec($ch);
        $status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($status !== 200) {
            throw new RuntimeException("Tracking failed: {$status} — {$response}");
        }
    }
    ```
  </Tab>
</Tabs>

## الحقول الاختيارية

| الحقل              | الوصف                                                                                                         |
| ------------------ | ------------------------------------------------------------------------------------------------------------- |
| `event_id`         | معرّف UUID لإعادة الإرسال بأمان. أنشئه مرة واحدة وأعد استخدامه في كل محاولة. وإذا لم تُرسله، يُنشأ تلقائيًا.  |
| `event_time`       | ختم زمني بصيغة ISO 8601 لوقت وقوع الحدث. وافتراضيًا وقت الاستلام. ومفيد إذا كنت ترسل الأحداث بشكل غير متزامن. |
| `conversion_value` | `{ "amount": 49.99, "currency": "USD" }`. ويجب أن تكون العملة رمزًا من ثلاثة أحرف وفق ISO 4217.               |
| `user_identifiers` | معرّفات الزائر المشفّرة: `email_hash` و`phone_hash` و`external_id`. لا ترسل البريد أو الهاتف كما هو أبدًا.    |
| `properties`       | كائن مفاتيح وقيم خاص بك. بحد أقصى 10 كيلوبايت. وبلا بيانات شخصية صريحة.                                       |
| `consent`          | `granted` أو `denied` أو `pending`. يتحكم في التعامل مع البيانات الشخصية.                                     |

## تمرير scan\_session\_id من المتصفح إلى الخادم

تنشأ القيمة `scan_session_id` في المتصفح. وعليك تمريرها من الواجهة الأمامية إلى الخادم لديك.

**الخيار الأول: حقل نموذج مخفي**

```html theme={null}
<form action="/checkout" method="POST">
  <input type="hidden" name="scan_session_id" id="scan_session_id_field">
  <!-- other form fields -->
</form>

<script>
  // _scnv is the SDK's internal localStorage key (structure may change in future SDK versions)
  const stored = localStorage.getItem('_scnv');
  const sessionId = stored ? JSON.parse(stored).sid : null;
  if (sessionId) {
    document.getElementById('scan_session_id_field').value = sessionId;
  }
</script>
```

**الخيار الثاني: إدراجها في جسم طلب الواجهة من الواجهة الأمامية**

```javascript theme={null}
// _scnv is the SDK's internal localStorage key (structure may change in future SDK versions)
const stored = localStorage.getItem('_scnv');
const scanSessionId = stored ? JSON.parse(stored).sid : null;

await fetch('/api/checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    cart: cartData,
    scan_session_id: scanSessionId,  // pass to your server
  }),
});
```

## إرسال دفعة من الأحداث

استخدم نقطة وصول الدفعات لإرسال ما يصل إلى 100 حدث في طلب واحد:

```
POST https://track.scanova.io/server-events/batch
```

```json theme={null}
{
  "events": [
    {
      "site_id": "YOUR_SITE_ID",
      "event_name": "purchase",
      "scan_session_id": "7ad26d4f-...",
      "conversion_value": { "amount": 49.99, "currency": "USD" }
    },
    {
      "site_id": "YOUR_SITE_ID",
      "event_name": "signup",
      "scan_session_id": "3b5e1234-..."
    }
  ]
}
```

يوضح الرد لكل حدث ما إذا كان قد قُبل أو رُفض:

```json theme={null}
{
  "accepted": 2,
  "rejected": 0,
  "results": [
    { "index": 0, "event_id": "...", "status": "accepted" },
    { "index": 1, "event_id": "...", "status": "accepted" }
  ]
}
```

## الخطوات التالية

* [تكرار الطلبات والإرسال مرة أخرى](/ar/conversion-tracking/server/idempotency-retries) — كيف تعيد إرسال الطلبات الفاشلة بأمان
* [التحقق من الوصول](/ar/conversion-tracking/server/verify) — تأكد من وصول الأحداث
* [مرجع الواجهة: حدث واحد](/ar/conversion-tracking/api/events-collect) — المواصفات الكاملة لنقطة الوصول
* [مرجع الواجهة: دفعة أحداث](/ar/conversion-tracking/api/events-batch) — مواصفات نقطة وصول الدفعات
