> ## 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.

# التحقق من الهوية عبر الإطار المضمّن: KYC مضمّن على الويب

> ضمّن KYC وKYB وAML والكشف عن الحيوية في موقعك عبر iframe. UniLink بدون كود أو جلسات API. من $0.33 لكل فحص KYC كامل، و10 مجاناً شهرياً، بدون عقود.



موجّه تكامل iframe
        نسخ الموجّه إلى الحافظة



      
      

\<pre>

\`Embed Didit identity verification into my web page using an iframe.

\## Two Options

\### Option A: UniLink (no backend — fastest setup)
Copy your UniLink URL from Didit Console > Workflows > Copy Link.
It looks like: https://verify.didit.me/u/<BASE64_WORKFLOW_ID>
Embed it directly:

\<iframe
src="https://verify.didit.me/u/YOUR_WORKFLOW_ID_BASE64"
style="width: 100%; height: 700px; border: none; border-radius: 12px;"
allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
/>

No backend needed. Results appear in your Didit Console dashboard.

\### Option B: API session (full control)
1\. Backend creates session: POST /v3/session/ → response includes "url"
2\. Frontend embeds that "url" as the iframe src
3\. Listen for postMessage events from the iframe (event.origin === 'https://verify.didit.me', or your white-label domain)
4\. Backend receives the full, signed decision via webhook (status.updated)

\## postMessage contract (key events — full table below)
Every message is an object: { type: "didit:<event>", data: { ... }, timestamp: <ms epoch> }
Completion event: type === "didit:completed", data: { sessionId, status }
Other events: didit:ready { sessionId }, didit:started, didit:step_started { step },
didit:step_completed { step, nextStep }, didit:step_changed { step, previousStep },
didit:status_updated { status }, didit:error { error, step }, didit:cancelled, didit:close_request,
didit:layout { contentHeight, colorScheme: "light" | "dark", dir: "ltr" | "rtl" }
The payload is NESTED under event.data.data (event.data is the envelope).
For your own iframe, add sdk_presentation=embedded with the URL API to receive didit:layout.

\## Iframe size (redesigned flow)
\- Window 1024px and wider: 960px by 660px (at most 90% of the window)
\- Window 541px to 1023px: 500px wide, height = didit:layout contentHeight (700px until the first message, at most 90% of the window height)
\- Window 540px and below: full screen

\## Frontend Code (Option B — React)
function VerificationIframe({ verificationUrl }) {
useEffect(() => {
function handleMessage(event) {
  if (event.origin !== 'https://verify.didit.me') return; // use your white-label domain if configured
  const { type, data } = event.data || {};
  if (type === 'didit:completed') {
    // data.sessionId, data.status: "Approved" | "Declined" | "In Review" // open string — other session statuses possible in edge flows
    // Trust the webhook on your backend for the canonical decision.
  }
}
window.addEventListener('message', handleMessage);
return () => window.removeEventListener('message', handleMessage);
}, []);

return (
\<iframe
  src={verificationUrl}
  style={{ width: '100%', height: '700px', border: 'none', borderRadius: '12px' }}
  allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
/>
);
}

\## Required client-side permissions
If you front your site with a reverse proxy (nginx, Cloudflare, etc.) make sure it does not
strip the Permissions-Policy / Feature-Policy headers — camera and microphone access must be
allowed for your origin or the iframe will be unable to start the camera.

\## Required iframe Permissions
allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
camera: document and face capture. microphone: optional audio during video capture.
geolocation: the location step. clipboard-write: the copy buttons.
digital-credentials-get: sharing a digital ID from a wallet such as Google Wallet.

\## 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, "vendor_data": userId }
201 response fields (all 10, per OpenAPI):
\{ "session_id", "session_number", "session_token", "url", "vendor_data", "metadata",
"status", "workflow_id", "workflow_version", "callback" }
Use response.url as the iframe src — never build the URL from session_token by hand.

\## Rate Limits
600 session-create requests per minute per API key (falls back to bearer token, then client IP), plus a shared 300 write-requests/minute budget across all endpoints. HTTP 429 with Retry-After when exceeded.

\## Environment Variables
\- DIDIT_API_KEY (backend only)
\- DIDIT_WORKFLOW_ID (backend only)

\## Docs
\- Iframe guide: https://docs.didit.me/integration/web-sdks/incontext-iframe
\- Create Session: https://docs.didit.me/sessions-api/create-session
\- Webhooks: https://docs.didit.me/integration/webhooks`

\</pre>



      
      

الصق في

ضمّن مسار التحقق من Didit مباشرةً داخل تطبيقك باستخدام iframe. يوفّر ذلك تجربة سلسة دون إعادة توجيه المستخدمين بعيداً عن موقعك.## نظرة عامة| الميزة | UniLink (بدون خادم خلفي) | جلسة API (مع خادم خلفي) |
| - | - | - |
| وقت الإعداد | أقل من دقيقة | 5-10 دقائق |
| يتطلب خادماً خلفياً | ❌ لا | ✅ نعم |
| `vendor_data` مخصصة | ❌ لا | ✅ نعم |
| `metadata` مخصصة | ❌ لا | ✅ نعم |
| رابط الاستدعاء لكل جلسة | ❌ لا | ✅ نعم |
| تتبّع الجلسات | ❌ لا | ✅ نعم |***## iframe من UniLink (بدون خادم خلفي)أسرع طريقة للبدء: ما عليك سوى نسخ رابط UniLink الخاص بك ولصقه.### ما تحتاجه1) سير عمل في Didit (يُنشأ في [Didit Console](https://business.didit.me))
2) رابط UniLink الخاص بك (انقر **Copy Link** في سير العمل الخاص بك)### التنفيذ```html theme={null}
<iframe 
  src="https://verify.didit.me/u/YOUR_WORKFLOW_ID_BASE64"
  style="width: 100%; height: 700px; border: none;" 
  allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
></iframe>
```> ⚠️ **مطلوب**: سمة `allow` إلزامية للوصول إلى الكاميرا أثناء كشف الحيوية.### أبرز المزايا- **إعداد في أقل من دقيقة**: بدون خادم خلفي ولا مفاتيح API
- **دون أي إعدادات**: يُضبط رابط الاستدعاء في إعدادات سير العمل
- **مثالي للنماذج الأولية (MVP)**: ابدأ فوراً***## جلسة iframe عبر API (مع خادم خلفي)للتكاملات المتقدمة التي تحتاج إلى تخصيص لكل جلسة.### متى تستخدمها- مرّر `vendor_data` أو `metadata` مخصصة لكل جلسة
- اضبط روابط استدعاء مختلفة لكل جلسة
- تتبّع الجلسات على الخادم قبل بدء التحقق
- اربط الجلسات بمعرّفات المستخدمين لديك### التنفيذ**الخطوة 1: أنشئ جلسة (من الخادم الخلفي)**تستخدم استجابة إنشاء الجلسة حقلاً اسمه **`url`**، استخدمه كقيمة `src` للـ iframe.```javascript theme={null}
// Node.js / Express
app.post('/api/create-verification', async (req, res) => {
  const { userId } = req.body;

  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: userId,
      callback: 'https://yourapp.com/verification-callback',
      metadata: { source: 'web-app', timestamp: Date.now() },
    }),
  });

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

  // 201 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({ sessionId: session.session_id, verificationUrl: session.url });
});
```**الخطوة 2: ضمّن الجلسة في iframe (الواجهة الأمامية)**```html theme={null}
<iframe 
  id="didit-verification"
  src="" <!-- Set dynamically from API response -->
  style="width: 100%; height: 650px; border: none;" 
  allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
></iframe>

<script>
  async function startVerification() {
    const response = await fetch('/api/create-verification', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ userId: 'user-123' })
    });
    
    const { verificationUrl } = await response.json();
    document.getElementById('didit-verification').src = verificationUrl;
  }
</script>
```***## الاستماع للأحداث (postMessage)ترسل صفحة التحقق الأحداث إلى النافذة الأم. تحتوي كل رسالة على هذا الغلاف:```typescript theme={null}
{
  type: 'didit:<event>',   // e.g. 'didit:completed'
  data: { /* payload */ }, // event-specific; may be undefined
  timestamp: 1718000000000 // ms epoch
}
```الحمولة **متداخلة**: اقرأ `event.data.data.sessionId` وليس `event.data.sessionId`:```javascript theme={null}
window.addEventListener('message', (event) => {
  // Use your white-label domain here if you have one configured
  if (event.origin !== 'https://verify.didit.me') return;

  const { type, data } = event.data || {};

  if (type === 'didit:ready') {
    console.log('Session ID:', data.sessionId); // available as soon as the page loads
  }
  if (type === 'didit:completed') {
    console.log('Done:', data.sessionId, data.status); // e.g. "Approved" | "Declined" | "In Review"
    // UI hint only — the canonical decision arrives on your backend via webhook
  }
});
```أهم الأحداث: `didit:ready` (`{ sessionId }`)، `didit:started`، `didit:step_started` / `didit:step_completed` / `didit:step_changed` (`{ step, ... }`)، `didit:status_updated` (`{ status }`)، `didit:completed` (`{ sessionId, status }`)، `didit:cancelled`، `didit:error` (`{ error, step? }`)، `didit:close_request`، و`didit:layout` (`{ contentHeight, colorScheme, dir }`، انظر [أدناه](#تحديد-حجم-iframe-من-diditlayout)). تسرد [مرجع أحداث SDK لـ JavaScript](https://docs.didit.me/ar/integration/web-sdks/javascript-sdk.md#مرجع-الأحداث) أحداث التحقق المتاحة كدوال رد نداء محددة النوع. ابتداءً من الإصدار 0.5.0، يتولى SDK رسائل التخطيط داخلياً ولا يمررها إلى `onEvent`.### تحديد حجم iframe من `didit:layout`تُخبرك صفحة التحقق بالمساحة التي تحتاجها عبر رسالة `didit:layout`. ترسل رسالة عند التحميل وأخرى كلما تغيّر ارتفاع المحتوى أو السمة أو اتجاه النص:```typescript theme={null}
{
  type: 'didit:layout',
  data: {
    contentHeight: 612,    // CSS px
    colorScheme: 'light',  // 'light' | 'dark'
    dir: 'ltr'             // 'ltr' | 'rtl'
  },
  timestamp: 1718000000000
}
```| الحقل | النوع | الوصف |
| - | - | - |
| `contentHeight` | `number` | الارتفاع الطبيعي لمحتوى الصفحة ببكسل CSS، بما في ذلك الشريط العلوي |
| `colorScheme` | `'light' \| 'dark'` | السمة التي تُعرض بها الصفحة. مع ألوان العلامة البيضاء، يحدد لون خلفيتك السمة وليس إعداد الجهاز |
| `dir` | `'ltr' \| 'rtl'` | اتجاه النص للغة الصفحة |> [!NOTE]
>
> لاستقبال `didit:layout` في iframe الخاص بك، أضف `sdk_presentation=embedded` إلى رابط التحقق الخاص به. ابتداءً من الإصدار 0.5.0، يضبط [SDK لـ JavaScript](https://docs.didit.me/ar/integration/web-sdks/javascript-sdk.md) هذا العرض تلقائياً. بدون معامل العرض، تستخدم الصفحة تخطيطها المستقل ولا ترسل رسائل التخطيط.يتبع هذا المضيف [الأحجام الموصى بها](#حجم-الإطار): بطاقة ثابتة من عرض 1024 بكسل، وملء الشاشة عند 540 بكسل وأقل، وبينهما iframe بعرض 500 بكسل يأخذ الارتفاع الذي تُبلغ عنه الصفحة:```html theme={null}
<iframe
  id="didit-verification"
  class="didit-iframe"
  title="Didit verification"
  allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
></iframe>

<style>
  /* 541px to 1023px wide: 500px wide and as tall as the content */
  .didit-iframe {
    display: block;
    width: 500px;
    max-width: 100%;
    height: var(--didit-content-height, 700px); /* 700px until the first didit:layout */
    max-height: 90vh;
    max-height: 90dvh;
    margin: 0 auto;
    border: none;
    border-radius: 16px;
  }

  /* 1024px and wider: the computer card */
  @media (min-width: 1024px) {
    .didit-iframe {
      width: 960px;
      max-width: 90vw;
      height: 660px;
    }
  }

  /* 540px and below: full screen */
  @media (max-width: 540px) {
    .didit-iframe {
      position: fixed;
      inset: 0;
      width: 100%;
      height: 100vh;
      height: 100dvh;
      max-height: none;
      border-radius: 0;
    }
  }
</style>

<script>
  const DIDIT_ORIGIN = 'https://verify.didit.me'; // or your white-label domain
  const iframe = document.getElementById('didit-verification');

  // verificationUrl: the session `url` from your backend, or your UniLink
  const src = new URL(verificationUrl);
  src.searchParams.set('sdk_presentation', 'embedded');
  window.addEventListener('message', (event) => {
    if (event.origin !== DIDIT_ORIGIN || event.source !== iframe.contentWindow) return;
    const { type, data } = event.data || {};
    if (type !== 'didit:layout') return;
    const height = data?.contentHeight;
    if (typeof height !== 'number' || !Number.isFinite(height) || height <= 0) return;

    // Only the 541px to 1023px size reads it; the other two sizes are fixed
    iframe.style.setProperty('--didit-content-height', `${height}px`);
  });
  iframe.src = src.toString();
</script>
```بين 541 و1023 بكسل، يستخدم هذا المثال ارتفاع بداية قدره 700 بكسل إلى أن تصل رسالة التخطيط، مع حد أقصى 90% من ارتفاع النافذة المرئية. تُطبّق أحجام الحاسوب والهاتف فوراً. على الهواتف يغطي iframe النافذة، لذا وفّر طريقة للخروج من التحقق داخل المضيف. استخدم `colorScheme` و`dir` لمطابقة أي عناصر تحكم ترسمها حول iframe مع سمة الصفحة واتجاه نصها.إذا انقطع اتصال المستخدم، تعرض الصفحة شاشة "لا يوجد اتصال بالإنترنت" تُغلق نفسها تلقائياً عند عودة الاتصال. إذا اختار المستخدم **Exit Verification** هناك، ترسل الصفحة `didit:error` مع `error: "network_error"`، ثم `didit:cancelled`: أغلق iframe عند `didit:cancelled`.***## تنفيذ النافذة المنبثقةلتجربة نافذة منبثقة متقنة تُعرض فوق صفحتك:### HTML/CSS/JS```html theme={null}
<!DOCTYPE html>
<html>
<head>
  <style>
    .didit-modal-overlay {
      display: none;
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, 0.6);
      z-index: 9999;
      backdrop-filter: blur(4px);
    }
    
    .didit-modal-container {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 90%;
      max-width: 480px;
      height: 85vh;
      max-height: 750px;
      background: white;
      border-radius: 16px;
      overflow: hidden;
      box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
    }
    
    .didit-modal-close {
      position: absolute;
      top: 12px;
      right: 12px;
      z-index: 10;
      width: 32px;
      height: 32px;
      border: none;
      background: rgba(0, 0, 0, 0.1);
      border-radius: 50%;
      cursor: pointer;
      font-size: 18px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .didit-modal-close:hover {
      background: rgba(0, 0, 0, 0.2);
    }
    
    .didit-iframe {
      width: 100%;
      height: 100%;
      border: none;
    }
  </style>
</head>
<body>
  <button onclick="openVerification()">Verify Identity</button>

  <div id="didit-modal" class="didit-modal-overlay">
    <div class="didit-modal-container">
      <button class="didit-modal-close" onclick="closeVerification()">✕</button>
      <iframe 
        id="didit-iframe"
        class="didit-iframe"
        allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
      ></iframe>
    </div>
  </div>

  <script>
    const UNILINK_URL = 'https://verify.didit.me/u/YOUR_WORKFLOW_ID_BASE64';
    
    function openVerification() {
      document.getElementById('didit-iframe').src = UNILINK_URL;
      document.getElementById('didit-modal').style.display = 'block';
      document.body.style.overflow = 'hidden';
    }
    
    function closeVerification() {
      document.getElementById('didit-iframe').src = '';
      document.getElementById('didit-modal').style.display = 'none';
      document.body.style.overflow = '';
    }
    
    // Close on escape key
    document.addEventListener('keydown', (e) => {
      if (e.key === 'Escape') closeVerification();
    });
    
    // Close on overlay click
    document.getElementById('didit-modal').addEventListener('click', (e) => {
      if (e.target.id === 'didit-modal') closeVerification();
    });
  </script>
</body>
</html>
```***## مكوّن Reactمكوّن React قابل لإعادة الاستخدام للتحقق عبر نافذة منبثقة:```tsx theme={null}
import { useState, useEffect } from 'react';

interface DiditInContextProps {
  /**
   * Either the `url` returned by POST /v3/session/ (API session)
   * or your UniLink URL copied from the Console (Workflows → Copy Link).
   * Don't derive the UniLink yourself — the path segment is a 22-character
   * base64url encoding of the workflow UUID's raw bytes, not btoa(workflowId).
   */
  verificationUrl: string;
  isOpen: boolean;
  onClose: () => void;
  onComplete?: (sessionId: string, status: string) => void;
}

export function DiditInContext({ 
  verificationUrl, 
  isOpen, 
  onClose,
  onComplete 
}: DiditInContextProps) {
  const [iframeSrc, setIframeSrc] = useState<string>('');

  useEffect(() => {
    if (isOpen) {
      setIframeSrc(verificationUrl);
      document.body.style.overflow = 'hidden';
    } else {
      setIframeSrc('');
      document.body.style.overflow = '';
    }
  }, [isOpen, verificationUrl]);

  // Listen for postMessage from iframe
  // Messages look like: { type: 'didit:<event>', data: {...}, timestamp }
  useEffect(() => {
    const handleMessage = (event: MessageEvent) => {
      // Use your white-label domain here if you have one configured
      if (event.origin !== 'https://verify.didit.me') return;

      if (event.data?.type === 'didit:completed' && onComplete) {
        onComplete(event.data.data?.sessionId, event.data.data?.status);
        onClose();
      }
    };

    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, [onComplete, onClose]);

  // Handle escape key
  useEffect(() => {
    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === 'Escape' && isOpen) onClose();
    };
    
    document.addEventListener('keydown', handleEscape);
    return () => document.removeEventListener('keydown', handleEscape);
  }, [isOpen, onClose]);

  if (!isOpen) return null;

  return (
    <div 
      className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center"
      onClick={(e) => e.target === e.currentTarget && onClose()}
    >
      <div className="relative w-[90%] max-w-[480px] h-[85vh] max-h-[750px] bg-white rounded-2xl overflow-hidden shadow-2xl">
        <button 
          onClick={onClose}
          className="absolute top-3 right-3 z-10 w-8 h-8 rounded-full bg-black/10 hover:bg-black/20 flex items-center justify-center"
          aria-label="Close"
        >
          ✕
        </button>
        <iframe 
          src={iframeSrc}
          className="w-full h-full border-0"
          allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
          title="Didit Verification"
        />
      </div>
    </div>
  );
}
```### الاستخدام```tsx theme={null}
import { useState } from 'react';
import { DiditInContext } from './DiditInContext';

function App() {
  const [isVerificationOpen, setIsVerificationOpen] = useState(false);
  
  return (
    <>
      <button onClick={() => setIsVerificationOpen(true)}>
        Verify Identity
      </button>
      
      <DiditInContext
        verificationUrl="https://verify.didit.me/u/YOUR_WORKFLOW_ID_BASE64" // UniLink from Console, or the API session `url`
        isOpen={isVerificationOpen}
        onClose={() => setIsVerificationOpen(false)}
        onComplete={(sessionId, status) => {
          console.log(`Verification ${status}: ${sessionId}`);
          if (status === 'Approved') {
            // Navigate to success page
          }
        }}
      />
    </>
  );
}
```***## مكوّن Vue```vue theme={null}
<template>
  <Teleport to="body">
    <div 
      v-if="isOpen"
      class="fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center"
      @click.self="$emit('close')"
    >
      <div class="relative w-[90%] max-w-[480px] h-[85vh] max-h-[750px] bg-white rounded-2xl overflow-hidden shadow-2xl">
        <button 
          @click="$emit('close')"
          class="absolute top-3 right-3 z-10 w-8 h-8 rounded-full bg-black/10 hover:bg-black/20 flex items-center justify-center"
        >
          ✕
        </button>
        <iframe 
          :src="iframeSrc"
          class="w-full h-full border-0"
          allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
        />
      </div>
    </div>
  </Teleport>
</template>

<script setup lang="ts">
import { computed, watch, onMounted, onUnmounted } from 'vue';

const props = defineProps<{
  isOpen: boolean;
  // The `url` from POST /v3/session/, or your UniLink URL copied from the
  // Console (Workflows → Copy Link). Don't derive the UniLink with btoa() —
  // its path segment is base64url of the workflow UUID's raw bytes.
  verificationUrl: string;
}>();

const emit = defineEmits<{
  close: [];
  complete: [sessionId: string, status: string];
}>();

const iframeSrc = computed(() => (props.isOpen ? props.verificationUrl : ''));

// Handle escape key
const handleEscape = (e: KeyboardEvent) => {
  if (e.key === 'Escape' && props.isOpen) emit('close');
};

// Handle postMessage — messages look like { type: 'didit:<event>', data: {...}, timestamp }
const handleMessage = (event: MessageEvent) => {
  // Use your white-label domain here if you have one configured
  if (event.origin !== 'https://verify.didit.me') return;
  if (event.data?.type === 'didit:completed') {
    emit('complete', event.data.data?.sessionId, event.data.data?.status);
  }
};

onMounted(() => {
  document.addEventListener('keydown', handleEscape);
  window.addEventListener('message', handleMessage);
});

onUnmounted(() => {
  document.removeEventListener('keydown', handleEscape);
  window.removeEventListener('message', handleMessage);
});

// Lock body scroll when open
watch(() => props.isOpen, (isOpen) => {
  document.body.style.overflow = isOpen ? 'hidden' : '';
});
</script>
```***## الإعدادات### الأذونات المطلوبةاستخدم قائمة الأذونات الكاملة هذه للالتقاط والموقع والنسخ وتوافق الوسائط:```html theme={null}
allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
```| الإذن | الاستخدام وما يحدث بدونه |
| - | - |
| `camera` | مسح المستندات والتقاط الوجه. بدونه لا يمكن تشغيل الكاميرا، ويرى المستخدم إرشادات الوصول إلى الكاميرا |
| `microphone` | صوت اختياري أثناء تسجيل فيديو المستند والوجه. بدونه يستمر الالتقاط بدون صوت |
| `geolocation` | تقرأ خطوة الموقع موضع الجهاز. بدونه يرى المستخدم **الوصول إلى الموقع متوقف**، حتى لو سمح بالموقع في المتصفح |
| `clipboard-write` | نسخ مرجع الجلسة أو رابط التحقق، بما في ذلك على شاشة المتصفح داخل التطبيق. بدونه قد يفشل إجراء النسخ، ويجب على المستخدم نسخ النص الظاهر أو عنوان المتصفح يدوياً |
| `fullscreen` | يتيح لعناصر التحكم في الوسائط طلب ملء الشاشة. بدونه تبقى هذه العناصر داخل الإطار |
| `autoplay` | يتيح تشغيل مقاطع الفيديو الإرشادية ومعاينات الكاميرا تلقائياً، وفق قواعد المتصفح. بدونه قد ينتظر التشغيل إجراءً من المستخدم |
| `encrypted-media` | يُحتفظ به لتوافق الوسائط المحمية. لا تتطلبه خطوات الالتقاط الحالية؛ بدونه سيُحظر تشغيل الوسائط المحمية |
| `digital-credentials-get` | مشاركة الهوية الرقمية من محفظة مثل Google Wallet عبر Digital Credentials API في المتصفح. بدونه يرفض المتصفح طلب المحفظة داخل إطارك، فلا يستطيع المستخدم مشاركة الهوية من المحفظة هناك |تفوّض سمة `allow` الأذونات، لكنها لا تتجاوز اختيار المستخدم، ولا ترويسة `Permissions-Policy` الأكثر صرامة في صفحتك المضيفة.### حجم الإطارتتكيّف عملية التحقق مع حجم إطارها. اضبط حجم الإطار وفق النافذة التي يظهر فيها:| عرض النافذة | حجم الإطار الموصى به |
| - | - |
| 1024px فأكثر (حاسوب) | 960px × 660px، بحد أقصى 90% من عرض النافذة وارتفاعها. حافظ على هذا الحجم في كل خطوة |
| من 541px إلى 1023px | عرض 500px وبارتفاع يساوي ارتفاع المحتوى: خذ الارتفاع من `contentHeight` في [رسالة `didit:layout`](#تحديد-حجم-iframe-من-diditlayout)، بحد أقصى 90% من ارتفاع النافذة |
| 540px وأقل (هاتف) | ملء الشاشة: كامل عرض النافذة وكامل ارتفاعها المرئي، بدون زوايا مستديرة |في النطاق المتوسط، ابدأ بحجم 500px × 700px إلى أن تصل أول رسالة `didit:layout`، مع الحد الأقصى للارتفاع نفسه. يطبّق [مثال `didit:layout`](#تحديد-حجم-iframe-من-diditlayout) الأحجام الثلاثة، بما فيها أحجام الحاسوب والهاتف قبل وصول أي رسالة.### سياسة أمان المحتوى (CSP)إذا كنت تستخدم CSP، فأضف Didit إلى توجيه `frame-src`:```
Content-Security-Policy: frame-src https://verify.didit.me;
```***## التحقق عبر الأجهزةيدعم إطار InContext التحقق عبر الأجهزة تلقائياً:1) يبدأ المستخدم التحقق من الحاسوب
2) إذا كانت الكاميرا غير متاحة، يُعرض رمز QR
3) يمسح المستخدم رمز QR بهاتفه
4) يكمل المستخدم التحقق على الهاتف
5) يتحدّث إطار الحاسوب تلقائياً بالنتيجةيحدث هذا تلقائياً، ولا يتطلب أي إعداد إضافي.***## استكشاف الأخطاء وإصلاحها### الكاميرا لا تعمل1) تأكد من أن الإطار يتضمن [قائمة الأذونات](#الأذونات-المطلوبة) كاملة
2) تحقق من أن موقعك يعمل عبر HTTPS
3) تأكد من أن المستخدم منح أذونات الكاميرا لنطاقك
4) جرّب طريقة [إعادة التوجيه](https://docs.didit.me/ar/integration/web-sdks/web-redirect.md) إذا فشل الوصول إلى الكاميرا داخل الإطار### الإطار لا يُحمَّل1) تحقق من مشكلات سياسة أمان المحتوى (CSP)
2) أضف `https://verify.didit.me` إلى توجيه `frame-src`
3) تحقق من أخطاء وحدة التحكم في المتصفح### لا تُستقبل رسالة postMessage1) تأكد من أنك تستمع إلى الأصل الصحيح (`https://verify.didit.me`، أو نطاقك ذي العلامة البيضاء)
2) تحقق من إضافة مستمع الحدث قبل فتح الإطار
3) تحقق من اسم الحدث وبنيته: الأنواع تبدأ ببادئة (`didit:completed`، وليس `verification_complete`)، وpayload متداخل ضمن `event.data.data`***## مستودع الأمثلة> [card] [مستودع GitHub](https://github.com/didit-protocol/iframe-example)
>
> اطلع على الكود المصدري والأمثلة على GitHub***


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