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

# SDK جافاسكريبت للتحقق من الهوية: KYC للويب

> SDK جافاسكريبت جاهز للاستخدام لـ KYC وKYB وAML وكشف الحيوية البيومترية. مدمج أو إعادة توجيه أو iframe. من $0.33 لكل فحص KYC كامل، و$10 مجانًا شهريًا، بدون عقود.



مطالبة تكامل JavaScript SDK
        نسخ الموجّه إلى الحافظة



      
      

\<pre>

\`Integrate Didit identity verification into my web application using the JavaScript SDK.

\## Setup
Install: npm install @didit-protocol/sdk-web
Or CDN: <script src="https://unpkg.com/@didit-protocol/sdk-web/dist/didit-sdk.umd.min.js"></script>

\## Integration Flow
1\. (Option A — UniLink) Use a fixed UniLink URL from the Didit Console (no backend needed)
2\. (Option B — API session) Backend creates a session via POST /v3/session/ → 201 response includes "url"
3\. Frontend calls DiditSdk.shared.startVerification({ url }) — the SDK opens a modal (or inline if embedded mode)
4\. On completion, the SDK invokes DiditSdk.shared.onComplete(result) with type "completed" | "cancelled" | "failed"
5\. Backend receives full signed decision via webhook (status.updated)

\## Frontend Code — Vanilla JS / TypeScript
import { DiditSdk } from '@didit-protocol/sdk-web';

DiditSdk.shared.onComplete = (result) => {
switch (result.type) {
case 'completed':
  // result.session.status: "Approved" | "Pending" | "Declined"
  console.log('Done:', result.session.sessionId, result.session.status);
  break;
case 'cancelled':
  console.log('User cancelled');
  break;
case 'failed':
  console.error('Failed:', result.error.type, result.error.message);
  break;
}
};

// Modal mode (default)
DiditSdk.shared.startVerification({
url: 'https://verify.didit.me/session/SESSION_TOKEN' // from backend OR UniLink
});

// Inline / embedded mode
DiditSdk.shared.startVerification({
url: 'https://verify.didit.me/session/SESSION_TOKEN',
configuration: { embedded: true, embeddedContainerId: 'didit-container' }
});

\## Frontend Code — React
function VerifyButton({ userId }) {
const [loading, setLoading] = useState(false);

async function handleVerify() {
setLoading(true);
const res = await fetch('/api/create-session', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ user_id: userId })
});
const { url } = await res.json(); // OpenAPI field is named "url"

const { DiditSdk } = await import('@didit-protocol/sdk-web');
DiditSdk.shared.onComplete = (result) => {
  if (result.type === 'completed') {
    // update UI; final, signed result arrives on backend via webhook
  }
  setLoading(false);
};
DiditSdk.shared.startVerification({ url });
}

return <button onClick={handleVerify} disabled={loading}>Verify Identity</button>;
}

\## Backend: Create Session
POST https://verification.didit.me/v3/session/
Headers: { "x-api-key": DIDIT_API_KEY, "Content-Type": "application/json" }
Body: { "workflow_id": DIDIT_WORKFLOW_ID, "callback": "https://myapp.com/done", "vendor_data": userId }
Returns 201 (all 10 fields, per OpenAPI):
\{
"session_id": "uuid",
"session_number": 43762,
"session_token": "3FaJ9wLqX2Mz",   // 12-char URL-safe token; valid until the session expires
"url": "https://verify.didit.me/session/3FaJ9wLqX2Mz",
"vendor_data": "userId",
"metadata": null,
"status": "Not Started",
"workflow_id": "uuid",
"workflow_version": 3,
"callback": "https://myapp.com/done"
}
Pass the "url" field to DiditSdk.shared.startVerification({ url }) — never build the URL by hand.
(If the request sets "language", the URL gains a language segment: https://verify.didit.me/es/session/...)

\## SDK Surface (singleton — DiditSdk.shared)
Methods:  startVerification(options), close(), destroy()
Callbacks: onComplete(result), onStateChange(state, error?), onEvent(event)
State enum: 'idle' | 'loading' | 'ready' | 'error'

\## Rate Limits
600 session-create requests per minute per API key (falls back to bearer token, then client IP), plus a shared budget of 300 write (POST/PATCH/DELETE) requests per minute across all endpoints — the 300/min budget is exhausted first. Exceeding either returns HTTP 429 with Retry-After.

\## Environment Variables
\- DIDIT_API_KEY — backend only (Didit Console > API & Webhooks)
\- DIDIT_WORKFLOW_ID — backend only (Didit Console > Workflows)
\- Never expose the API key on the frontend — the session_token embedded in "url" is the only credential the SDK needs. It grants access to that one session's flow (valid until the session expires), so don't log or share it either.

\## Docs
\- JavaScript SDK: https://docs.didit.me/integration/web-sdks/javascript-sdk
\- Create Session API: https://docs.didit.me/sessions-api/create-session
\- Webhooks: https://docs.didit.me/integration/webhooks`

\</pre>



      
      

الصق في

يوفر Didit JavaScript SDK طريقة برمجية لدمج التحقق من الهوية في تطبيق الويب لديك، مع تحكم كامل في تجربة المستخدم.***## الميزات- **واجهة برمجية بسيطة** - نمط Singleton مع دوال سهلة الاستخدام
- **تكامل مرن** - استخدم رابط UniLink مباشرةً أو أنشئ الجلسات عبر الخادم الخلفي
- **متجاوب** - يعمل على متصفحات أجهزة سطح المكتب والأجهزة المحمولة
- **قابل للتخصيص** - خيارات إعداد للتنسيق والسلوك
- **صيغ متعددة** - بناءات ESM وCommonJS وUMD
- **دعم TypeScript** - تعريفات الأنواع الكاملة مضمّنة
- **الوضعان المنبثق والمضمَّن** - اختر بين طبقة نافذة منبثقة أو تضمين داخل الصفحة
- **استدعاءات الأحداث** - أحداث فورية لتقدم التحقق (بدء التحقق، اكتمال الخطوة، انتهاء التحقق)
- **إدارة الحالة** - راقب حالة SDK لبناء واجهة مخصصة***## التثبيت### NPM/Yarn```bash theme={null}
npm install @didit-protocol/sdk-web
# or
yarn add @didit-protocol/sdk-web
```### CDN (UMD)```html theme={null}
<script src="https://unpkg.com/@didit-protocol/sdk-web/dist/didit-sdk.umd.min.js"></script>
```> [!NOTE]
>
> أحدث إصدار منشور على npm هو `0.5.1`.
> أضاف `0.5.0` الدالة `DiditSdk.shared.submitEvent()` (راجع [إرسال الأحداث](#إرسال-الأحداث))، ويتيح `0.5.1` للتدفق المستضاف طلب الهوية الرقمية من محفظة الهوية الرقمية داخل SDK، ويُبقي عملية التشغيل الفاشلة في الحالة `error` مع `errorMessage` الخاصة بها.
> أضاف `0.4.0` خيارات الكاميرا التي تقدمها SDKs الأصلية أصلاً، بما فيها `defaultLivenessCamera` التي تفتح التقاط الوجه على الكاميرا الخلفية (راجع [خيارات الكاميرا](#خيارات-الكاميرا)).### التحقق من الإصدار المثبّتيبقى مدير الحزم لديك المرجع الأساسي لمعرفة الإصدار المثبّت:```bash theme={null}
npm list @didit-protocol/sdk-web
npm view @didit-protocol/sdk-web version
```يمكنك أيضاً فحص التصدير وقت التشغيل:```typescript theme={null}
const { SDK_VERSION } = await import('@didit-protocol/sdk-web');

console.log(SDK_VERSION);
```ابتداءً من الإصدار `0.3.1`، يُولَّد هذا التصدير من إصدار الحزمة في كل صيغ JavaScript (ESM وCommonJS وUMD وUMD المصغّر) وفي ملف تعريف TypeScript، لذلك يتطابق دائماً مع الإصدار المثبّت.الإصدار `0.3.0` والإصدارات الأقدم تُبلغ عن `0.2.1` من هذا التصدير بغض النظر عن الإصدار المثبّت فعلياً. في هذه الإصدارات، استخدم `npm list` أو ملف القفل (lockfile) الخاص بك بدلاً من ذلك.***## JavaScript العادي### ES Modules / TypeScript```typescript theme={null}
import { DiditSdk } from '@didit-protocol/sdk-web';

// Set up completion callback
DiditSdk.shared.onComplete = (result) => {
  switch (result.type) {
    case 'completed':
      console.log('Verification completed!');
      console.log('Session ID:', result.session?.sessionId);
      console.log('Status:', result.session?.status);
      break;
    case 'cancelled':
      console.log('User cancelled verification');
      break;
    case 'failed':
      console.error('Verification failed:', result.error?.message);
      break;
  }
};

// Start verification with the `url` returned by POST /v3/session/ (or your UniLink)
DiditSdk.shared.startVerification({
  url: 'https://verify.didit.me/session/3FaJ9wLqX2Mz'
});
```### وسم Script (UMD)```html theme={null}
<script src="https://unpkg.com/@didit-protocol/sdk-web/dist/didit-sdk.umd.min.js"></script>
<script>
  const { DiditSdk } = DiditSDK;

  DiditSdk.shared.onComplete = (result) => {
    if (result.type === 'completed') {
      alert('Verification completed: ' + result.session.status);
    }
  };

  function startVerification() {
    DiditSdk.shared.startVerification({
      // You can get this link by clicking on "copy link" in the workflows view
      url: 'https://verify.didit.me/u/WORKFLOW_ID_IN_BASE_64'
    });
  }
</script>

<button onclick="startVerification()">Verify Identity</button>
```***## أمثلة الأطر البرمجية> [card] [أمثلة SDK للويب](https://github.com/didit-protocol/sdk-web-examples)
>
> React وAngular وSvelte وNext.js وNuxt وVue وغيرها، مع أمثلة ووثائق لكل إطار عمل.***## طرق التكاملهناك طريقتان لدمج SDK:### الطريقة 1: رابط UniLink (الأبسط)استخدم رابط UniLink الخاص بسير العمل مباشرةً من Didit Console. لا يتطلب خادماً خلفياً.```typescript theme={null}
DiditSdk.shared.startVerification({
  // You can get this link by clicking on "copy link" in the workflows view
  url: 'https://verify.didit.me/u/WORKFLOW_ID_IN_BASE_64'
});
```احصل على رابط UniLink الخاص بك من [Didit Console](https://business.didit.me) ← سير العمل الخاص بك ← نسخ الرابط.**سيُرسَل إليك معرّف الجلسة session\_id المُولَّد عبر حدث.**
**[راجع مرجع الأحداث هنا](#مرجع-الأحداث)**### الطريقة 2: جلسة من الخادم الخلفي (موصى بها للإنتاج)ينشئ الخادم الخلفي جلسة عبر واجهة Didit API ويعيد رابط التحقق المستضاف. يمنحك هذا تحكماً في `vendor_data` و`callback` لكل جلسة و`metadata`، ويتيح لك إنشاء الجلسات قبل وصول المستخدم إلى الواجهة الأمامية.اقرأ المزيد في [مرجع واجهة إنشاء الجلسة](https://docs.didit.me/ar/sessions-api/create-session.md).**الخادم الخلفي (Node.js / Express)**```javascript theme={null}
import express from 'express';
const app = express();
app.use(express.json());

app.post('/api/create-session', async (req, res) => {
  const response = await fetch('https://verification.didit.me/v3/session/', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.DIDIT_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      workflow_id: process.env.DIDIT_WORKFLOW_ID,
      vendor_data: req.body.userId,             // links the session to your user
      callback: 'https://yourapp.com/verified', // optional — overrides workflow default
    }),
  });

  if (!response.ok) {
    return res.status(response.status).send(await response.text());
  }

  // 201 response fields (per OpenAPI): session_id, session_number, session_token, url,
  // vendor_data, metadata, status, workflow_id, workflow_version, callback
  const session = await response.json();
  res.json({ session_id: session.session_id, url: session.url });
});
```**الواجهة الأمامية**```typescript theme={null}
import { DiditSdk } from '@didit-protocol/sdk-web';

const res = await fetch('/api/create-session', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ userId: 'user-123' }),
});
const { url } = await res.json();

DiditSdk.shared.startVerification({
  url,
  configuration: {
    loggingEnabled: true,
  },
});
```> [!NOTE]
>
> حقل الاستجابة لإنشاء الجلسة اسمه `url` (راجع [مخطط OpenAPI لإنشاء الجلسة](https://docs.didit.me/ar/sessions-api/create-session.md)). مرّره مباشرةً إلى `startVerification({ url })`.***## الإعدادات| الخيار | النوع | الافتراضي | الوصف |
| - | - | - | - |
| `loggingEnabled` | `boolean` | `false` | تفعيل تسجيل SDK لأغراض تصحيح الأخطاء |
| `containerElement` | `HTMLElement` | `document.body` | عنصر حاوية مخصص لتركيب النافذة المنبثقة |
| `zIndex` | `number` | `9999` | قيمة z-index لطبقة النافذة المنبثقة |
| `showCloseButton` | `boolean` | `true` | إظهار زر الإغلاق في النافذة المنبثقة |
| `showExitConfirmation` | `boolean` | `true` | إظهار نافذة تأكيد الخروج عند الإغلاق |
| `closeModalOnComplete` | `boolean` | `false` | إغلاق النافذة المنبثقة تلقائياً عند اكتمال التحقق |
| `embedded` | `boolean` | `false` | عرض التحقق داخل الصفحة بدلاً من طبقة النافذة المنبثقة |
| `embeddedContainerId` | `string` | — | معرّف عنصر الحاوية في الوضع المضمَّن (مطلوب عندما تكون `embedded` بقيمة `true`) |
| `defaultDocumentCamera` | `'front' \| 'back'` | `'back'` | الكاميرا التي يبدأ بها التقاط المستند أولاً. راجع [خيارات الكاميرا](#خيارات-الكاميرا) |
| `defaultLivenessCamera` | `'front' \| 'back'` | `'front'` | الكاميرا التي يبدأ بها التقاط الوجه (الحيوية) أولاً. راجع [خيارات الكاميرا](#خيارات-الكاميرا) |
| `showDocumentCameraSwitchButton` | `boolean` | `true` | إظهار زر تبديل الكاميرا أثناء خطوة المستند |
| `showLivenessCameraSwitchButton` | `boolean` | `true` | إظهار زر تبديل الكاميرا أثناء خطوة كشف الحيوية |> [!TIP]
>
> راجع [تعريفات أنواع TypeScript الكاملة](#أنواع-typescript) أدناه للاطلاع على الواجهة `DiditSdkConfiguration` كاملةً.***## خيارات الكاميرا> [!NOTE]
>
> تتطلب خيارات الكاميرا الإصدار **0.4.0** من `@didit-protocol/sdk-web` أو أحدث.يوفّر SDK الويب الخيارات الأربعة نفسها للكاميرا المتوفرة في [SDKs الأصلية](https://docs.didit.me/ar/integration/native-sdks/overview.md). افتراضيًا، يفتح التقاطُ المستند الكاميرا الخلفية، ويفتح التقاطُ الوجه (كشف الحيوية) الكاميرا الأمامية (السيلفي)، وتتيح الخطوتان مبدّلَ الكاميرا داخل الالتقاط على الأجهزة التي تحتوي على أكثر من كاميرا. اضبط `defaultLivenessCamera: 'back'` لفتح التقاط الوجه بالكاميرا الخلفية، مثلًا في الأكشاك أو عندما يمسك المشغّل الجهاز ويوجّهه نحو الشخص الذي يجري التحقق منه.| الخيار | النوع | الافتراضي | الوصف |
| - | - | - | - |
| `defaultDocumentCamera` | `'front' \| 'back'` | `'back'` | العدسة المستخدمة عند الدخول إلى شاشة التقاط المستند للمرة الأولى |
| `defaultLivenessCamera` | `'front' \| 'back'` | `'front'` | العدسة المستخدمة عند الدخول إلى شاشة التقاط كشف الحيوية (الوجه السلبي) للمرة الأولى |
| `showDocumentCameraSwitchButton` | `boolean` | `true` | يعرض مبدّل الكاميرا داخل الالتقاط على شاشة المستند؛ القيمة `false` تُثبّت المستخدم على `defaultDocumentCamera` |
| `showLivenessCameraSwitchButton` | `boolean` | `true` | يعرض مبدّل الكاميرا داخل الالتقاط على شاشة كشف الحيوية؛ القيمة `false` تُثبّت المستخدم على `defaultLivenessCamera` |```typescript theme={null}
// A kiosk: the operator points the device at the person, on the rear camera, with no way to switch
DiditSdk.shared.startVerification({
  url,
  configuration: {
    defaultLivenessCamera: 'back',
    showLivenessCameraSwitchButton: false
  }
});
```- القيم المقبولة للعدسة هي `'front'` و`'back'`. أي قيمة أخرى تُتجاهل، وكذلك علامة المبدّل إذا لم تكن قيمة منطقية.
- الجهاز الذي لا يحتوي على الكاميرا المطلوبة يحتفظ بكاميرته المتوفرة: حاسوب محمول طُلب له `'back'` يستخدم كاميرا الويب الخاصة به. يُخفى المبدّل على الأجهزة ذات الكاميرا الواحدة مهما كانت العلامات.
- تنطبق خيارات كشف الحيوية على فحص كشف الحيوية السلبي. كشف الحيوية النشط لا يتأثر.
- يمرّر SDK الخيارات إلى صفحة التحقق بوصفها معاملات استعلام في عنوان التحقق: `document_camera` و`liveness_camera` و`document_camera_switch` و`liveness_camera_switch`. إذا فتحت عنوان التحقق مباشرة بدلًا من المرور عبر SDK، فاضبطها بنفسك: أضف `?liveness_camera=back` إلى عنوان بلا سلسلة استعلام، أو `&liveness_camera=back` إلى عنوان يحتوي معاملات بالفعل، أو اضبطها بواجهة `URL` لتتم معالجة الحالتين:```typescript theme={null}
const verificationUrl = new URL(url);
verificationUrl.searchParams.set('liveness_camera', 'back');
verificationUrl.searchParams.set('liveness_camera_switch', 'false');
window.location.assign(verificationUrl.toString());
```***## إرسال الأحداث`DiditSdk.shared.submitEvent()` يضع في قائمة الانتظار أحداث المستخدم النهائي (التسجيل، وتسجيل الدخول، وتسجيل الدخول الفاشل، وتسجيل الخروج، وإعادة تعيين كلمة المرور، والمصادقة متعددة العوامل، وتغيير الجهاز) لمراقبة الأحداث لدى Didit.
يُنشئ الخادم الخلفي لديك token للمراقبة للشخص، ويرسل SDK الأحداث على دفعات مع بصمة الجهاز.
لا ترسل مفتاح API إلى المتصفح مطلقًا.```typescript theme={null}
DiditSdk.shared.submitEvent({
  monitoringToken, // minted by your backend for this person
  event: { category: "auth", actionType: "login", payload: { method: "password" } },
});
```للاطلاع على token وحقول الحدث وسلوك التسليم، انظر [إرسال أحداث SDK](https://docs.didit.me/ar/transaction-monitoring/sdk-event-submission.md).***## ضبط حجم النافذة والتمرير> [!NOTE]
>
> يتطلب سلوك الحجم الموضّح أدناه الإصدار **0.3.1** أو أحدث. **0.3.0** والإصدارات الأقدم قد تقتطع تدفق التحقق على منافذ العرض القصيرة في سطح المكتب والوضع الأفقي.يستخدم وضع النافذة المنبثقة عرضًا أقصى قدره 500px وارتفاعًا أقصى قدره 700px. على منافذ العرض القصيرة في سطح المكتب والوضع الأفقي، يبلغ حجم iframe نسبة 90% من منطقة العرض المرئية. يتمرّر تدفق التحقق داخل iframe، فتبقى كل خطوة متاحة بينما تبقى الصفحة خلف النافذة مقفلة.يستخدم SDK الوحدة `dvh` في المتصفحات التي تدعم وحدات منفذ العرض الديناميكية، ويعود إلى `vh` في المتصفحات المدعومة الأقدم. عند عرض 540px وأقل، تملأ النافذة المنبثقة منطقة العرض المرئية. يبقى زر الإغلاق وتأكيد الخروج داخل النافذة المنبثقة.### تخطيط جديد لتدفق التحقق> [!NOTE]
>
> ينطبق كل ما في هذا القسم ابتداءً من الإصدار **0.5.0**، وهو غير منشور بعد. إلى أن تقوم بالترقية، تحتفظ النافذة المنبثقة بالحجم الموضّح أعلاه.ابتداءً من الإصدار 0.5.0، تضبط النافذة المنبثقة حجمها بنفسها حول تدفق التحقق المُعاد تصميمه بمجرد أن تُبلغ الصفحة عن تخطيطها عبر [رسالة `didit:layout`](https://docs.didit.me/ar/integration/web-sdks/incontext-iframe#تحديد-حجم-iframe-من-diditlayout):| عرض النافذة | النافذة المنبثقة (ابتداءً من الإصدار 0.5.0) |
| - | - |
| 1024px فأكثر | 960px × 660px في كل خطوة، بحد أقصى 90% من عرض النافذة وارتفاعها |
| من 541px إلى 1023px | عرض 500px وارتفاع يساوي محتوى الصفحة، بحد أقصى 90% من ارتفاع النافذة |
| 540px وأقل | ملء الشاشة |- **حجم البداية، ابتداءً من الإصدار 0.5.0:** إلى أن تُبلغ الصفحة عن تخطيطها، وبالنسبة للصفحات التي لا تفعل ذلك أبدًا، تحتفظ النافذة المنبثقة بالحد الأقصى الحالي 500px × 700px. وما زالت تتناسب مع النوافذ القصيرة، وتبقى بملء الشاشة عند 540px وأقل.
- **زر الإغلاق، ابتداءً من الإصدار 0.5.0:** دائرة قطرها 44px فوق الشريط العلوي للصفحة. تتبع السمة الفاتحة أو الداكنة للصفحة، وتنتقل إلى اليسار في اللغات التي تُكتب من اليمين إلى اليسار.
- **الوضع المضمّن، ابتداءً من الإصدار 0.5.0:** يستمر في ملء عنصره المضيف كما كان من قبل (انظر [الوضع المضمّن](#الوضع-المضمّن)).
- **عنوان التحقق، ابتداءً من الإصدار 0.5.0:** يضيف SDK المعامل `sdk_presentation` (`modal` أو `embedded`)، وفي النافذة المنبثقة المعامل `sdk_close_button` (`true` أو `false`، بحسب `showCloseButton`)، حتى تعرف الصفحة طريقة عرضها.
- **الأحداث، ابتداءً من الإصدار 0.5.0:** يتولى SDK معالجة `didit:layout` بنفسه ولا يمرّرها إلى `onEvent`.لا يوجد ما يتطلب ضبطًا، وتستمر كل الخيارات الحالية في العمل.***## الوضع المضمّنلا يستخدم الوضع المضمّن الحدّ 500px × 700px الخاص بالنافذة المنبثقة. يملأ SDK منطقة المحتوى للعنصر المضيف، لذا امنح هذا العنصر ارتفاعًا صريحًا أو ارتفاعًا محسوبًا بطريقة أخرى:```html theme={null}
<div id="verification-container" style="width: 500px; height: 700px;"></div>
``````typescript theme={null}
DiditSdk.shared.startVerification({
  url: 'https://verify.didit.me/u/...',
  configuration: {
    embedded: true,
    embeddedContainerId: 'verification-container'
  }
});
```إذا لم يكن للعنصر المضيف ارتفاع محسوب، فلن يكون لـ iframe المضمّن ارتفاع قابل للاستخدام أيضًا. أعد ضبط حجم العنصر المضيف عندما يتغيّر تخطيطك؛ يستمر SDK في ملئه تلقائيًا.***## نتائج التحققيُرجع SDK ثلاثة أنواع من النتائج:### مكتملانتهى تدفق التحقق (مقبولة أو قيد الانتظار أو مرفوضة).```typescript theme={null}
{
  type: 'completed',
  session: {
    sessionId: 'session-uuid',
    status: 'Approved' | 'Pending' | 'Declined'
  }
}
```> [!NOTE]
>
> يحدد نوع TypeScript القيم `'Approved' | 'Pending' | 'Declined'`، لكن القيمة تُمرَّر كما هي من حالة الجلسة في التدفق المستضاف، وقد تتلقى حالات أخرى مثل `In Review` أيضًا. تمثل `Pending` القيمة البديلة التي يستخدمها SDK عندما لا يُبلّغ التدفق عن أي حالة. تعامل مع `status` على أنه مؤشر فقط، واعتمد على [webhook](https://docs.didit.me/ar/integration/webhooks.md) للحصول على القرار المعتمد.### ملغىأغلق المستخدم نافذة التحقق. تُدرج `session` عندما يكون `sessionId` معروفًا بالفعل (وقد تكون `undefined` إذا ألغى المستخدم العملية قبل أن يُبلّغ iframe عنه).```typescript theme={null}
{
  type: 'cancelled',
  session: {
    sessionId: 'session-uuid',
    status: 'Pending'
  }
}
```### فشلحدث خطأ أثناء التحقق.```typescript theme={null}
{
  type: 'failed',
  error: {
    type: 'sessionExpired' | 'networkError' | 'cameraAccessDenied' | 'unknown',
    message: 'Your verification session has expired.'
  }
}
```***## إدارة الحالةيمكنك مراقبة حالة SDK لبناء واجهة مستخدم مخصصة:```typescript theme={null}
DiditSdk.shared.onStateChange = (state, error) => {
  switch (state) {
    case 'idle':
      // Ready to start
      break;
    case 'loading':
      // Loading verification iframe
      showLoadingSpinner();
      break;
    case 'ready':
      // Verification in progress
      hideLoadingSpinner();
      break;
    case 'error':
      // Error occurred
      showError(error);
      break;
  }
};

// Check current state
console.log(DiditSdk.shared.state);

// Check if verification is presented
console.log(DiditSdk.shared.isPresented);
```***## مرجع API### DiditSdk.sharedمثيل SDK المفرد.### الطرق| الطريقة | الوصف |
| - | - |
| `startVerification(options)` | بدء تدفق التحقق |
| `submitEvent(options)` | إضافة حدث للمستخدم النهائي إلى قائمة انتظار مراقبة الأحداث باستخدام token للمراقبة |
| `close()` | إغلاق نافذة التحقق برمجيًا |
| `destroy()` | إتلاف مثيل SDK وتنظيف الموارد |### الخصائص| الخاصية | النوع | الوصف |
| - | - | - |
| `state` | `DiditSdkState` | الحالة الحالية لـ SDK |
| `configuration` | `DiditSdkConfiguration \| undefined` | الإعدادات النشطة (تكون معيّنة أثناء إجراء عملية التحقق) |
| `isPresented` | `boolean` | ما إذا كانت نافذة التحقق مفتوحة |
| `errorMessage` | `string \| undefined` | رسالة الخطأ (تُضبط عندما تكون الحالة `error`)؛ تبقى الحالة `error` بعد فشل البدء حتى تبدأ التحقق من جديد |### الاستدعاءات| دالة الاستدعاء | المعاملات | الوصف |
| - | - | - |
| `onComplete` | `(result: VerificationResult)` | يُستدعى عند انتهاء التحقق |
| `onStateChange` | `(state: DiditSdkState, error?: string)` | يُستدعى عند تغيّر الحالة |
| `onEvent` | `(event: VerificationEvent)` | يُستدعى عند أحداث التحقق التفصيلية |***## الأحداث التفصيليةتتبع تقدم التحقق باستخدام الدالة `onEvent`:```typescript theme={null}
DiditSdk.shared.onEvent = (event) => {
  console.log('Event:', event.type, event.data);
};
```### مرجع الأحداث| الحدث | الوصف | بيانات payload |
| - | - | - |
| `didit:ready` | الصفحة جاهزة ومعرّف الجلسة متاح | `{ sessionId }` |
| `didit:started` | بدأ المستخدم التحقق | `{ sessionId? }` |
| `didit:step_started` | بدأت خطوة تحقق | `{ step, sessionId? }` |
| `didit:step_completed` | انتهت الخطوة بنجاح | `{ step, nextStep?, sessionId? }` |
| `didit:step_changed` | تغيرت الخطوة الحالية | `{ step, previousStep?, sessionId? }` |
| `didit:media_started` | بدأ التقاط الوسائط عبر الكاميرا | `{ step, mediaType }` |
| `didit:media_captured` | تم التقاط صورة أو فيديو | `{ step, isAuto }` |
| `didit:document_selected` | اختار المستخدم نوع المستند والدولة | `{ documentType, country }` |
| `didit:verification_submitted` | أُرسلت البيانات للمعالجة | `{ step, sessionId? }` |
| `didit:code_sent` | أُرسل رمز OTP | `{ step, channel?, codeSize?, sessionId? }` |
| `didit:code_verified` | تم التحقق من رمز OTP | `{ step, sessionId? }` |
| `didit:status_updated` | تغيرت حالة الجلسة | `{ status, previousStep?, sessionId? }` |
| `didit:completed` | اكتمل مسار التحقق | `{ sessionId?, status?, country?, documentType? }` |
| `didit:cancelled` | ألغى المستخدم التحقق | `{ sessionId? }` |
| `didit:error` | حدث خطأ | `{ error: string, step?, sessionId? }` |
| `didit:close_request` | طلب المستخدم إغلاق النافذة المنبثقة | (لا توجد بيانات) |### انقطاع الاتصالإذا انقطع اتصال المستخدم بالإنترنت، تغطي صفحة التحقق المسار بشاشة "لا يوجد اتصال بالإنترنت" بدلاً من ترك الخطوة في حالة التحميل.
تواصل الصفحة التحقق من الاتصال في الخلفية، وتغلق الشاشة تلقائياً بمجرد أن يصبح Didit متاحاً مرة أخرى، ويتابع المستخدم من الخطوة التي كان فيها.
داخل النافذة المنبثقة الخاصة بالـ SDK أو داخل iframe، تعرض الشاشة أيضاً الزر **إنهاء التحقق**: عندها ترسل الصفحة `didit:error` مع `error: "network_error"`، ثم `didit:cancelled`، ويغلق الـ SDK النافذة المنبثقة ويستدعي `onComplete` مع `type: "cancelled"`.ابتداءً من الإصدار 0.5.0، تحدد رسالة `didit:layout` الخاصة بالصفحة حجم النافذة المنبثقة ولا تصل إلى `onEvent`. إذا كنت تُضمّن الصفحة باستخدام iframe خاص بك بدلاً من ذلك، فراجع [تغيير حجم الـ iframe من `didit:layout`](https://docs.didit.me/ar/integration/web-sdks/incontext-iframe#تحديد-حجم-iframe-من-diditlayout).### قيم الخطوةيمكن أن يكون الحقل `step` أحد القيم التالية:- `document_selection` - اختيار نوع المستند
- `document_front` - الوجه الأمامي للمستند
- `document_back` - الوجه الخلفي للمستند
- `face` - التحقق من الوجه وكشف الحيوية
- `email` - التحقق من البريد الإلكتروني
- `phone` - التحقق من رقم الهاتف
- `poa` - إثبات العنوان
- `questionnaire` - خطوة الاستبيان### قيم القناةيمكن أن يكون الحقل `channel` في `code_sent` أحد القيم التالية:- `email` - رمز مرسل عبر البريد الإلكتروني
- `sms` - رمز مرسل عبر الرسائل النصية SMS
- `whatsapp` - رمز مرسل عبر WhatsApp### حجم الرمزيشير الحقل `codeSize` في `code_sent` إلى طول رمز OTP، مثلاً 4 أو 6 أرقام.***## أنواع TypeScript```typescript theme={null}
// Configuration types
interface DiditSdkConfiguration {
  /**
   * Enable SDK logging for debugging
   * @default false
   */
  loggingEnabled?: boolean;

  /**
   * Custom container element to mount the modal
   * @default document.body
   */
  containerElement?: HTMLElement;

  /**
   * Z-index for the modal overlay
   * @default 9999
   */
  zIndex?: number;

  /**
   * Show close button on modal
   * @default true
   */
  showCloseButton?: boolean;

  /**
   * Show exit confirmation dialog when closing
   * @default true
   */
  showExitConfirmation?: boolean;

  /**
   * Automatically close modal when verification completes
   * @default false
   */
  closeModalOnComplete?: boolean;

  /**
   * Render verification inline instead of modal overlay
   * @default false
   */
  embedded?: boolean;

  /**
   * Container element ID for embedded mode
   * Required when embedded is true
   */
  embeddedContainerId?: string;

  /**
   * Camera the document capture opens first.
   * @default 'back'
   */
  defaultDocumentCamera?: CameraLens;

  /**
   * Camera the face (liveness) capture opens first.
   * Applies to passive liveness; devices without a rear camera keep the front one.
   * @default 'front'
   */
  defaultLivenessCamera?: CameraLens;

  /**
   * Show the in-capture camera switcher on the document step.
   * false locks the user to defaultDocumentCamera.
   * @default true
   */
  showDocumentCameraSwitchButton?: boolean;

  /**
   * Show the in-capture camera switcher on the liveness step.
   * false locks the user to defaultLivenessCamera.
   * @default true
   */
  showLivenessCameraSwitchButton?: boolean;
}

type CameraLens = 'front' | 'back';

// Session + error types
type VerificationStatus = 'Approved' | 'Pending' | 'Declined';

interface SessionData {
  sessionId: string;
  status: VerificationStatus;
}

type VerificationErrorType =
  | 'sessionExpired'
  | 'networkError'
  | 'cameraAccessDenied'
  | 'unknown';

interface VerificationError {
  type: VerificationErrorType;
  message: string;
}

// Verification result — `session` and `error` are both optional fields
// on every result; which one is populated depends on `type`.
type VerificationResultType = 'completed' | 'cancelled' | 'failed';

interface VerificationResult {
  type: VerificationResultType;
  session?: SessionData;
  error?: VerificationError;
}

// State types
type DiditSdkState = 'idle' | 'loading' | 'ready' | 'error';

// Event types
type VerificationEventType =
  | 'didit:ready'
  | 'didit:started'
  | 'didit:step_started'
  | 'didit:step_completed'
  | 'didit:step_changed'
  | 'didit:media_started'
  | 'didit:media_captured'
  | 'didit:document_selected'
  | 'didit:verification_submitted'
  | 'didit:code_sent'
  | 'didit:code_verified'
  | 'didit:status_updated'
  | 'didit:completed'
  | 'didit:cancelled'
  | 'didit:error'
  | 'didit:close_request';

interface VerificationEventData {
  sessionId?: string;
  status?: string;
  step?: string;
  nextStep?: string;
  previousStep?: string;
  error?: string;
  country?: string;
  documentType?: string;
  isAuto?: boolean;
  mediaType?: string;
  channel?: string;
  codeSize?: number;
  [key: string]: unknown;
}

interface VerificationEvent {
  type: VerificationEventType;
  data?: VerificationEventData;
  timestamp?: number;
}

// Start verification options
interface StartVerificationOptions {
  url: string;
  configuration?: DiditSdkConfiguration;
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.