دليل البدء

في هذا المرجع، سنأخذك في جولة سريعة على كيفية استخدام LightOTP. كما هو متوقع، فإن LightOTP بسيط وسهل للمطورين، ويتطلب إعداداً بسيطاً للبدء.

سنرشدك في هذا الدليل إلى الخطوات الأساسية، بما في ذلك كيفية الاشتراك في خطة وكيفية استخدام مفاتيح API لبدء إرسال رسائل OTP.

العملية مباشرة ومصممة لمساعدتك على دمج وظيفة OTP في تطبيقك بسرعة وكفاءة.


اشترك في خطة

قبل إرسال أي رسائل OTP، عليك الاشتراك في خطة.

الخطوات:

  1. انتقل إلى قسم "الاشتراكات" في لوحة التحكم، ثم اضغط على "شراء خطة".
  2. اختر خطة من الخطط المتاحة، ثم اضغط على "اشترك".
  3. الدفع التلقائي غير متاح حالياً. اضغط على "تأكيد الطلب"، وأضف ملاحظات اختيارية إن لزم، وسيتواصل معك فريقنا عبر واتساب أو البريد الإلكتروني لتفعيل خطتك.

إرسال رسائل OTP

الخطوات:

  1. انتقل إلى قسم "API Keys" في لوحة التحكم وأضف مفتاح API جديداً. تأكّد من تخزين المفتاح بشكل آمن وعدم مشاركته مع أي شخص خارج فريقك.
  2. نادِ Endpoint إرسال الرسائل مع تمرير رمز OTP ورقم هاتف المستلم.
  3. احتفظ بقيمة id المُعادة لتتمكن لاحقاً من الاستعلام عن حالة التسليم عبر Endpoint التحقق من حالة الرسالة.

Endpoint

Endpoint:

POSThttps://api.lightotp.com/SendMessage
البندالقيمة
الطريقة (Method)POST
المسار (Path)/SendMessage
Content-Typeapplication/json
المصادقةHeader X-Api-Key
حالة النجاح200 OK

المصادقة

يجب أن يتضمن كل طلب مفتاح API الخاص بك في Header الطلب X-Api-Key. تُصدَر مفاتيح API لكل client من لوحة تحكم LightOTP وقد تُمنَح تاريخ انتهاء صلاحية اختياري. تُرفَض الطلبات التي تحوي مفتاحاً مفقوداً أو غير صالح أو منتهي الصلاحية قبل أن يُستهلَك أي رصيد.

تعامل مع مفتاح API كبيانات اعتماد. خزّنه على الخادم فقط، ولا تكشفه أبداً داخل تطبيقات الجوال أو شيفرة المتصفح أو أي repository عام. إذا تعرّض المفتاح للاختراق، فألغِه واستبدله من لوحة التحكم فوراً.

Headers

Headerإلزاميةالوصف
X-Api-Keyنعممفتاح API الخاص بحسابك.
Content-Typeنعميجب أن تكون application/json.
Accept-Languageلاar أو en. تتحكّم بلغة رسائل الخطأ وإشعارات البريد الإلكتروني التي تُعيدها المنصّة (ولا تختار لغة رسالة WhatsApp — راجع languageCode).

Body

مثال على الـ Body:

{
  "otpCode": "123456",
  "toPhoneE164": "+966551234567",
  "languageCode": "en",
  "idempotencyKey": "a3f1c2e4-9b27-4d6a-8e5f-1c2b3d4e5f60"
}
الحقلالنوعإلزاميالقيود
otpCodestringنعممن 1 إلى 8 محارف. أحرف (A–Z, a–z) وأرقام (0–9) فقط. لا فراغات ولا رموز.
toPhoneE164stringنعمرقم هاتف المستلم بصيغة E.164 (مثال: +966551234567).
languageCodestringلاوسم لغة بصيغة BCP-47 (مثال: en, ar, en_US, ar_SA). يختار لغة رسالة WhatsApp. إذا حُذف أو لم تتوفر لغة مطابقة، تعود المنصّة إلى اللغة الافتراضية لحسابك.
idempotencyKeyuuidلاUUID اختياري يحدّده client لإعادة المحاولة الآمنة. راجع idempotencyKey أدناه.

otpCode — قواعد التحقق الكاملة

  1. يجب أن يكون مضمّناً ضمن الطلب.
  2. أن يكون الطول ≤ 8 محارف.
  3. أن يكون كل محرف حرفاً أو رقماً. الواصلات والفراغات والنقاط وعلامات الترقيم الأخرى مرفوضة.

toPhoneE164 — صيغة رقم الهاتف

يجب أن يكون الرقم رقماً صالحاً ضمن منطقته؛ ولا يكفي أن يكون مكتوباً بشكل جيّد (مثلاً يبدأ بـ + ويملك عدد الخانات المناسب).

صالح:

  • +966551234567
  • +201001234567
  • +14155552671

غير صالح:

  • 0551234567 (بدون رمز دولة)
  • +999999999999 (منطقة غير صالحة)

languageCode — اختيار اللغة

إذا أرسلت قيمة languageCode، تُرسَل الرسالة بهذه اللغة. وإن لم تتوفر لغة مطابقة، تعود المنصّة إلى اللغة الافتراضية لحسابك.

idempotencyKey — إعادة المحاولة الآمنة

حين تُرسل قيمة idempotencyKey، تخزّنها المنصّة مع الرسالة التي تُنشئها. وإذا استدعيت Endpoint نفسه لاحقاً بنفس قيمة idempotencyKey وبنفس مفتاح API، فلن تُرسَل رسالة جديدة ولن يُخصم من رصيدك مرّة أخرى — بل تُعيد المنصّة الاستجابة الأصلية، أي نفس قيمة id ونفس messageStatus اللذين أعادتهما المرّة الأولى. هذا يجعل من الآمن إعادة المحاولة عند عدم استلام الاستجابة (انتهاء المهلة، انقطاع الاتصال، أعطال الشبكة المؤقتة) دون المخاطرة بإرسال مكرّر. وإذا كانت الاستجابة المُعادة تحمل messageStatus بقيمة Failed، فهذا يعني أن الرسالة الأصلية لم تصل، وإعادة المحاولة بنفس idempotencyKey ستُعيد فقط نتيجة الفشل ذاتها؛ ولإرسال الـ OTP فعلياً في هذه الحالة، عليك توليد قيمة idempotencyKey جديدة وإعادة الطلب. ويجب أن تكون كل قيمة idempotencyKey فريدة بين جميع طلباتك السابقة؛ فبمجرّد استخدامها تبقى مرتبطة بتلك الرسالة وحدها ولا يمكن إعادة استخدامها لرسالة مختلفة. ويمكنك حذف الحقل إن لم تكن بحاجة إلى هذه الضمانة — فالمنصّة تقبل الطلب بدونه.

استجابة النجاح — 200 OK

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

{
  "id": "f5b2d2e9-2c1f-4f1d-9c89-2c41f3d9a4e2",
  "messageStatus": "Sent"
}
الحقلالنوعالوصف
iduuidالمعرّف الفريد لرسالة LightOTP. احتفظ بهذه القيمة لتتمكن لاحقاً من الاستعلام عن حالة التسليم عبر CheckMessageStatus.
messageStatusstringالحالة الابتدائية التي يُعيدها WhatsApp وقت الاستدعاء. إحدى: Pending, Sent, Delivered, Read, Failed, Deleted. غالباً ما تكون Pending.

دورة حياة messageStatus

الحالةالمعنى
Pendingتم إنشاؤها محلياً؛ لم تُؤكَّد بعد من قِبل WhatsApp.
Sentقُبلت من قِبل WhatsApp للتسليم.
Deliveredسُلِّمت إلى جهاز المستلم.
Readفتح المستلم المحادثة التي تحوي الرسالة.
Failedرفض WhatsApp الإرسال أو فشل التسليم اللاحق.
Deletedحُذفت الرسالة (إجراء إداري).

استخدم Check Message Status لقراءة آخر حالة للرسالة.

الأخطاء

تُعاد جميع الأخطاء بصيغة JSON على الشكل:

مثال خطأ:

{
  "errorMessage": "InsufficientBalance"
}

رموز الخطأ

الرمزHTTPالمعنى
ApiKeyIsRequired400Header X-Api-Key مفقود أو فارغ.
ApiKeyNotFound404لا يوجد مفتاح API فعّال يطابق القيمة المرسلة.
ApiKeyExpired400انتهت صلاحية مفتاح API.
OTPCodeIsRequired400otpCode مفقود.
OTPCodeLengthMustBeLessThanOrEqualTo8400otpCode يتجاوز 8 محارف.
OTPCodeMustContainOnlyLettersOrDigits400otpCode يحوي محارف غير الأحرف والأرقام.
DestinationPhoneNumberIsRequired400toPhoneE164 مفقود.
InvalidphoneNumber400toPhoneE164 ليس رقم هاتف صالحاً بصيغة E.164.
PhoneNumberCanNotBeEmpty400toPhoneE164 كان فارغاً.
InsufficientBalance400لا يوجد اشتراك فعّال برصيد كافٍ لتغطية كلفة الرسالة لدولة الوجهة.
SenderNumberNotFound404لا يوجد رقم مرسل مخصص لحسابك.
TemplateNotFound404لم يتم العثور على لغة مطابقة لهذا الطلب.
رسالة فترة الانتظار للإرسال المكرّر400فترة الانتظار للإرسال المكرّر فعّالة لهذا الرقم. راجع حماية الإرسال المكرّر.
خطأ خدمة WhatsApp4xxرفضت خدمة WhatsApp الإرسال. تكون قيمة errorMessage هي الرسالة التي تُعيدها WhatsApp، وتعكس حالة HTTP حالة استجابة WhatsApp.
InternalServerError500حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى لاحقاً، وإذا استمرت المشكلة، تواصل مع الدعم.

الفوترة والرصيد

كل إرسال ناجح يخصم وحدة أو أكثر من رصيد أحدث اشتراك فعّال لديك يحوي رصيداً كافياً.

  • الكلفة الافتراضية: 1 رصيد لكل رسالة.
  • يتم خصم الرصيد حسب الدولة المرسل إليها وفق جدول الأسعار الدولية. الدول غير المدرجة في الجدول تُخصم بالكلفة الافتراضية: 1 رصيد لكل رسالة.
  • الرسائل الفاشلة لا تخصم من رصيدك، لكنها تبقى مسجلة لأغراض التتبع.
  • عندما ينتهي رصيد اشتراكك بالكامل، يُعلَّم تلقائياً كمنتهي الصلاحية.
  • نرسل لك بريداً إلكترونياً عندما يقترب رصيد اشتراكك من النفاد.

حماية الإرسال المكرّر

لتجنب إرسال نفس الـ OTP إلى المستلم نفسه مرات متكررة، تطبّق المنصّة فترة انتظار لكل رقم هاتف، تزداد كلما زادت إعادة الإرسال إلى الرقم نفسه:

  • فترة الانتظار الأولية: 30 ثانية بعد كل إرسال ناجح.
  • كل إرسال إضافي ضمن النافذة المتجدّدة لمدة 6 ساعات يُضاعف فترة الانتظار: الإرسال رقم 1 ← 30ث، رقم 2 ← 60ث، رقم 3 ← 120ث، رقم 4 ← 240ث، وهكذا.
  • تُحدّ فترة الانتظار بحد أقصى 6 ساعات.
  • تُعاد فترة الانتظار إلى الصفر بعد مرور 6 ساعات دون إرسال غير فاشل إلى الرقم نفسه.
  • الرسائل الفاشلة لا تُحسب ضمن فترة الانتظار.

خلال فترة الانتظار، تُعيد الواجهة 400 Bad Request مع errorMessage بالشكل: "You can't send another message to the same number yet. Please wait HH:mm:ss and try again."

حدود الطلبات

تطبّق المنصّة حدوداً على عدد الطلبات لكل IP لمنع الاستخدام المفرط. عند تجاوز الحد، تُعيد الواجهة 429 Too Many Requests.

مثال (cURL)

cURL:

curl -X POST "https://api.lightotp.com/SendMessage" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Accept-Language: en" \
  -d '{
    "otpCode": "482913",
    "toPhoneE164": "+966551234567",
    "languageCode": "en",
    "idempotencyKey": "a3f1c2e4-9b27-4d6a-8e5f-1c2b3d4e5f60"
  }'

التحقق من حالة الرسالة

بعد إرسال ناجح، استخدم هذا الـ Endpoint لقراءة آخر حالة لرسالة (بما في ذلك تفاصيل الفشل إن فشلت).

Endpoint:

POSThttps://api.lightotp.com/CheckMessageStatus
البندالقيمة
الطريقة (Method)POST
المسار (Path)/CheckMessageStatus
Content-Typeapplication/json
المصادقةHeader X-Api-Key
حالة النجاح200 OK

Body

مثال على الـ Body:

{
  "id": "f5b2d2e9-2c1f-4f1d-9c89-2c41f3d9a4e2"
}

استجابة النجاح — 200 OK

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

{
  "id": "f5b2d2e9-2c1f-4f1d-9c89-2c41f3d9a4e2",
  "messageStatus": "Delivered",
  "toPhoneE164": "+966551234567",
  "createdAt": "2026-05-14T09:13:42.812Z",
  "failureCode": null,
  "failureTitle": null,
  "failureReason": null,
  "failedAt": null
}
الحقلالنوعالوصف
iduuidمعرّف رسالة LightOTP.
messageStatusstringالحالة الراهنة: Pending أو Sent أو Delivered أو Read أو Failed أو Deleted.
toPhoneE164stringرقم هاتف الوجهة الذي أُرسلت إليه الرسالة.
createdAtdatetimeختم زمني UTC وقت إنشاء الرسالة.
failureCodeinteger | nullرمز خطأ خدمة WhatsApp إن وُجد.
failureTitlestring | nullنوع/عنوان خطأ WhatsApp.
failureReasonstring | nullسبب الفشل بصيغة مفهومة.
failedAtdatetime | nullختم زمني UTC وقت تسجيل الفشل.

حقول الفشل

عند فشل الرسالة، تُملأ حقول الفشل:

الحقلالنوعالوصف
failureCodeinteger | nullرمز خطأ خدمة WhatsApp إن وُجد.
failureTitlestring | nullنوع/عنوان خطأ WhatsApp.
failureReasonstring | nullسبب الفشل بصيغة مفهومة.
failedAtdatetime | nullختم زمني UTC وقت تسجيل الفشل.

الأخطاء

الرمزHTTPالمعنى
ApiKeyIsRequired400Header X-Api-Key مفقود.
ApiKeyNotFound404لا يوجد مفتاح API يطابق القيمة المرسلة.
ApiKeyExpired400انتهت صلاحية مفتاح API.
MessageNotFound404لا توجد رسالة بهذا id ضمن حسابك.

مثال (cURL)

cURL:

curl -X POST "https://api.lightotp.com/CheckMessageStatus" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -d '{ "id": "f5b2d2e9-2c1f-4f1d-9c89-2c41f3d9a4e2" }'

جرّبها بنفسك

انتقل إلى لوحة التحكم لإنشاء مفتاح API وإرسال أول رسالة OTP، أو تواصل معنا إذا احتجت مساعدة في البدء.