تكامل تطبيق الويب
تصف هذه الصفحة كيفية عمل رحلات Unico ونماذج التكامل المتاحة لدمجها في أحد التطبيقات.
الرحلة هي مجموعة الخطوات التي يمر بها المستخدم لإتمام التحقق من الهوية. على سبيل المثال: التقاط صورة للمستند وإجراء التقاط للوجه (لايفنس).
تتولى Unico إدارة التجربة بأكملها. جهد التكامل ضئيل: تُنشأ الرحلة عبر CreateProcess، ويُوجَّه المستخدم إليها، وتُستلَم النتيجة في النهاية. كل ما يحدث في الأثناء (الشاشات والتعليمات وعمليات التحقق) جاهز بالفعل وتتولى Unico صيانته.
- Web SDK (حزمة
unico-webframe): استخدمها عندما يتحكم الـ back-end لديك بالفعل في تدفق التحقق من الهوية ويحتاج فقط إلى مكوّن الالتقاط من جانب العميل. تُعيدbase64+ رمز JWT مشفّرًا مباشرةً إلى الـ callback الخاص بك؛ وأنت من يدير استدعاءات الـ API. - Web App Integration (حزمة
idpay-b2b-sdk): استخدمها عندما تريد أن تتولى Unico تنسيق الرحلة بأكملها (تدفقات متعددة الخطوات، التقاط المستند + لايفنس). حزمةidpay-b2b-sdkتشغّل نموذج Journeys SDK (iFrame) المضمَّن؛ أما نموذج الوصول المباشر (إعادة التوجيه) فلا يحتاج إلى أي مكتبة.
نموذجا التكامل
لكل عميل احتياجات مختلفة. تقدّم Unico نموذجين لتوجيه المستخدم إلى الرحلة.
| النموذج | الأنسب لـ |
|---|---|
| الوصول المباشر | تطبيقات الجوال التي تستخدم بالفعل WebView، أو تدفقات الويب التي يمكن أن تتم فيها الرحلة خارج الصفحة الرئيسية |
| Journeys SDK | تطبيقات الويب التي تحتاج إلى تجربة متكاملة وسلسة، مع إبقاء المستخدم داخل البيئة نفسها |
- الوصول المباشر
- Journeys SDK
يُعاد توجيه المستخدم إلى رابط مُستضاف من Unico، حيث تتم الرحلة. وعند الاكتمال، يُعاد إلى عنوان URL المحدَّد أثناء إنشاء العملية (المعامل callbackUri).
هذا هو أبسط نهج يمكن اعتماده: فهو لا يتطلب تثبيت أي مكتبة، ويعمل جيدًا عندما لا تحتاج الرحلة إلى أن تتم داخل صفحة التطبيق نفسها. في المقابل، فإن نقل المستخدم خارج بيئة العميل يميل إلى إحداث مزيد من الاحتكاك، ومن ثَمّ معدل تخلٍّ أعلى.
بعد إنشاء عملية، تتضمن استجابة الـ API عنوان URL للرحلة المستضافة من Unico. هناك طريقتان شائعتان لتوجيه المستخدم إليها:
- إعادة التوجيه القياسية. يُعاد توجيه المستخدم مباشرةً إلى عنوان URL للرحلة. وعند الاكتمال، تعيد Unico توجيهه إلى
callbackUriالمحدَّد أثناء إنشاء العملية. - علامة تبويب جديدة باستخدام
window.open(). تُفتح الرحلة في علامة تبويب جديدة في المتصفح، مما يُبقي المستخدم في سياق منفصل. في هذه الحالة، يُوصى بمراقبة تغيُّر عنوان URL إلىcallbackUriوإغلاق علامة التبويب بمجرد اكتمال العملية. للاطلاع على تفاصيل حول الـ API، راجع توثيق MDN.

في تطبيقات الجوال، من الشائع استخدام WebView لفتح الرحلة مباشرةً دون الحاجة إلى إعادة توجيه إضافية. في هذه الحالة، يقبل callbackUri أيضًا deeplink، مما يتيح أن يؤدي اكتمال الرحلة إلى فتح شاشة محددة في التطبيق الأصلي. ما عليك سوى ضبط الـ deeplink كوجهة عودة، ويتولى نظام التشغيل توجيه المستخدم إلى المكان الصحيح.

تتم الرحلة داخل التطبيق نفسه، دون إخراج المستخدم من سياقه. يُثبَّت Journeys SDK في التطبيق ويُستخدم لفتح الرحلة عند الحاجة.
هذا هو المسار الموصى به للحصول على تجربة أكثر تكاملًا وسلاسة، مع إبقاء المستخدم في البيئة نفسها طوال الوقت، مما يميل إلى تقليل الاحتكاك ومعدل التخلي على امتداد التدفق.
تقدّم Unico مكتبة JavaScript متوافقة مع المتصفحات الحديثة، تتيح دمج الرحلة في أي تطبيق تقريبًا بأسطر قليلة من التعليمات البرمجية.
التوافق
صُمِّمت المكتبة لتندمج في أي مشروع دون احتكاك، بغضّ النظر عن الـ stack المُستخدَم:
- أي تطبيق ويب. تُوزَّع بصيغة UMD، وتعمل عند استيرادها عبر أدوات الحزم الحديثة (مثل webpack أو Vite). متوافقة مع أي إطار عمل (React وAngular وVue) أو مع JavaScript الخالص.
- المتصفحات الحديثة. تتضمن المكتبة بالفعل الـ polyfills اللازمة لميزات مثل Promises و
async/await، مما يوسّع التوافق ليشمل أيضًا الإصدارات الأقدم من المتصفحات. - واجهات الويب البرمجية القياسية. تعمل الرحلة اعتمادًا على القدرات الأصلية للمتصفح، دون الاعتماد على إضافات أو مكتبات خارجية في المشروع.
كيف يعمل الـ SDK داخليًا
عند فتح رحلة، يُدرِج الـ SDK إطار iFrame في الصفحة ويتولى من تلك اللحظة التحكم في التجربة المرئية بالكامل. تعمل شاشات كل خطوة ونصوصها البرمجية وأصولها داخل هذا الـ iFrame، منذ لحظة بدء المستخدم وحتى اكتمال العملية.
هذا القرار المعماري مقصود: يضمن عزل الـ iFrame ألا تتداخل رحلة Unico مع أنماط التطبيق أو سلوكه. لا يتسرب أي نص برمجي إلى السياق الخارجي، ولا تتعارض أي قاعدة CSS مع أنماط التطبيق نفسه. والنتيجة تجربة متسقة للمستخدم النهائي وأثر ضئيل على منتج العميل.
بما أن Unico مسؤولة عن إنشاء الـ iFrame وإدارته، فإن تحسينات الرحلة (سواء في الأداء أو التجربة أو التحقق) تصل تلقائيًا إلى جميع المستخدمين، دون الحاجة إلى أي تغيير في التطبيق المُدمَج. وستعمل عملية التكامل دائمًا بأفضل التحسينات المتاحة، دون الحاجة إلى متابعة كل تطور في المنصة أو التفاعل معه.
البدء
الخطوة 1: التثبيت
تُشارَك حزمة idpay-b2b-sdk بين رحلات الدفع في IDPay ورحلات التحقق من الهوية. لحالات استخدام الهوية، استورد الفئة ByUnicoSDK كما هو موضح في الخطوات أدناه.
npm install idpay-b2b-sdk
الطريقة الموصى بها لتثبيت Journeys SDK هي عبر مدير اعتماديات مثل npm أو yarn، من الحزمة المتاحة على npm registry. وإلى جانب تبسيط التثبيت وإدارة الاعتماديات، يوفّر هذا النهج تحكمًا واضحًا في الإصدار المُستخدَم ويُسهّل التحديث في كل مرة يُنشر فيها إصدار جديد.
يتبع الـ SDK الإصدار الدلالي (SemVer)، ما يعني أن تحديثات patch وminor لا تُدخِل تغييرات كاسرة للتوافق. ومن الآمن تهيئة المشروع لتلقّي هذه التحديثات تلقائيًا. أما التغييرات التي قد تتطلب تعديلات في التكامل فهي محصورة في إصدارات major وتأتي دائمًا مصحوبة بدليل ترحيل.
البقاء على أحدث إصدار مهم بشكل خاص لسببين. الأول هو الأمان: تُنشر تصحيحات الأمان كلما اكتُشفت ثغرات أو سنحت فرص لتعزيز بروتوكول الاتصال. وتشغيل إصدار قديم يعني التخلي عن هذه الإصلاحات وتعريض التدفق لمخاطر غير ضرورية. والثاني هو الاستقرار: تُوزَّع إصلاحات الأخطاء بالطريقة نفسها، وقد تُظهر الإصدارات القديمة سلوكيات سبق حلّها في الإصدارات الأحدث.
قبل البدء، سجّل نطاقاتك لدى فريق دعم Unico. يجب أن تستخدم جميع النطاقات HTTPS.
الخطوة 2: استدعِ init(options)
يُهيّئ الـ SDK ويُحمّل مسبقًا النصوص البرمجية اللازمة لعمل الرحلة بشكل صحيح، مما يوفّر تجربة أكثر سلاسة للمستخدم النهائي. استدعِه في أبكر وقت ممكن في التدفق.
| المعامل | مطلوب | الوصف |
|---|---|---|
token | نعم | رمز العملية المُعاد من واجهة Create Process البرمجية |
env | لا | اضبطه على 'uat' لبيئات الاختبار فقط |
import { ByUnicoSDK } from 'idpay-b2b-sdk';
ByUnicoSDK.init({
token,
// env: 'uat' // لبيئات الاختبار فقط
});
الخطوة 3: استدعِ open(options)
يعرض الـ iFrame ويبدأ الرحلة للمستخدم. من هذه النقطة فصاعدًا، يحدث كل شيء تلقائيًا داخل الـ iFrame، دون الحاجة إلى إدارة أي خطوة وسيطة.
| المعامل | مطلوب | الوصف |
|---|---|---|
transactionId | نعم | معرّف العملية المُعاد من واجهة Create Process البرمجية |
token | نعم | رمز العملية المُعاد من واجهة Create Process البرمجية |
onFinish | نعم | دالة رد نداء تُنفَّذ عند انتهاء الرحلة أو إغلاقها |
onWidgetVisibilityChange | لا | دالة رد نداء تُنفَّذ عند تغيُّر حالة ظهور الأداة |
يحدث التفاعل التالي مع التطبيق عند انتهاء الرحلة، سواء أكملها المستخدم أم أغلقها. في تلك اللحظة، يستدعي الـ SDK دالة رد النداء onFinish المُمرَّرة كمعامل في open. ومن هناك، يمكن للتطبيق استدعاء واجهة getProcess البرمجية للتحقق من النتيجة، أو انتظار إشعار عبر Webhook إذا كان النهج غير المتزامن مفضّلًا.
بالإضافة إلى الاستعلام عن النتيجة، يُوصى باستخدام onFinish لمعالجة حالة الواجهة الأمامية للتطبيق:
- تجنّب الحلقات. امنع إعادة إنشاء العمليات فورًا ودون داعٍ إذا أعاد المستخدم تشغيل التدفق مباشرةً بعد انتهاء الرحلة.
- إدارة التدفق. تأكّد من توجيه المستخدم إلى الخطوة التالية في التطبيق، لتفادي بقائه عالقًا في شاشة بلا مخرج بعد إغلاق الرحلة.
تشير دالة رد النداء onFinish إلى أن المستخدم قد أكمل الرحلة، لكنها لا تضمن الموافقة. فقد تكون العملية انتهت برفض عند إحدى قواعد التحقق لدى Unico. الاستعلام عبر getProcess أو استلام إشعار Webhook ليس اختياريًا: فهما المصدران الوحيدان للنتيجة الفعلية، ويجب أن يستند سلوك التطبيق إليهما. ولا ينبغي استخدام onFinish بمفرده لتحديد ما إذا كان المستخدم قد تمت الموافقة عليه.
تتلقى دالة رد النداء onFinish كائنًا يصف كيفية انتهاء الرحلة:
| الحقل | النوع | الوصف |
|---|---|---|
type | string | كيفية انتهاء الرحلة: 'FINISH' (اكتملت) أو 'CLOSE' (أغلقها المستخدم قبل الانتهاء) |
transaction | object | undefined | موجود عندما يكون type بقيمة 'FINISH'؛ وundefined عندما يكون type بقيمة 'CLOSE' |
transaction.id | string | معرّف العملية (نفس transactionId المُمرَّر) |
transaction.redirectUrl | string | عنوان URL لإعادة توجيه المستخدم بعد الرحلة |
معالجة دالة رد النداء onWidgetVisibilityChange اختيارية وقد لا تكون ذات صلة بحالة استخدامك. تُستدعى كلما تغيّرت حالة ظهور الأداة، وهي مفيدة فقط في سيناريو محدد: تعرض بعض الرحلات خلفية شفافة، مما يُبقي صفحة التطبيق مرئية خلف التجربة. والتطبيقات التي تعرض نافذة منبثقة خاصة بها أثناء تدفق التحقق (على سبيل المثال، كجزء من تنسيق بين عدة مزودي خدمات KYC) قد ينتهي بها الأمر إلى عرض تلك النافذة خلف أداة Unico، مما يُضعِف التجربة المرئية. في هذه الحالة، تتيح دالة رد النداء للتطبيق إخفاء أي عناصر مرئية إضافية ما دامت رحلة Unico نشطة، واستعادتها بمجرد انتهائها. وإذا لم يكن لدى تطبيقك أي واجهة مستخدم قد تتداخل مع الأداة، فيمكنك حذفها بأمان.
ByUnicoSDK.open({
transactionId: '9bc22bac-1e64-49a5-94d6-9e4f8ec9a1bf',
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
onFinish: ({ transaction, type }) => {
if (type === 'FINISH') {
// اكتملت الرحلة (transaction = { id, redirectUrl }): تابِع تدفقك هنا.
}
// type === 'CLOSE' → أغلق المستخدم قبل الانتهاء;
},
// اختياري: مطلوب فقط إذا كان تطبيقك يعرض واجهة قد تتداخل مع الأداة.
onWidgetVisibilityChange: (visible) => {
// أخفِ نافذتك المنبثقة أو استعِدها بناءً على ظهور الأداة
},
});
// لإغلاق الـ SDK صراحةً في أي وقت:
ByUnicoSDK.close();
يوضّح مخطط التسلسل أدناه كيفية استخدام الـ SDK ونتيجة الـ API لتهيئة الـ iFrame:

الأمان
ينطبق مبرّر الأمان هذا تحديدًا على Web App Integration (idpay-b2b-sdk). يستخدم Web SDK (unico-webframe) نموذجًا مختلفًا: فهو يعمل بالكامل في سياق الصفحة ويتطلب CSP فعلًا. وهما منتجان مختلفان بمعماريتَي أمان مختلفتين.
الأمان في هذا النموذج مبني على طبقات، بدءًا من بروتوكول الاتصال بين الـ SDK والتطبيق الذي يعمل داخل الـ iFrame.
عند تحميل الرحلة، ينفّذ الطرفان مصافحة (handshake) لإنشاء الاتصال. وفي هذه العملية، يتحقق تطبيق Unico من مصدر رسالة حقن البيانات المستلَمة عبر postMessage مقابل قائمة مغلقة من النطاقات المصرّح بها، مقسّمة حسب البيئة (UAT وPROD). وتُرفض الرسائل الواردة من مصادر غير معتمدة على الفور، مما يمنع تضمين الرحلة في صفحات غير مصرّح بها ويزيل سطح الهجوم لثغرات مثل clickjacking.
بالإضافة إلى التحقق من المصدر، لا يتقدّم التدفق إلا مع رمز معاملة صالح: رمز JWT للاستخدام مرة واحدة، صادر وموقّع من الواجهة الخلفية لـ Unico. وهذا يضمن ألا يتمكن حتى مصدر مصرّح به من العمل برمز منتهي الصلاحية أو مُعاد استخدامه أو مزوَّر.
بعد المصافحة، يُحقَن الرمز في الـ iFrame ولا تتدفق بعد ذلك أي معلومات حساسة بين الطرفين. ويخدم كل الاتصال المتبقي التحكمَ في الواجهة فقط (الفتح والإغلاق وانتقالات الشاشات)، مما يمنع اعتراض بيانات العملية أو تسريبها أثناء الرحلة.
كما يحمي عزل الـ iFrame سلامة نصوص Unico البرمجية في وقت التشغيل. وبما أن الكود يعمل في سياق منفصل عن الصفحة، فلا يمكن للنصوص البرمجية الخارجية الوصول إليه أو تعديله، مما يضمن تنفيذ الرحلة تمامًا كما بُنيت، دون أي تدخّل.
بحكم التصميم، لا نعتمد CSP في نموذج التكامل هذا. فالنطاقات المصرّح بها جزء من تهيئة الأمان لكل عميل، وقد يؤدي كشفها علنًا في الترويسات إلى تسهيل رسم خريطة البنية التحتية على الجهات الخبيثة. وبما أن تحديد هوية العميل لا يحدث إلا عند init، فلا يمكن حقن هذه النطاقات ديناميكيًا في الترويسات قبل تلك اللحظة، مما يجعل CSP غير عملي دون التخلي عن هذه الخصوصية. وتُوفَّر جميع ضمانات الأمان من خلال بروتوكول المصافحة الموضّح أعلاه.
استكشاف أخطاء الـ SDK وإصلاحها
يتناول هذا القسم أكثر المشكلات شيوعًا التي تُصادَف أثناء التكامل والطرق الموصى بها للتحقيق فيها.
سلوك غير متوقع أو تدفق متوقف
تحقق مما إذا كان أي نص برمجي في التطبيق يتلاعب مباشرةً بالـ iFrame في الـ DOM. ينشئ الـ SDK الـ iFrame ويديره داخل body الصفحة، وأي تعديل خارجي (سواء في النطاق أو الموضع أو السمات) قد يتداخل مع دورة حياة الرحلة ويسبّب سلوكًا غير متوقع.
تجربة مرئية مختلفة عن المتوقع
تحقق مما إذا كانت أي ورقة أنماط عامة في التطبيق تتجاوز خصائص داخل الـ iFrame. ينشئ الـ SDK الـ iFrame وجميع عناصره الداخلية بمعرّفات ديناميكية وفئات مسبوقة بـ unico، مما يقلّل بشكل كبير من خطر التعارض عبر محدِّدات المعرّف أو الفئة. ومع ذلك، فإن قواعد CSS ذات النطاق الواسع (مثل محدِّدات الوسوم) قد تصل إلى عناصر داخل الـ iFrame وتغيّر التجربة المرئية المقدَّمة للمستخدم.
تعديل ملفات مكتبة الـ SDK مباشرةً
تحقق مما إذا كان أي ملف من ملفات المكتبة قد عُدِّل خارج مدير الاعتماديات. يجب إدارة المكتبة حصريًا عبر npm أو yarn، دو ن إجراء تعديلات مباشرة على الملفات المثبَّتة. فقد تؤدي التعديلات اليدوية إلى سلوك شاذ يصعب إعادة إنتاجه وتجعل تقديم الدعم من Unico متعذّرًا.
لا تُبقِ DevTools مفتوحة أثناء اختبارات الالتقاط
يستخدم تطبيق Unico الـ Capture SDK (unico-webframe) لالتقاط الوجه، وهو يكتشف أدوات DevTools المفتوحة كإشارة احتيال محتملة ويحظر الإرسال. أغلِق DevTools قبل تشغيل اختبارات الالتقاط الشاملة (end-to-end).
النماذج الموضّحة في هذه الوثائق (الوصول المباشر وJourneys SDK) هي طرق التكامل الوحيدة المدعومة رسميًا من Unico. وقد تتسبب عمليات التكامل التي تحيد عن هذه المعايير في سلوك غير متوقع، وإخفاقات في تدفق الأمان، وانقطاعات في الرحلة، ولن تكون مشمولة بدعم Unico.
بعض الأمثلة على الأنهج غير المدعومة:
- تضمين الـ SDK داخل WebView في تطبيقات الجوال. في هذه الحالات، النهج الصحيح هو استخدام نموذج الوصول المباشر، بفتح رابط الرحلة مباشرةً في الـ WebView دون إشراك Journeys SDK.
- تحميل الـ iFrame مباشرةً عبر وسم HTML
<iframe>، دون المرور عبر Journeys SDK. الـ iFrame تفصيل تنفيذي داخلي للـ SDK ولا ينبغي إنشاؤه يدويًا. والنهج الصحيح هو استخدام Journeys SDK، الذي يدير دورة حياة الـ iFrame بأمان وضمن المعايير المتوقعة.
إذا كان هناك أي شك حول ما إذا كان نهج ما ضمن المعيار المدعوم، فراجع الوثائق أو تواصل مع الدعم قبل المضي قدمًا في التنفيذ.