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

# تنزيل إشعار AADL

> نزّل إشعار الدفع الرسمي من AADL لإحدى معاملاتك أنت

<div dir="ltr">
  ## نظرة عامة

  يبثّ *إشعار الدفع* الذي تنشره `AADL` لملف سكني — وهو ملف PDF نفسه الذي كان المستأجر سينزّله من مُصدِر الفاتورة — لمعاملة تملكها **أنت**. وكما في [تنزيل الإيصال](/ar/api-reference/bill-payment/get-receipt)، لا يُعيد هذا endpoint غلاف JSON عند النجاح: الجسم هو البايتات نفسها، فيمكنك تمريرها مباشرةً إلى عميلك.

  وهو ليس الإيصال. فالإيصال يثبت أن دفعتك أنت قد تمت؛ أما الإشعار فهو بيان AADL بما يستحق على الملف السكني. ولا ينشره سوى `AADL`.

  <Warning>
    **الإشعار يُطلب بالمعاملة، لا برقم الملف السكني أبدًا.** لا يوجد في هذا الطلب أي `codeloc`، ولا يُقبل إرسال واحد. فنحن نحمّل المعاملة، ونتأكد أنها لك في هذه البيئة، ونرفضها إذا لم يكن `partner` فيها `AADL`، ثم نقرأ الملف السكني من الفاتورة المخزَّنة عليها أصلًا.

    وهذا مقصود. فصفحة التصدير لدى AADL لا تطلب أي جلسة وتُعيد ملف PDF لأي رمز، موجودًا كان أو غير موجود؛ ولو مرّرنا رمزًا يرسله المتصل لتحوّل هذا endpoint إلى أداة لتعداد ملفات الآخرين. أما استخراجه من معاملتك أنت فيجعل ذلك مستحيلًا.
  </Warning>

  ## معاملات المسار

  <ParamField path="transactionId" type="string" required>
    معرّف المعاملة. سلسلة ست عشرية صغيرة الأحرف من 24 حرفًا، من [الحصول على معاملة بالمعرّف](/ar/api-reference/bill-payment/check-by-id) أو من أي قائمة، وتخص إحدى معاملات `AADL` التي تملكها.

    وخلافًا للإيصال، لا يلزم أن تكون المعاملة في `SUCCESS`: فأي معاملة `AADL` لك جرى فيها تحديد فاتورة يمكن أن تُنتج إشعارًا.
  </ParamField>

  ## الاستجابة

  عند النجاح يكون الجسم هو ملف PDF نفسه. اقرأ الترويسات لتعرف ما استلمته.

  <ResponseField name="Content-Type" type="header" required>
    `application/pdf`.
  </ResponseField>

  <ResponseField name="Content-Disposition" type="header" required>
    `attachment; filename="avis_<transactionId>.pdf"`. والاسم مبنيّ من معرّف المعاملة وحده، فلا يحمل أي هوية للمستأجر.
  </ResponseField>

  <ResponseField name="Content-Length" type="header" required>
    حجم الملف بالبايت.
  </ResponseField>

  <ResponseField name="Cache-Control" type="header" required>
    `private, no-store`. تُعيد AADL توليد الإشعار عند الطلب وتستبدله كل فترة، فلا شيء ثابت يستحق التخزين المؤقت — وهو وثيقة عميل واحد، لا وثيقة مشتركة.
  </ResponseField>

  ## أمثلة

  <CodeGroup>
    ```bash cURL theme={null}
    # -J -O تكتب الملف بالاسم الذي يقترحه الخادم
    curl https://api.oneclickdz.com/v3/bills/transactions/68b2f4c1a7d3e9f204c81a55/avis \
      -H "X-Access-Token: YOUR_API_KEY" \
      --fail \
      --remote-header-name --remote-name
    ```

    ```javascript Node.js theme={null}
    import { writeFile } from "node:fs/promises";

    const transactionId = "68b2f4c1a7d3e9f204c81a55";

    const response = await fetch(
      `https://api.oneclickdz.com/v3/bills/transactions/${transactionId}/avis`,
      { headers: { "X-Access-Token": process.env.ONECLICKDZ_API_KEY } },
    );

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`${error.error.code}: ${error.error.message}`);
    }

    const bytes = Buffer.from(await response.arrayBuffer());
    await writeFile(`avis-${transactionId}.pdf`, bytes);

    console.log(bytes.length);
    ```

    ```python Python theme={null}
    import os
    import requests

    transaction_id = '68b2f4c1a7d3e9f204c81a55'

    response = requests.get(
        f'https://api.oneclickdz.com/v3/bills/transactions/{transaction_id}/avis',
        headers={'X-Access-Token': os.getenv('ONECLICKDZ_API_KEY')}
    )

    if response.status_code != 200:
        error = response.json()
        raise RuntimeError(f"{error['error']['code']}: {error['error']['message']}")

    with open(f'avis-{transaction_id}.pdf', 'wb') as handle:
        handle.write(response.content)

    print(len(response.content))
    ```

    ```php PHP theme={null}
    <?php
    $transactionId = '68b2f4c1a7d3e9f204c81a55';

    $ch = curl_init("https://api.oneclickdz.com/v3/bills/transactions/$transactionId/avis");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-Access-Token: ' . getenv('ONECLICKDZ_API_KEY')
    ]);

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

    if ($status !== 200) {
        $error = json_decode($bytes, true);
        throw new Exception($error['error']['code'] . ': ' . $error['error']['message']);
    }

    file_put_contents("avis-$transactionId.pdf", $bytes);

    echo strlen($bytes);
    ?>
    ```
  </CodeGroup>

  ### استجابة النجاح

  الجسم ثنائي. وتبدو الترويسات هكذا:

  ```http theme={null}
  HTTP/1.1 200 OK
  Content-Type: application/pdf
  Content-Length: 71204
  Content-Disposition: attachment; filename="avis_68b2f4c1a7d3e9f204c81a55.pdf"
  Cache-Control: private, no-store
  ```

  ## استجابات الخطأ

  تُعاد الأخطاء بصيغة JSON، في الغلاف نفسه المستخدَم في كل endpoint آخر.

  <AccordionGroup>
    <Accordion title="401 — رمز وصول مفقود أو غير صالح">
      **المفتاح غائب أو مرفوض.**

      ```json theme={null}
      {
        "success": false,
        "error": {
          "code": "INVALID_ACCESS_TOKEN",
          "message": "The provided access token is invalid."
        },
        "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
      }
      ```

      **ما العمل:** تحقق من المفتاح عبر دليل [المصادقة](/ar/authentication).
    </Accordion>

    <Accordion title="404 — المعاملة غير موجودة">
      **المعرّف غير معروف، أو المعاملة ليست لك في هذه البيئة.**

      ```json theme={null}
      {
        "success": false,
        "error": {
          "code": "NOT_FOUND",
          "message": "Transaction not found."
        },
        "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
      }
      ```

      مفتاح sandbox لا يرى معاملة إنتاج أبدًا، ولا يرى أي منهما معاملة مفتاح آخر. والجواب واحد في كل الحالات، فلا يؤكد هذا endpoint أبدًا وجود معاملة تخص شخصًا آخر.

      **ما العمل:** تحقق من المعرّف، وتحقق من أنك تستخدم المفتاح الذي أُنشئت به المعاملة.
    </Accordion>

    <Accordion title="404 — ليست معاملة AADL">
      **المعاملة لك فعلًا، لكن شريكها لا ينشر إشعارًا.**

      ```json theme={null}
      {
        "success": false,
        "error": {
          "code": "NOT_FOUND",
          "message": "This partner does not publish a downloadable avis."
        },
        "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
      }
      ```

      **ما العمل:** اقرأ `partner` على المعاملة أولًا، ولا تعرض التنزيل إلا حين تكون قيمته `AADL`. أما بقية مُصدِري الفواتير فالوثيقة المطلوبة لديهم هي [الإيصال](/ar/api-reference/bill-payment/get-receipt).
    </Accordion>

    <Accordion title="404 — لا يتوفر إشعار بعد">
      **لم يُحدَّد بعد أي ملف سكني على هذه المعاملة، أو رفضت AADL إصدار الوثيقة.**

      ```json theme={null}
      {
        "success": false,
        "error": {
          "code": "NOT_FOUND",
          "message": "No avis is available for this transaction yet."
        },
        "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
      }
      ```

      فالاستكشاف الذي لم يبلغ `READY` بعد لا يحمل أي فاتورة، ومن ثمّ لا يوجد ما يُستخرج منه ملف سكني.

      **ما العمل:** انتظر حتى تحمل المعاملة فاتورة، ثم أعد المحاولة. ورفض مُصدِر الفاتورة يستحق محاولة إضافية واحدة، لا حلقة متكررة.
    </Accordion>
  </AccordionGroup>

  ## فيمَ يُستخدم الإشعار

  <CardGroup cols={2}>
    <Card title="إظهار ما على العميل" icon="file-invoice">
      يحمل الإشعار تفصيل AADL نفسها للملف السكني. وهو الوثيقة التي يعرفها المستأجر.
    </Card>

    <Card title="ليس بديلاً عن الإيصال" icon="receipt">
      وحده [الإيصال](/ar/api-reference/bill-payment/get-receipt) يثبت أن الدفع قد تم. وهو ما ينبغي حفظه مع طلبك.
    </Card>
  </CardGroup>

  <Note>
    تذكّر أن لملف السكن في AADL إشعارًا مفتوحًا **واحدًا** فقط، بما فيه من متأخرات مُدرَجة في مبلغه — فهذا الـPDF يمثل كل ما يستحق على الملف، لا فترة واحدة من بين عدة فترات. انظر [الشركاء والحسابات](/ar/bill-payment-guides/1-partners-and-accounts).
  </Note>

  ## أفضل الممارسات

  <CardGroup cols={2}>
    <Card title="تحقق من الشريك أولاً" icon="building-columns">
      لا تعرض التنزيل إلا لمعاملات `AADL`. فكل شريك آخر يُجيب بـ `404 NOT_FOUND`.
    </Card>

    <Card title="لا تكشف الرابط أبداً" icon="shield-halved">
      هذا الرابط يتطلب مفتاح API الخاص بك. قدّم البايتات من نظامك أنت، خلف مصادقتك أنت.
    </Card>

    <Card title="نزّله عند الحاجة" icon="rotate">
      `no-store` ليست زينة: فـAADL تستبدل الإشعار كل فترة. نزّله حين تحتاج إليه.
    </Card>

    <Card title="لا ترسل codeloc أبداً" icon="lock">
      لا يوجد أي معامِل معرّف يمكن تخمينه. وإن كان كودك يبني واحداً فهو ينادي شيئاً آخر.
    </Card>
  </CardGroup>

  ## Endpoints ذات صلة

  <CardGroup cols={2}>
    <Card title="تنزيل الإيصال" icon="file-arrow-down" href="/ar/api-reference/bill-payment/get-receipt">
      إثبات دفع ناجح
    </Card>

    <Card title="الحصول على معاملة بالمعرّف" icon="id-card" href="/ar/api-reference/bill-payment/check-by-id">
      حيث يظهر `partner` والفواتير
    </Card>

    <Card title="استكشاف الفواتير" icon="magnifying-glass-dollar" href="/ar/api-reference/bill-payment/discover-bills">
      كيف يُستعلَم عن ملف سكني لدى AADL
    </Card>

    <Card title="الشركاء والحسابات" icon="address-card" href="/ar/bill-payment-guides/1-partners-and-accounts">
      قواعد معرّف AADL
    </Card>
  </CardGroup>
</div>
