دليل البدء
في هذا المرجع، سنأخذك في جولة سريعة على كيفية استخدام LightOTP. كما هو متوقع، فإن LightOTP بسيط وسهل للمطورين، ويتطلب إعداداً بسيطاً للبدء.
سنرشدك في هذا الدليل إلى الخطوات الأساسية، بما في ذلك كيفية الاشتراك في خطة وكيفية استخدام مفاتيح API لبدء إرسال رسائل OTP.
العملية مباشرة ومصممة لمساعدتك على دمج وظيفة OTP في تطبيقك بسرعة وكفاءة.
اشترك في خطة
قبل إرسال أي رسائل OTP، عليك الاشتراك في خطة.
الخطوات:
- انتقل إلى قسم "الاشتراكات" في لوحة التحكم، ثم اضغط على "شراء خطة".
- اختر خطة من الخطط المتاحة، ثم اضغط على "اشترك".
- الدفع التلقائي غير متاح حالياً. اضغط على "تأكيد الطلب"، وأضف ملاحظات اختيارية إن لزم، وسيتواصل معك فريقنا عبر واتساب أو البريد الإلكتروني لتفعيل خطتك.
إرسال رسائل OTP
الخطوات:
- انتقل إلى قسم "API Keys" في لوحة التحكم وأضف مفتاح API جديداً. تأكّد من تخزين المفتاح بشكل آمن وعدم مشاركته مع أي شخص خارج فريقك.
- نادِ Endpoint إرسال الرسائل مع تمرير رمز OTP ورقم هاتف المستلم.
- احتفظ بقيمة id المُعادة لتتمكن لاحقاً من الاستعلام عن حالة التسليم عبر Endpoint التحقق من حالة الرسالة.
Endpoint
Endpoint:
| البند | القيمة |
|---|---|
| الطريقة (Method) | POST |
| المسار (Path) | /SendMessage |
| Content-Type | application/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"
}| الحقل | النوع | إلزامي | القيود |
|---|---|---|---|
otpCode | string | نعم | من 1 إلى 8 محارف. أحرف (A–Z, a–z) وأرقام (0–9) فقط. لا فراغات ولا رموز. |
toPhoneE164 | string | نعم | رقم هاتف المستلم بصيغة E.164 (مثال: +966551234567). |
languageCode | string | لا | وسم لغة بصيغة BCP-47 (مثال: en, ar, en_US, ar_SA). يختار لغة رسالة WhatsApp. إذا حُذف أو لم تتوفر لغة مطابقة، تعود المنصّة إلى اللغة الافتراضية لحسابك. |
idempotencyKey | uuid | لا | UUID اختياري يحدّده client لإعادة المحاولة الآمنة. راجع idempotencyKey أدناه. |
otpCode — قواعد التحقق الكاملة
- يجب أن يكون مضمّناً ضمن الطلب.
- أن يكون الطول ≤ 8 محارف.
- أن يكون كل محرف حرفاً أو رقماً. الواصلات والفراغات والنقاط وعلامات الترقيم الأخرى مرفوضة.
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"
}| الحقل | النوع | الوصف |
|---|---|---|
id | uuid | المعرّف الفريد لرسالة LightOTP. احتفظ بهذه القيمة لتتمكن لاحقاً من الاستعلام عن حالة التسليم عبر CheckMessageStatus. |
messageStatus | string | الحالة الابتدائية التي يُعيدها 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 | المعنى |
|---|---|---|
ApiKeyIsRequired | 400 | Header X-Api-Key مفقود أو فارغ. |
ApiKeyNotFound | 404 | لا يوجد مفتاح API فعّال يطابق القيمة المرسلة. |
ApiKeyExpired | 400 | انتهت صلاحية مفتاح API. |
OTPCodeIsRequired | 400 | otpCode مفقود. |
OTPCodeLengthMustBeLessThanOrEqualTo8 | 400 | otpCode يتجاوز 8 محارف. |
OTPCodeMustContainOnlyLettersOrDigits | 400 | otpCode يحوي محارف غير الأحرف والأرقام. |
DestinationPhoneNumberIsRequired | 400 | toPhoneE164 مفقود. |
InvalidphoneNumber | 400 | toPhoneE164 ليس رقم هاتف صالحاً بصيغة E.164. |
PhoneNumberCanNotBeEmpty | 400 | toPhoneE164 كان فارغاً. |
InsufficientBalance | 400 | لا يوجد اشتراك فعّال برصيد كافٍ لتغطية كلفة الرسالة لدولة الوجهة. |
SenderNumberNotFound | 404 | لا يوجد رقم مرسل مخصص لحسابك. |
TemplateNotFound | 404 | لم يتم العثور على لغة مطابقة لهذا الطلب. |
رسالة فترة الانتظار للإرسال المكرّر | 400 | فترة الانتظار للإرسال المكرّر فعّالة لهذا الرقم. راجع حماية الإرسال المكرّر. |
خطأ خدمة WhatsApp | 4xx | رفضت خدمة WhatsApp الإرسال. تكون قيمة errorMessage هي الرسالة التي تُعيدها WhatsApp، وتعكس حالة HTTP حالة استجابة WhatsApp. |
InternalServerError | 500 | حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى لاحقاً، وإذا استمرت المشكلة، تواصل مع الدعم. |
الفوترة والرصيد
كل إرسال ناجح يخصم وحدة أو أكثر من رصيد أحدث اشتراك فعّال لديك يحوي رصيداً كافياً.
- الكلفة الافتراضية: 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:
| البند | القيمة |
|---|---|
| الطريقة (Method) | POST |
| المسار (Path) | /CheckMessageStatus |
| Content-Type | application/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
}| الحقل | النوع | الوصف |
|---|---|---|
id | uuid | معرّف رسالة LightOTP. |
messageStatus | string | الحالة الراهنة: Pending أو Sent أو Delivered أو Read أو Failed أو Deleted. |
toPhoneE164 | string | رقم هاتف الوجهة الذي أُرسلت إليه الرسالة. |
createdAt | datetime | ختم زمني UTC وقت إنشاء الرسالة. |
failureCode | integer | null | رمز خطأ خدمة WhatsApp إن وُجد. |
failureTitle | string | null | نوع/عنوان خطأ WhatsApp. |
failureReason | string | null | سبب الفشل بصيغة مفهومة. |
failedAt | datetime | null | ختم زمني UTC وقت تسجيل الفشل. |
حقول الفشل
عند فشل الرسالة، تُملأ حقول الفشل:
| الحقل | النوع | الوصف |
|---|---|---|
failureCode | integer | null | رمز خطأ خدمة WhatsApp إن وُجد. |
failureTitle | string | null | نوع/عنوان خطأ WhatsApp. |
failureReason | string | null | سبب الفشل بصيغة مفهومة. |
failedAt | datetime | null | ختم زمني UTC وقت تسجيل الفشل. |
الأخطاء
| الرمز | HTTP | المعنى |
|---|---|---|
ApiKeyIsRequired | 400 | Header X-Api-Key مفقود. |
ApiKeyNotFound | 404 | لا يوجد مفتاح API يطابق القيمة المرسلة. |
ApiKeyExpired | 400 | انتهت صلاحية مفتاح API. |
MessageNotFound | 404 | لا توجد رسالة بهذا 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، أو تواصل معنا إذا احتجت مساعدة في البدء.