# تكامل MZ3B بالمفتاح الواحد — الإصدار 1.3

الدليل الإنجليزي: https://mz3b.com/integration.en.md

عنوان الدليل: https://mz3b.com/docs
العقد القابل للقراءة آليًا: https://mz3b.com/openapi.json
مثال Node.js الكامل: https://mz3b.com/examples/mz3b-node.mjs

بعد تجهيز المشروع وتعيين رقم واتساب لرموز التحقق وحفظ مفتاح المشروع على خادم تطبيقك، لا تحتاج إلى لوحة MZ3B للإرسال أو الفحص أو قراءة الرصيد أو إدارة قائمة موظفي التنبيهات. يختار المفتاح المشروع ورقم الإرسال تلقائيًا. تنبيهات الطلبات ورموز التحقق تستخدمان اختيار المرسل نفسه: رقم المشروع الحالي، أو مجموعة أرقامه إذا فعّل المالك المجموعة صراحةً من اللوحة. المشاريع القديمة تحتفظ بأقدم تعيين غير ملغى إلى أن تُحفظ المجموعة. مع التوزيع قد تُرسل عمليات مختلفة من أرقام مختلفة، لكن العملية الواحدة تبقى مثبتة على مرسلها الأصلي. إعادة الربط بعد إلغاء واتساب للجلسة، وإدارة الحساب والشحن، تبقى إجراءات للمستخدم عند الحاجة.

## الأمان والصلاحيات

احفظ `MZ3B_KEY` في مدير أسرار خادمك، لا في المتصفح أو الهاتف أو المستودع أو المحادثة أو السجلات. لا تستخدم `curl -v` أو تتبع الترويسات. لا تسجل جسم طلب OTP أو الرمز المستلم. المفتاح الذي يبدأ بـ `mz_test_` ليس محاكاة: يمكنه إرسال رسائل حقيقية.

| الوظيفة | الصلاحية |
| --- | --- |
| إرسال/محاكاة رمز | `verifications:send` |
| فحص الرمز | `verifications:check` |
| قراءة محاولة | `verifications:read` |
| إرسال/محاكاة تنبيه | `messages:send` |
| قراءة تنبيه | `messages:read` |
| تسجيل الموظفين وإلغاء الموافقة | `recipients:manage` |
| ملخص الحساب والرصيد | `account:read` |

المفاتيح القديمة غير المقيدة تستمر وتدعم التكامل الجديد دون تبديل. إنشاء مفتاح جديد من اللوحة يمنح هذه الصلاحيات افتراضيًا. تقبل واجهة إنشاء المفاتيح الحالية `POST /api/keys` حقل `scopes` اختياريًا لتقييده، بمصادقة جلسة مالك الحساب وحماية طلبات اللوحة؛ ليست واجهة يسمح مفتاح المشروع عبرها بإنشاء مفاتيح أخرى. المفاتيح المقيدة أو الملغاة لا تتجاوز قيودها. يعرض الملخص الصلاحيات الفعلية. لا تُلغِ مفتاحًا قائمًا لمجرد تجربة التكامل.

## 1. فحص الجاهزية والرصيد دون إرسال

الأوامر لخادم موثوق، ومتغير المفتاح محقون من مدير الأسرار مسبقًا:

```bash
curl --silent --show-error --max-time 20 \
  'https://mz3b.com/api/v1/account/summary' \
  -H "Authorization: Bearer $MZ3B_KEY"
```

اقرأ `ready` و`reasons` و`whatsapp.connection`. الرقم مقنّع. بيانات `billing.paidCredits` و`billing.trial.remaining` و`expiresAt` فعلية وليست أرقام باقة ثابتة. الرصيد مشترك بين مشاريع الحساب، وليس محفظة منفصلة لكل مشروع. `trial.eligibleForSender` يوضح قابلية استخدام التجربة مع الرقم الحالي. تكلفة الحجز الحالية رسالة واحدة للرمز أو التنبيه، وصفر لاستعلام الرصيد والفحص والمحاكاة؛ استثناء الإدارة المصرح به يظهر صراحة. لا نقدم سعر دولار ثابتًا للرسالة لأن حزم الشراء تختلف.

التجربة 20 رسالة لمرة واحدة خلال 7 أيام من أول ربط ناجح، ثم الرصيد المدفوع؛ لا يتجدد أسبوعيًا أو شهريًا. الرصيد المشترى لا ينتهي شهريًا. الملخص لا يرسل ولا يشحن ولا يعيد تشغيل الجلسة، لكنه يسجل استخدام المفتاح وحدود الطلبات. الجاهزية ملاحظة وقتية، وقد ينقطع واتساب بعد الاستعلام. حد الملخص 12 طلبًا لكل حساب في الدقيقة. اتبع `links.manage` و`links.topUp` عندما يلزم تدخل المالك.

اعرض `whatsapp.connection` منفصلًا عن `ready`: قد يكون الرقم متصلًا لكن الرصيد أو الحماية يمنعان الإرسال. عند فشل القراءة أو `connection=unknown` اعرض «تعذر تأكيد الاتصال»، لا تحتفظ بعلامة جاهزية قديمة ولا تفترض الحظر. التحديث كل 30 ثانية أثناء عرض البطاقة مناسب، مع عدم تداخل الطلبات واحترام `Retry-After` وإبطال الجاهزية بعد 45 ثانية دون ملاحظة حديثة. لوحة MZ3B تستخدم مصدر الملخص الحي نفسه؛ الحالة المحفوظة للجلسة وحدها ليست دليل اتصال. لا تعِد إنشاء مفتاح أو جلسة لمعالجة تعذر الاستعلام.


## مجموعة أرقام للمشروع — اختيارية

من «المشاريع والأرقام»، اختر المشروع ثم افتح «أرقام الإرسال والاحتياط». حدد أرقامًا مملوكة للحساب أو أضف رقمًا جديدًا واربطه من هاتفه، ثم احفظ المجموعة. لا يُطلب مفتاح جديد ولا معرّف جلسة في طلبات التطبيق الخارجي.

- `priority`: يستخدم الرقم الأساسي الجاهز، ثم الاحتياطي قبل أول إرسال عند توقف تقني مؤكد أو بلوغ الحد اليومي المحلي الذي حدده صاحب الحساب.
- `balanced`: يختار الأقل استخدامًا نسبةً إلى حده اليومي من الأرقام الجاهزة. التوزيع تقريبي تحت التزامن؛ الحجز الذري يمنع تجاوز الحد.
- حد الرقم الصحيح بين 1 و10000، والافتراضي في شاشة الإعداد 30. يُحسب للرقم نفسه عبر **جميع مشاريعه** ورموز التحقق والتنبيهات، ويتجدد عند 00:00 UTC. الطلب المحجوز أو غير المؤكد يُحسب؛ عدم الإرسال المثبت وحده يحرر الحصة. رمز أُرسل ثم فشل التحقق منه يبقى محسوبًا.
- لا تُحوّل العملية إلى مرسل آخر بعد محاولة الإرسال، حتى لو فشلت أو غمضت نتيجتها. أعد مفتاح منع التكرار والجسم نفسيهما لاسترجاع العملية الأصلية. تغير ترتيب المجموعة لا يغير مرسل عملية قديمة.
- حماية أو تحذير أو تقييد أو حالة `FAILED` غير مشخّصة على أحد الأرقام توقف الاختيار الآلي للمجموعة للمراجعة. فشل فحص حالة عضو يجعل المجموعة غير مؤكدة. لا تُستخدم الأرقام للالتفاف على حظر أو حدود واتساب، ولا تضمن 30 رسالة تجنب التقييد.
- الحدود المعلنة للحساب والخادم وللمستلم تبقى قائمة. لا توجد تجربة مجانية إضافية لكل رقم، ولا توزيع يتجاوز حدود معدل الإرسال.

يضيف `GET /api/v1/account/summary` الحقل الاختياري `routing` للمشاريع ذات المجموعة: `mode` و`ready` و`reasons` و`dayTimezone: UTC` و`resetsAt` و`senders[]`. لكل مرسل اسم ورقم مقنّع وحالة اتصال ووقت فحص و`priority` و`dailyLimit` و`usedToday` و`available` و`reason`، دون معرّفات داخلية. `whatsapp` يلخص المرشح الحالي؛ افحص `ready` و`routing` قبل الاستنتاج أن المجموعة جاهزة. ملخص الحالة لا يحجز رقمًا لطلب لاحق.

`429 SENDER_DAILY_LIMIT_REACHED`: بلغت الأرقام حدودها اليومية؛ انتظر `routing.resetsAt`. `503 SENDER_POOL_PROTECTED` أو `SENDER_POOL_REVIEW_REQUIRED`: مراجعة حماية، لا تدوير تلقائي. `SENDER_POOL_STATUS_UNAVAILABLE`: تعذر إثبات الحالة. `SENDER_POOL_LOCAL_STATE_PENDING`: مزامنة الجلسة المحلية لم تكتمل. `SENDER_POOL_NO_CONNECTED_NUMBER`: لا يوجد مرسل متصل ومتاح. عند `RESERVATION_UNAVAILABLE`، لا تفترض عدم الحجز؛ احتفظ بمفتاح العملية والجسم.

واجهات إعداد المجموعة **خاصة بجلسة لوحة الحساب وليست بمفتاح المشروع**: قراءة أو حفظ `/api/applications/{id}/sender-pool`؛ الحفظ `PUT` بالجسم `{"mode":"balanced","senders":[{"id":"OWNED_NUMBER_UUID","dailyLimit":30}]}`، ومن 1 إلى 8 أعضاء ضمن الحصة. الحفظ يرتب القائمة ويضبط الحد المشترك للرقم عبر مشاريعه. لا يحذف رقمًا أو يفصل جلسته. المتصفح يرسل حماية المصدر وترويسة `x-mz3b-client: dashboard`. إنشاء رقم إضافي عبر مسار الرقم الحالي يستخدم `additional:true` و`requestId` ثابتًا للمحاولة؛ لا تستخدم هذه الواجهات من التطبيق الخارجي.


## 2. إرسال رمز ثم التحقق منه

احصل على موافقة المستلم الفعلية وحدد رقمه بالصيغة الدولية. أنشئ UUID للعملية واحفظه وجسم الطلب في قاعدة بيانات تطبيقك قبل الإرسال. لا تخمن رقمًا أو رمزًا ولا تصطنع الموافقة. في مثال `curl`، جهّز ملفًا خاصًا `otp-request.json` خارج المستودع بهذا الشكل، مستبدلًا القيم التوضيحية بالبيانات التي وافق عليها المستخدم:

```json
{
  "to": "USER_APPROVED_E164",
  "locale": "ar",
  "purpose": "authentication",
  "consent": {
    "granted": true,
    "occurredAt": "ACTUAL_CONSENT_ISO_8601_TIME",
    "reference": "login:unique-consent-reference"
  },
  "context": { "userSessionId": "opaque-end-user-session-id" }
}
```

وقت الموافقة خلال 10 دقائق، ويحفظ كما هو عند إعادة الطلب. معرّف سياق المستخدم مرجع معتم وليس ملف تعريف ارتباط أو رمز دخول. التطبيقات القديمة تحتفظ بالعقد القديم `to` و`locale`؛ التطبيقات الجديدة تتطلب الموافقة والسياق. لا تحتاج لأي معرّف جلسة واتساب داخلي.

```bash
# لا يرسل ولا يحجز ولا يخصم: فحص صيغة وموافقة فقط.
curl --silent --show-error --max-time 20 \
  'https://mz3b.com/api/v1/verifications/validate' \
  -H "Authorization: Bearer $MZ3B_KEY" \
  -H "Idempotency-Key: $OTP_OPERATION_ID" \
  -H 'Content-Type: application/json' --data-binary @otp-request.json

# إرسال حقيقي يحجز رسالة واحدة: لا تنفذه دون موافقة المستلم المحدد.
curl --silent --show-error --max-time 20 \
  'https://mz3b.com/api/v1/verifications' \
  -H "Authorization: Bearer $MZ3B_KEY" \
  -H "Idempotency-Key: $OTP_OPERATION_ID" \
  -H 'Content-Type: application/json' --data-binary @otp-request.json

# VERIFICATION_ID هو id من الرد، وليس معرّف المشروع أو الجلسة.
curl --silent --show-error --max-time 20 \
  "https://mz3b.com/api/v1/verifications/$VERIFICATION_ID" \
  -H "Authorization: Bearer $MZ3B_KEY"

# ملف received-code.json الخاص يحتوي الرمز الذي قدمه المستلم: {"code":"......"}
curl --silent --show-error --max-time 20 \
  "https://mz3b.com/api/v1/verifications/$VERIFICATION_ID/check" \
  -H "Authorization: Bearer $MZ3B_KEY" \
  -H 'Content-Type: application/json' --data-binary @received-code.json
```

احفظ `id` من رد الإرسال. `pending` تعني قبول الطلب، لا وصوله. رمز واتساب 6 أرقام وصلاحيته 5 دقائق. **`approved` وحدها تعني نجاح التحقق**؛ لا تقبل HTTP 200 وحده دليلاً على صحة الرمز. `pending` أو `failed` ليست نجاحًا؛ `410 OTP_EXPIRED` يعني انتهاء الصلاحية. في سياسة الحماية الجديدة حد الفحص 5 محاولات لكل مشروع ومستلم خلال 10 دقائق، وليس 5 لكل رمز جديد. لا تخمّن الرمز، ولا تعِد الفحص آليًا بعد فقد رد قد يكون استهلك محاولة.

## 3. تنبيهات الطلبات لموظفين موافقين

القائمة لكل مشروع. يجب على تطبيقك التحقق من أن الشخص موظف مخول وأن لديه موافقة موثقة؛ التصريح عبر API لا يثبت ذلك بصورة مستقلة. احفظ الدليل عندك، وأرسل مرجعًا معتمًا. سجل الموظف مرة واحدة بعد الموافقة الفعلية الحديثة:

```json
{
  "to": "STAFF_APPROVED_E164",
  "role": "staff",
  "consent": {
    "granted": true,
    "occurredAt": "ACTUAL_CONSENT_ISO_8601_TIME",
    "reference": "staff:consent:unique-reference"
  }
}
```

```bash
# staff-consent.json: الجسم أعلاه. التسجيل لا يرسل ولا يخصم.
curl --silent --show-error --max-time 20 \
  'https://mz3b.com/api/v1/message-recipients' \
  -H "Authorization: Bearer $MZ3B_KEY" \
  -H 'Content-Type: application/json' --data-binary @staff-consent.json

# عرض القائمة المقنّعة؛ احفظ id لكل موظف لإلغاء موافقته لاحقًا.
curl --silent --show-error --max-time 20 \
  'https://mz3b.com/api/v1/message-recipients' \
  -H "Authorization: Bearer $MZ3B_KEY"

# إلغاء الموافقة على الرسائل المستقبلية. لا يلغي رسالة بدأت بالفعل.
curl --silent --show-error --max-time 20 -X DELETE \
  "https://mz3b.com/api/v1/message-recipients/$STAFF_RECIPIENT_ID" \
  -H "Authorization: Bearer $MZ3B_KEY"
```

لإرسال تنبيه، جهّز واحفظ `order-alert.json` و`ORDER_OPERATION_ID` للعملية المنطقية:

```json
{
  "to": "STAFF_APPROVED_E164",
  "text": "الطلب 42 جاهز للمراجعة",
  "reference": "order:42:ready:v1",
  "url": "https://shop.example.com/orders/42"
}
```

الرابط يجب أن يكون HTTPS عامًا دون اسم مستخدم أو كلمة مرور أو عنوان IP أو منفذ مخصص. يجب أن يطلب تطبيقك تسجيل دخول الموظف ويتحقق من صلاحياته عند فتح التفاصيل. لا تضع مفاتيح API أو رموز دخول طويلة العمر في الرابط. MZ3B لا يفتح الرابط ولا يجلب معاينته. ضع الرابط في `url` والنص دون روابط إضافية في `text`. الحد 1500 محرف للنص و1000 للرابط. مرجع الحدث معتم حتى 100 محرف من حروف وأرقام ورموز `._:-`، وليس بيانات عميل أو سرًا.

```bash
# محاكاة صيغة فقط؛ لا تتحقق من موافقة الموظف أو الجاهزية ولا تخصم.
curl --silent --show-error --max-time 20 \
  'https://mz3b.com/api/v1/messages/validate' \
  -H "Authorization: Bearer $MZ3B_KEY" \
  -H "Idempotency-Key: $ORDER_OPERATION_ID" \
  -H 'Content-Type: application/json' --data-binary @order-alert.json

# إرسال حقيقي إلى الموظف الموافق من رقم المشروع أو مجموعته المهيأة.
curl --silent --show-error --max-time 20 \
  'https://mz3b.com/api/v1/messages' \
  -H "Authorization: Bearer $MZ3B_KEY" \
  -H "Idempotency-Key: $ORDER_OPERATION_ID" \
  -H 'Content-Type: application/json' --data-binary @order-alert.json

# قراءة النتيجة لاحقًا؛ لا يعيد الإرسال أو يخصم مرة ثانية.
curl --silent --show-error --max-time 20 \
  "https://mz3b.com/api/v1/messages/$MESSAGE_ID" \
  -H "Authorization: Bearer $MZ3B_KEY"
```

الرد يحتوي `id` و`status` و`billing` و`delivery` ورابط قراءة النتيجة. `201 accepted` يعني قبول المزود وليس وصول الرسالة. `202 reserved/uncertain` يعني انتظار النتيجة أو عدم اليقين، ولا يبيح إعادة الإرسال بعملية جديدة. `failed` مع `delivery.status=not_sent` يعني إثبات عدم الإرسال ورد الرصيد مرة واحدة. القراءة قد تُسوّي نتيجة قديمة بالاستعلام عن البوابة، ولا تستدعي الإرسال. لا يوجد حاليًا تأكيد تسليم مضمون للتنبيهات، ويظل `delivery.confirmed=false`.

التكرار محمي داخل المشروع بالمفتاح، وكذلك برقم المستلم ومرجع الحدث: تغيير المفتاح وحده لا يكرر الحدث نفسه. لتحديث آخر للطلب، استخدم مرجع حدث جديدًا حقيقيًا مثل `order:42:shipped:v1`. الجسم المختلف مع مفتاح مستعمل أو مرجع حدث مستعمل يُرفض. إعادة عملية فاشلة تعيد الفشل ولا ترسل مجددًا. MZ3B يحتفظ بالمرجع والبصمات والرقم المقنّع والنتيجة، لا بنص التنبيه أو رابطه أو رقم المستلم الخام في قاعدة التكامل أو حالة البوابة الدائمة. واتساب ومزوده يعالجان محتوى الرسالة بطبيعة الإرسال.

الحدود الحالية: 25 موظفًا نشطًا و100 سجل كحد أقصى لكل مشروع، و10 تسجيلات/إعادات تفعيل لكل حساب يوميًا. 20 إرسالًا في الدقيقة لكل رقم مشترك مع OTP، وحد الدقيقة للحساب مشترك أيضًا. 10 تنبيهات في الدقيقة و200 يوميًا لكل مستلم عبر الخدمة، و1000 يوميًا لكل حساب. القيود للحماية لا للإرسال الجماعي. لا تصطنع حسابات لتجاوزها.

## 4. مثال Node.js كامل

ضع الملف `mz3b-node.mjs` في خادمك بعد مراجعته. استيراده لا ينفذ أي طلب. المثال التالي يوضح ترتيب الاستدعاءات داخل وظائف تطبيقك؛ معرّفات العملية وأجسام الطلب تحفظ في قاعدة بياناتك قبل الإرسال، وليس في ذاكرة العملية وحدها:

```javascript
import { createMZ3B, MZ3BError } from './mz3b-node.mjs';
const mz3b = createMZ3B(); // MZ3B_KEY from server secret manager

export async function inspectReadiness() {
  return mz3b.summary(); // No send or credit charge
}

export async function deliverPersistedOtp(operation) {
  // operation was created with newVerification after real end-user opt-in,
  // then durably saved by your application before this function was called.
  await mz3b.validateVerification(operation); // Syntax/consent check only
  const state = await mz3b.summary();
  if (!state.ready) return { ready:false,reasons:state.reasons };
  try {
    const result = await mz3b.sendVerification(operation);
    // Persist result.id against the SAME operation; pending is not delivery.
    return result;
  } catch (error) {
    if (!(error instanceof MZ3BError)) throw error;
    // Retain operation.idempotencyKey and operation.body unchanged.
    // If error.id exists, read mz3b.verification(error.id).
    // Never start a new logical operation automatically after uncertainty.
    return { error:error.message,id:error.id,retryAfter:error.retryAfter };
  }
}

export async function verifyReceivedCode(verificationId, codeFromRecipient) {
  const result = await mz3b.checkVerification(verificationId, codeFromRecipient);
  return result.status === 'approved'; // The only success condition
}

export async function deliverPersistedStaffAlert(operation) {
  // Staff was enrolled using mz3b.enrollStaff with real prior opt-in.
  // operation = mz3b.newOrderAlert({to,text,reference,url}), durably saved first.
  await mz3b.validateOrderAlert(operation); // No send, no charge
  const result = await mz3b.sendOrderAlert(operation);
  // Save result.id; for reserved/uncertain use mz3b.message(result.id).
  // accepted is not confirmed delivery. Do not generate a second operation.
  return result;
}
```

أنشئ عملية OTP باستخدام `newVerification({to,consentedAt,consentReference,userSessionId})`. سجل الموظف باستخدام `enrollStaff({to,consentedAt,consentReference})`. يجب أن تكون الأوقات وأدلة الموافقة فعلية، لا مضافة تلقائيًا لتجاوز الرفض. يحتفظ المثال بمهلة 20 ثانية ويرفض تحويلات الوجهة، ولا يسجل الأسرار أو الأجسام. ادمج وظائف التخزين والطابور داخل تطبيقك؛ هذه وظائف عميل مرجعي وليست طابورًا دائمًا جاهزًا.

## 5. الأخطاء والمهلات ومنع الخصم المزدوج

| الحالة | التصرف |
| --- | --- |
| `400` / `415` / `413` | صحح الصيغة أو نوع/حجم الجسم؛ لا تفترض حصول إرسال. |
| `401` | المفتاح غير صالح أو ألغي أو توقف المشروع؛ تواصل مع المالك دون عرض السر. |
| `403` | صلاحية مفقودة أو موظف غير مصرح أو إيقاف استقبال؛ لا تتجاوز الرفض. |
| `402` | الرصيد نفد؛ اقرأ الملخص ورابط الشحن. |
| `409 IDEMPOTENCY_KEY_REUSED` | تعارض جسم الطلب؛ استعد العملية الأصلية بدل تغيير المفتاح. |
| `409 REQUEST_IN_PROGRESS` | OTP قيد التنفيذ؛ اتبع `Retry-After` واحتفظ بالعملية الأصلية. |
| `410 OTP_EXPIRED` | انتهى الرمز؛ لا تقبله. طلب جديد فقط بعد إجراء وموافقة جديدين من المستخدم. |
| `429` | انتظر `Retry-After` إن وجد؛ لا تبدل الحساب/الرقم للتحايل. |
| `202 uncertain` أو `502 DELIVERY_STATE_UNAVAILABLE` أو انقطاع الشبكة | النتيجة غير مؤكدة، وقد تكون الرسالة أرسلت. اقرأ الحالة أو أعد الطلب نفسه بالجسم والمفتاح نفسيهما؛ لا تنشئ عملية جديدة. |
| `502` مع تنبيه `failed/not_sent` | لا إرسال مؤكد، والرصيد مردود مرة واحدة. تكرار العملية يعيد الفشل. |
| `503` | الخدمة/الجلسة/الحجز غير متاح؛ افحص الجاهزية واحتفظ بالعملية الأصلية. |

إذا فقد رد الإرسال ولم تعرف `id`، أعد الطلب نفسه بالمفتاح والجسم الأصليين للحصول على الحالة دون خصم أو إرسال جديد. أخطاء المزود بعد حجز OTP تعيد معرّف المحاولة الأصلية، بما فيها المهلة والحماية. موافقة OTP الجديدة لا تُصطنع لتحديث جسم عملية قديمة: إعادة عملية محفوظة تستخدم وقت الحجز والمرسل الأصليين، حتى بعد انتهاء نافذة حداثة الموافقة؛ أما إنشاء عملية جديدة والتحقق البنيوي فيتطلبان موافقة حديثة فعلية. لا تغيّر المرسل أثناء عملية معلقة؛ إذا تغيّر لاحقًا تبقى العملية الأصلية قابلة للقراءة دون إرسال من الرقم الجديد، وتُقرأ نتيجة OTP غير المؤكدة من مرسلها الأصلي حتى إذا تغير اختيار الرقم. تحتفظ البوابة بتاريخ المصالحة 15 دقيقة؛ بعد فقده أو انتهاء احتفاظه قد تبقى النتيجة غير مؤكدة وتحتاج مراجعة، ولا يعني فقد التاريخ فشل الإرسال أو استحقاق رد تلقائي. سجل منع التكرار في قاعدة MZ3B يبقى قائمًا ما دام سجل العملية محفوظًا؛ لا توجد دورة حذف تلقائي له في هذا الإصدار.

## المتاح وغير المتاح

متاح في هذا الإصدار: مفتاح مشروع، OTP وإثبات الرمز، ملخص الرصيد/الجاهزية، قائمة موظفين بموافقة، تنبيهات معاملاتية فردية، قراءة حالة العملية، منع التكرار والخصم الذري، محاكاة صيغة لا ترسل ولا تخصم، ومجموعة أرقام اختيارية بحدود يومية واختيار أساسي/احتياطي أو توزيع الاستخدام. واجهات OTP الحالية مستمرة؛ لا تحتاج تغيير المفاتيح أو فصل الأرقام.

غير متاح: تأكيد تسليم مضمون أو webhook خارجي لتطبيق العميل، الإرسال التسويقي/الجماعي، الرد التلقائي بالذكاء الاصطناعي على واتساب، OTP البريد. إعداد Gemini واختباره منفصلان ولا يعنيان تفعيل ردود واتساب. لا تعد بعمل كامل قبل اختبار تطبيق العميل نفسه بموافقة مستلم محدد؛ اختبارات هذا الإصدار المحلية تستخدم مزودًا وهميًا ولم ترسل رسالة حقيقية جديدة.
