> ## 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 React Native : vérification mobile

> SDK KYC Didit pour React Native et Expo : iOS, Android et NFC. Dès $0.33 par vérification KYC complète, $10 offerts/mois, sans engagement.



Prompt d'intégration du SDK React Native
        Copier le prompt dans le presse-papiers



      
      

\<pre>

\`Integrate Didit identity verification into my React Native app using the native SDK.

\## Requirements
\- React Native 0.76+ (New Architecture / TurboModules)
\- Node.js 20+, TypeScript 5+
\- iOS 13.0+ (NFC requires iOS 15+)
\- Android API 24+ (Android 7.0), Kotlin 1.9+, Java 17+
\- New Architecture (TurboModules) only - package is published as @didit-protocol/sdk-react-native v4.x (latest 4.13.2)

\## Installation

\### Expo (recommended)
npx expo install @didit-protocol/sdk-react-native

Add to app.json (NFC is enabled by default):
\{
"expo": {
"plugins": ["@didit-protocol/sdk-react-native"]
}
}

To opt out of NFC dependencies:
\{
"expo": {
"plugins": [["@didit-protocol/sdk-react-native", { "iosNfcEnabled": false, "androidNfcEnabled": false }]]
}
}

The config plugin automatically adds the Didit Maven repo (Android), the DiditSDK podspec (iOS),
and BouncyCastle packaging rules for Android. This SDK requires a development build — it does not work in Expo Go.
The plugin does not edit Info.plist: add the iOS permission keys and, for NFC, the ISO7816 select identifiers
(including D392F000260100000001 for the Japan My Number Card) under expo.ios.infoPlist in app.json.

\### React Native CLI
npm install @didit-protocol/sdk-react-native

iOS — add this block to ios/Podfile inside the app target (NFC-aware; pins to iOS 15 when NFC is on):
didit_sdk_ios_nfc_enabled = ENV.fetch('DIDIT_SDK_IOS_NFC_ENABLED', 'true').downcase != 'false'
didit_sdk_ios_pod = didit_sdk_ios_nfc_enabled ? 'DiditSDK' : 'DiditSDK/Core'
pod didit_sdk_ios_pod, :podspec => 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.13.2/DiditSDK.podspec'
The tag in that URL must equal diditNativeSdkVersions.ios in the package (4.13.2); do not use 'main', because the package requires that exact version and every pod install fails when the URL resolves to a different one.
Then: cd ios && bundle exec pod install

Android — add to settings.gradle (dependencyResolutionManagement.repositories):
maven { url "https://raw.githubusercontent.com/didit-protocol/sdk-android/main/repository" }
To disable NFC, add diditSdkAndroidNfcEnabled=false to android/gradle.properties.

\## Backend: Create Session (your server)
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": "user-id" }
Response: { "session_id": "uuid", "session_token": "short-token", "url": "https://verify.didit.me/session/short-token", "status": "Not Started" }
Send session_token to the React Native app (never expose DIDIT_API_KEY to the device).

\## Integration
import { startVerification, VerificationStatus } from '@didit-protocol/sdk-react-native';

// Option A: With session token from your backend (recommended)
const result = await startVerification('session-token-from-backend');

// Option B: With workflow ID (SDK creates session internally)
const result = await startVerificationWithWorkflow('your-workflow-id', {
vendorData: 'user-123',
});

// Handle result
switch (result.type) {
case 'completed':
if (result.session.status === VerificationStatus.Approved) { /* grant access */ }
break;
case 'cancelled':
// User dismissed the verification flow
break;
case 'failed':
// SDK error — show result.error.message
break;
}

\## Result Statuses (VerificationStatus enum)
\- VerificationStatus.Approved — user identity verified, grant access
\- VerificationStatus.Declined — verification failed, show retry or contact support
\- VerificationStatus.Pending  — needs manual review by your compliance team

\## Full Verification Results
The SDK only returns the status. Full decision data (document fields, face match scores, AML hits, etc.) arrives via webhook to your backend.
Set up webhooks: https://docs.didit.me/integration/webhooks

\## Rate Limits (session creation)
\- 600 session-create requests / minute per x-api-key (see https://docs.didit.me/integration/rate-limiting)
\- On 429, retry honouring Retry-After / X-RateLimit-* headers

\## Environment Variables (backend only — never expose in the app)
\- DIDIT_API_KEY — from Didit Console > API & Webhooks
\- DIDIT_WORKFLOW_ID — from Didit Console > Workflows

\## Docs
\- React Native SDK: https://docs.didit.me/integration/native-sdks/react-native-sdk
\- GitHub: https://github.com/didit-protocol/sdk-react-native
\- npm: https://www.npmjs.com/package/@didit-protocol/sdk-react-native
\- Webhooks: https://docs.didit.me/integration/webhooks
\- API Reference: https://docs.didit.me/api-reference/overview`

\</pre>



      
      

Coller dans

Un SDK React Native multiplateforme qui encapsule les SDK natifs iOS et Android et fournit une API TypeScript unifiée pour la vérification d'identité.> [card] [Dépôt GitHub](https://github.com/didit-protocol/sdk-react-native)
>
> Consultez le code source et les exemples sur GitHub> [card] [Package npm](https://www.npmjs.com/package/@didit-protocol/sdk-react-native)
>
> @didit-protocol/sdk-react-native> [!NOTE]
>
> ### **SDK natif** : c'est l'approche recommandée pour les applications React Native et Expo. Le SDK encapsule les SDK natifs iOS et Android pour offrir la meilleure expérience utilisateur, une gestion optimisée de la caméra et une prise en charge complète du NFC.***## Prérequis| Prérequis | Version minimale |
| - | - |
| React Native | 0.76+ (New Architecture / TurboModules) |
| Node.js | 20+ |
| TypeScript | 5+ |### Prérequis de plateforme| Plateforme | Version minimale | Remarques |
| - | - | - |
| iOS | 13.0+ | La lecture des passeports par NFC nécessite iOS 15.0+ |
| Android | API 24+ (7.0) | Kotlin 1.9+, Java 17+ |> [!NOTE]
>
> **Le consentement biométrique nécessite la version native 4.10.0 ou ultérieure.** Pour les personnes couvertes par les lois de l'Illinois, du Texas ou du Colorado, Didit peut demander un [consentement biométrique](https://docs.didit.me/fr/getting-started/biometric-consent.md) explicite avant la première capture de visage. Une version du SDK React Native qui verrouille les SDK natifs iOS et Android sur la version 4.10.0 ou une version ultérieure affiche cette étape. Les versions antérieures ne peuvent pas l'afficher : leurs sessions se déroulent comme auparavant et la décision indique que le consentement n'a pas été recueilli (`biometric_consent.reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`). Mettez à niveau si vous vérifiez des personnes dans ces États.***## Installation### Expo (recommandé)```bash theme={null}
npx expo install @didit-protocol/sdk-react-native
```Ajoutez ensuite le plugin de configuration à votre `app.json` (ou `app.config.js`). Le NFC est activé par défaut :```json theme={null}
{
  "expo": {
    "plugins": ["@didit-protocol/sdk-react-native"]
  }
}
```Le plugin configure automatiquement les deux plateformes :- **Android :** ajoute le dépôt Maven de Didit à Gradle, définit la propriété Gradle `diditSdkAndroidNfcEnabled` et applique les règles de dépendances et de packaging pour BouncyCastle
- **iOS :** ajoute le podspec DiditSDK au Podfile (fixé à iOS 15 lorsque le NFC est activé)Le plugin ne modifie pas `Info.plist`. Ajoutez les [clés d'autorisation iOS](#ios) et, pour le NFC, les identifiants de sélection ISO7816 sous `ios.infoPlist` dans le même fichier. `D392F000260100000001` permet au SDK de lire la Japan My Number Card via [JPKI](https://docs.didit.me/fr/core-technology/nfc-verification/overview.md#carte-my-number-japonaise-jpki) :```json theme={null}
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NFCReaderUsageDescription": "NFC is used to read passport chip data for identity verification.",
        "com.apple.developer.nfc.readersession.iso7816.select-identifiers": [
          "D23300000045737445494420763335",
          "A0000002471001",
          "A0000002472001",
          "00000000000000",
          "D392F000260100000001"
        ]
      }
    }
  }
}
```#### Désactiver les dépendances NFCPour compiler sans prise en charge du NFC (binaire plus léger, aucune capacité NFC requise), transmettez les options du plugin :```json theme={null}
{
  "expo": {
    "plugins": [
      [
        "@didit-protocol/sdk-react-native",
        { "iosNfcEnabled": false, "androidNfcEnabled": false }
      ]
    ]
  }
}
```Lorsque le NFC est désactivé, vous n'avez pas besoin de la capacité NFC iOS, des droits NFC ni de la configuration de provisioning liée au NFC.> [!WARNING]
>
> Ce SDK utilise des modules natifs (caméra, NFC) qui ne sont **pas disponibles dans Expo Go**. Vous devez utiliser un [build de développement](https://docs.expo.dev/develop/development-builds/introduction/) ou exécuter `npx expo prebuild` pour générer les projets natifs.### React Native CLI```bash theme={null}
npm install @didit-protocol/sdk-react-native
# or
yarn add @didit-protocol/sdk-react-native
```#### Configuration iOSAjoutez le pod DiditSDK à votre `Podfile` (il n'est pas disponible sur le dépôt CocoaPods trunk). Le bloc ci-dessous accepte une variable d'environnement `DIDIT_SDK_IOS_NFC_ENABLED`, qui vous permet de basculer vers le subspec sans NFC (`DiditSDK/Core`) au moment de l'installation :```ruby theme={null}
# In your ios/Podfile — at the top, before the target block:
didit_sdk_ios_nfc_enabled = ENV.fetch('DIDIT_SDK_IOS_NFC_ENABLED', 'true').downcase != 'false'

def max_ios_version(*versions)
  versions.map(&:to_s).max_by { |version| Gem::Version.new(version) }
end

platform :ios, didit_sdk_ios_nfc_enabled ? max_ios_version(min_ios_version_supported, '15.0') : min_ios_version_supported

# Inside your app target:
didit_sdk_ios_pod = didit_sdk_ios_nfc_enabled ? 'DiditSDK' : 'DiditSDK/Core'
pod didit_sdk_ios_pod, :podspec => 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.13.2/DiditSDK.podspec'
```> [!WARNING]
>
> La balise de l'URL du podspec doit correspondre à `diditNativeSdkVersions.ios` de la version du package installée.
> React Native `4.13.2` fixe le SDK natif iOS `4.13.2` et le SDK natif Android `4.13.2`. Ne faites pas pointer le podspec
> vers `main` : le package dépend de cette version exacte du SDK natif iOS. Dès que `main` prend de l'avance, CocoaPods détecte deux exigences incompatibles pour
> `DiditSDK` et chaque `pod install` échoue. Le plugin de configuration Expo calcule cette URL pour vous ; seul le chemin React Native CLI pur doit la saisir manuellement.Installez ensuite les dépendances :```bash theme={null}
cd ios
bundle exec pod install
```Pour recompiler sans les dépendances NFC, nettoyez CocoaPods et relancez l'installation avec la variable d'environnement définie :```bash theme={null}
cd ios
rm -rf Pods Podfile.lock
DIDIT_SDK_IOS_NFC_ENABLED=false bundle exec pod install
```#### Configuration AndroidAjoutez le dépôt Maven de Didit à votre `settings.gradle` au niveau du projet :```groovy theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url "https://raw.githubusercontent.com/didit-protocol/sdk-android/main/repository" }
    }
}
```Ajoutez ce qui suit dans `android/app/build.gradle` de votre application (à l'intérieur du bloc `android { ... }`) afin de résoudre les conflits de classes en double de BouncyCastle, ainsi que le doublon `MANIFEST.MF` OSGi que peuvent provoquer les dépendances transitives du DiditSDK :```groovy theme={null}
android {
    configurations.configureEach {
        exclude group: 'org.bouncycastle', module: 'bcprov-jdk15to18'
        exclude group: 'org.bouncycastle', module: 'bcutil-jdk15to18'
        exclude group: 'org.bouncycastle', module: 'bcpkix-jdk15to18'
        exclude group: 'org.bouncycastle', module: 'bcprov-jdk15on'
    }
    packaging {
        resources {
            pickFirsts += ['org/bouncycastle/**']
            excludes += 'META-INF/versions/9/OSGI-INF/MANIFEST.MF'
        }
    }
}
```Pour compiler sans les dépendances NFC Android (utilise l'artefact `me.didit:didit-sdk-core` au lieu de `me.didit:didit-sdk`), ajoutez ceci dans `android/gradle.properties` :```properties theme={null}
diditSdkAndroidNfcEnabled=false
```Supprimez cette propriété, ou définissez-la à `true`, pour utiliser le SDK Android complet avec le NFC.***## Autorisations### iOSAjoutez les clés suivantes au fichier `Info.plist` de votre application. Si des clés de confidentialité iOS obligatoires sont manquantes, iOS arrêtera immédiatement l'application dès que le SDK tentera d'accéder à la ressource protégée.| Autorisation | Clé Info.plist | Description | Requis |
| - | - | - | - |
| Caméra | `NSCameraUsageDescription` | Numérisation de documents et vérification faciale | Oui |
| Microphone | `NSMicrophoneUsageDescription` | Enregistrement vidéo de détection du vivant | Oui |
| Bibliothèque de photos | `NSPhotoLibraryUsageDescription` | Téléversement d'images de documents | Oui |
| Localisation | `NSLocationWhenInUseUsageDescription` | Géolocalisation pour la prévention de la fraude | Oui |
| NFC | `NFCReaderUsageDescription` | Lecture des puces NFC des passeports/cartes d'identité | Si NFC utilisé |```xml theme={null}
<key>NSCameraUsageDescription</key>
<string>Camera access is required to scan your identity documents for verification.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access is required to record video for liveness verification.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access is required to upload document images.</string>
<key>NFCReaderUsageDescription</key>
<string>NFC is used to read passport chip data for identity verification.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location access is used to detect your country for identity verification.</string>
```#### Configuration NFCPour activer la lecture NFC des passeports et des cartes d'identité à puce :1) **Ajoutez la fonctionnalité NFC** dans Xcode :
   * Sélectionnez votre cible > **Signing & Capabilities** > **+ Capability** > **Near Field Communication Tag Reading**

2) **Ajoutez les identifiants ISO7816** à `Info.plist` :```xml theme={null}
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
    <string>D23300000045737445494420763335</string>
    <string>A0000002471001</string>
    <string>A0000002472001</string>
    <string>00000000000000</string>
    <string>D392F000260100000001</string>
</array>
````D392F000260100000001` permet au SDK de lire la carte japonaise My Number via [JPKI](https://docs.didit.me/fr/core-technology/nfc-verification/overview.md#carte-my-number-japonaise-jpki) : sans cet identifiant, iOS ne transmet pas la carte au SDK. La lecture de la carte My Number n'est pas encore activée en production, et cet identifiant ne modifie rien pour les autres documents, vous pouvez donc l'ajouter dès maintenant.3) **Ajoutez un fichier d'entitlements** avec la lecture d'étiquettes NFC activée :```xml theme={null}
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>TAG</string>
</array>
```Assurez-vous que le profil de provisionnement de l'application inclut la fonctionnalité NFC Tag Reading. Cette configuration NFC n'est pas nécessaire lorsque le NFC est désactivé.### AndroidLes autorisations suivantes sont déclarées dans le fichier `AndroidManifest.xml` du SDK et fusionnées automatiquement :| Autorisation | Description | Requis |
| - | - | - |
| `INTERNET` | Accès réseau pour la communication avec l'API | Oui |
| `ACCESS_NETWORK_STATE` | Détection de la disponibilité du réseau | Oui |
| `CAMERA` | Numérisation de documents et vérification faciale | Oui |
| `NFC` | Lecture des puces NFC des passeports/cartes d'identité | Si NFC utilisé |Les fonctionnalités matérielles liées à la caméra et au NFC sont déclarées comme optionnelles (`android:required="false"`). Votre application peut donc être installée sur des appareils qui ne disposent pas de ces fonctionnalités.***## Démarrage rapide```tsx theme={null}
import { startVerification, VerificationStatus } from '@didit-protocol/sdk-react-native';

// Start verification with a session token from your backend
const result = await startVerification('your-session-token');

switch (result.type) {
  case 'completed':
    if (result.session.status === VerificationStatus.Approved) {
      console.log('Identity verified!');
    }
    break;
  case 'cancelled':
    console.log('User cancelled');
    break;
  case 'failed':
    console.log('Error:', result.error.message);
    break;
}
```***## Méthodes d'intégrationLe SDK prend en charge deux méthodes d'intégration :### Méthode 1 : Token de session (recommandée pour la production)Créez une session sur votre backend à l'aide de l'[API de création de session de vérification](https://docs.didit.me/fr/sessions-api/create-session.md), puis transmettez le token au SDK :```tsx theme={null}
import { startVerification } from '@didit-protocol/sdk-react-native';

// Your backend creates a session and returns the token
const sessionToken = await yourBackend.createVerificationSession(userId);

// Pass the token to the SDK
const result = await startVerification(sessionToken);
```Cette approche vous offre un contrôle total sur :- L'association des sessions à vos utilisateurs (`vendor_data`)
- La définition de métadonnées personnalisées
- La configuration des callbacks par session### Méthode 2 : ID de workflow (intégration plus simple)Pour des intégrations plus simples, le SDK peut créer des sessions directement à l'aide de votre ID de workflow :```tsx theme={null}
import { startVerificationWithWorkflow } from '@didit-protocol/sdk-react-native';

const result = await startVerificationWithWorkflow('your-workflow-id', {
  vendorData: 'user-123',
  contactDetails: { email: 'user@example.com' },
  config: { loggingEnabled: true },
});
```***## ConfigurationPersonnalisez le comportement du SDK en transmettant un objet `DiditConfig` :```tsx theme={null}
const result = await startVerification('your-session-token', {
  languageCode: 'es',           // Force Spanish language
  showLanguageSelector: true,   // Let the user change language
  fontFamily: 'Avenir',         // Custom font (must be registered natively)
  loggingEnabled: true,         // Enable debug logging
  showCloseButton: true,        // Show close (X) button on step screens
  showExitConfirmation: true,   // Confirm before exit
  closeOnComplete: false,       // Auto-dismiss UI on completion
});
```Pour `startVerificationWithWorkflow`, transmettez la configuration dans `options.config` :```tsx theme={null}
const result = await startVerificationWithWorkflow('your-workflow-id', {
  vendorData: 'user-123',
  config: {
    languageCode: 'es',
    showLanguageSelector: true,
    loggingEnabled: true,
    showCloseButton: true,
    showExitConfirmation: true,
  },
});
```### Options de configuration| Propriété | Type | Valeur par défaut | Description |
| - | - | - | - |
| `languageCode` | `string` | Paramètres régionaux de l'appareil | Code langue ISO 639-1 (par ex. `"en"`, `"fr"`, `"ar"`) |
| `showLanguageSelector` | `boolean` | `false` | Afficher le sélecteur de langue façon web sur l'écran d'accueil |
| `fontFamily` | `string` | Police système | Nom de la famille de police personnalisée (doit être enregistrée nativement) |
| `loggingEnabled` | `boolean` | `false` | Activer la journalisation de débogage du SDK |
| `showCloseButton` | `boolean` | `true` | Afficher le bouton de fermeture (X) sur les écrans des étapes de vérification |
| `showExitConfirmation` | `boolean` | `true` | Afficher une boîte de dialogue de confirmation lorsque l'utilisateur tente de quitter |
| `closeOnComplete` | `boolean` | `false` | Masquer automatiquement l'interface utilisateur de vérification une fois terminée |
| `defaultDocumentCamera` | `CameraLens?` | Valeur par défaut native (`CameraLens.Back`) | Objectif utilisé à l'ouverture de l'écran de capture du document |
| `defaultLivenessCamera` | `CameraLens?` | Valeur par défaut native (`CameraLens.Front`) | Objectif utilisé à l'ouverture de l'écran de capture faciale (détection du vivant) |
| `showDocumentCameraSwitchButton` | `boolean` | `true` | Afficher le sélecteur de caméra intégré sur l'écran de capture du document |
| `showLivenessCameraSwitchButton` | `boolean` | `true` | Afficher le sélecteur de caméra intégré sur l'écran de capture faciale |### Options de caméraLes options de caméra correspondent aux [options de caméra du SDK Web](https://docs.didit.me/fr/integration/web-sdks/javascript-sdk.md#options-de-caméra).
Chaque objectif correspond à `CameraLens.Front` ou `CameraLens.Back`.
Si l'appareil ne dispose pas de l'objectif demandé, le SDK utilise la première caméra disponible.
Le sélecteur de caméra est également masqué sur les appareils ne disposant que d'une seule caméra.
Définissez une option de changement de caméra sur `false` pour contraindre l'utilisateur à l'objectif par défaut de cette étape.```tsx theme={null}
import { startVerification, CameraLens } from '@didit-protocol/sdk-react-native';

await startVerification('your-session-token', {
  defaultLivenessCamera: CameraLens.Back,
  showLivenessCameraSwitchButton: false,
});
```> [!NOTE]
>
> **Thèmes et couleurs** : Les couleurs, les arrière-plans et les paramètres de l'écran d'introduction sont configurés dans vos [paramètres de marque blanche](https://business.didit.me) sur la Console Didit, et non dans la configuration du SDK. Cela garantit une cohérence de marque sur toutes les plateformes.***## Prise en charge linguistiqueLe SDK prend en charge **54 langues**. Si aucune langue n'est spécifiée, le SDK utilise les paramètres régionaux de l'appareil avec l'anglais comme langue de secours.```tsx theme={null}
// Use device locale (default)
await startVerification(token);

// Force specific language
await startVerification(token, { languageCode: 'fr' });

// Let the user change language on the welcome screen
await startVerification(token, { showLanguageSelector: true });
```**[Voir toutes les langues prises en charge →](https://docs.didit.me/fr/integration/supported-languages.md)*****## Options avancéesCes options sont uniquement disponibles avec `startVerificationWithWorkflow`, où le SDK crée la session pour votre compte.### Coordonnées (préremplissage et notifications)Fournissez des coordonnées pour préremplir les formulaires de vérification et activer les notifications par e-mail :```tsx theme={null}
const result = await startVerificationWithWorkflow('your-workflow-id', {
  contactDetails: {
    email: 'user@example.com',
    sendNotificationEmails: true,  // Send status update emails
    emailLang: 'en',               // Email language (ISO 639-1)
    phone: '+14155552671',         // E.164 format
  },
});
```### Informations attendues (validation croisée)Fournissez les informations utilisateur attendues pour une validation croisée automatique avec les données extraites du document :```tsx theme={null}
const result = await startVerificationWithWorkflow('your-workflow-id', {
  expectedDetails: {
    firstName: 'John',
    lastName: 'Doe',
    dateOfBirth: '1990-05-15',     // YYYY-MM-DD format
    gender: 'M',
    nationality: 'USA',            // ISO 3166-1 alpha-3
    country: 'USA',
    address: '1 Market St, San Francisco, CA',
    identificationNumber: 'A1234567',
    ipAddress: '203.0.113.42',
    portraitImage: 'https://...',  // URL or base64 reference image
  },
});
```Tous les champs de `ExpectedDetails` sont optionnels. Consultez [`src/types.ts`](https://github.com/didit-protocol/sdk-react-native/blob/main/src/types.ts) pour le type complet.### Métadonnées personnaliséesEnregistrez des métadonnées JSON personnalisées avec la session (non affichées à l'utilisateur) :```tsx theme={null}
const result = await startVerificationWithWorkflow('your-workflow-id', {
  vendorData: 'user-123',
  metadata: '{"internalId": "abc123", "source": "mobile-app"}',
});
```***## Traitement des résultats`startVerification` et `startVerificationWithWorkflow` renvoient tous deux une `Promise<VerificationResult>`. Le résultat est une union discriminée — utilisez le champ `type` pour déterminer l'issue.### Cas de résultat| Cas | Description |
| - | - |
| `completed` | Flux de vérification terminé (vérifiez `session.status` pour connaître le résultat) |
| `cancelled` | L'utilisateur a annulé le flux de vérification |
| `failed` | Une erreur est survenue pendant la vérification |### Propriétés de SessionData| Propriété | Type | Description |
| - | - | - |
| `sessionId` | `string` | Identifiant unique de session |
| `status` | `VerificationStatus` | `Approved`, `Pending` ou `Declined` |### Types d'erreur| Erreur | Description |
| - | - |
| `sessionExpired` | La session a expiré |
| `networkError` | Problème de connectivité réseau |
| `cameraAccessDenied` | Autorisation de la caméra non accordée |
| `notInitialized` | SDK non initialisé (Android uniquement) |
| `apiError` | La requête API a échoué |
| `unknown` | Autre erreur avec un message |### Perte de connexionSi l'appareil perd sa connexion pendant la vérification, le SDK affiche un écran « Pas de connexion Internet » par-dessus le flux au lieu de laisser une étape en chargement.
Il continue à vérifier en arrière-plan et ferme automatiquement l'écran dès que Didit est de nouveau joignable, et l'utilisateur reprend à l'étape où il s'était arrêté.
L'écran propose **Réessayer** et, lorsque `showCloseButton` est défini sur `true` (valeur par défaut), **Quitter la vérification**.
Quitter interrompt la vérification avec un résultat `failed` dont l'erreur est `networkError`, afin que votre application sache que l'utilisateur est parti en raison de la connexion.### Exemple complet de traitement des résultats```tsx theme={null}
import {
  startVerification,
  VerificationStatus,
  type VerificationResult,
} from '@didit-protocol/sdk-react-native';

async function verify(token: string) {
  const result: VerificationResult = await startVerification(token);

  switch (result.type) {
    case 'completed':
      switch (result.session.status) {
        case VerificationStatus.Approved:
          console.log('Approved! Session:', result.session.sessionId);
          // User is verified — grant access
          break;
        case VerificationStatus.Pending:
          console.log('Under review. Session:', result.session.sessionId);
          // Show "verification in progress" UI
          break;
        case VerificationStatus.Declined:
          console.log('Declined. Session:', result.session.sessionId);
          // Handle declined verification
          break;
      }
      break;

    case 'cancelled':
      console.log('User cancelled the verification.');
      // Maybe show retry option
      break;

    case 'failed':
      console.log(`Error [${result.error.type}]: ${result.error.message}`);
      // Handle error — show retry or contact support
      break;
  }
}
```***## Exemple de bout en bout (Session backend → SDK React Native → Webhook)L'intégration prête pour la production : votre backend crée la session, votre application RN reçoit le `session_token`, et le SDK exécute le flux. La décision finale est transmise à votre backend par webhook — ne vous fiez jamais uniquement au résultat côté client.### 1. Backend — créer la session```ts theme={null}
// Node.js / Express example. Run on your server. NEVER ship DIDIT_API_KEY to the device.
import express from "express";

const app = express();
app.use(express.json());

app.post("/api/verification/start", 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, // your stable user id
    }),
  });

  if (!response.ok) {
    return res.status(500).json({ error: `Didit ${response.status}` });
  }

  const { session_id, session_token } = await response.json();
  // Persist session_id <-> userId so you can match the webhook later.
  res.json({ session_id, session_token });
});
```### 2. React Native — échanger et lancer le SDK```tsx theme={null}
import { useCallback, useState } from 'react';
import { Button, View } from 'react-native';
import {
  startVerification,
  VerificationStatus,
  type VerificationResult,
} from '@didit-protocol/sdk-react-native';

export function VerifyButton({ userId }: { userId: string }) {
  const [loading, setLoading] = useState(false);

  const onPress = useCallback(async () => {
    setLoading(true);
    try {
      const r = await fetch('https://your-backend.example.com/api/verification/start', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ userId }),
      });
      const { session_token } = await r.json();

      const result: VerificationResult = await startVerification(session_token);

      switch (result.type) {
        case 'completed':
          if (result.session.status === VerificationStatus.Approved) {
            // Optimistic UI; rely on the webhook delivered to your backend as the source of truth.
          }
          break;
        case 'cancelled':
          // User dismissed the flow
          break;
        case 'failed':
          // Show retry — result.error.type / result.error.message
          break;
      }
    } finally {
      setLoading(false);
    }
  }, [userId]);

  return (
    <View>
      <Button title={loading ? 'Starting...' : 'Verify identity'} onPress={onPress} disabled={loading} />
    </View>
  );
}
```### 3. Backend — recevoir la décision finale par webhook```ts theme={null}
app.post("/api/webhooks/didit", express.raw({ type: "application/json" }), (req, res) => {
  // 1. Verify the X-Signature header (see Webhooks docs)
  // 2. Parse the body
  const event = JSON.parse(req.body.toString());
  if (event.webhook_type === "status.updated") {
    // event.session_id, event.status ("Approved" | "Declined" | "In Review" | ...)
    // Look up the user by session_id and update their verification state.
  }
  res.sendStatus(200);
});
```Consultez le [guide sur les webhooks](https://docs.didit.me/fr/integration/webhooks.md) pour les détails sur la vérification de signature HMAC.***## Exemple complet```tsx theme={null}
import { useState, useCallback } from 'react';
import {
  Text,
  View,
  TextInput,
  TouchableOpacity,
  Alert,
  ActivityIndicator,
  SafeAreaView,
} from 'react-native';
import {
  startVerification,
  VerificationStatus,
  type VerificationResult,
} from '@didit-protocol/sdk-react-native';

export default function App() {
  const [token, setToken] = useState('');
  const [loading, setLoading] = useState(false);

  const handleVerify = useCallback(async () => {
    if (!token.trim()) {
      Alert.alert('Error', 'Please enter a session token.');
      return;
    }

    setLoading(true);
    try {
      const result = await startVerification(token.trim(), {
        loggingEnabled: true,
      });

      switch (result.type) {
        case 'completed':
          Alert.alert(
            'Verification Complete',
            `Status: ${result.session.status}\nSession: ${result.session.sessionId}`
          );
          break;
        case 'cancelled':
          Alert.alert('Cancelled', 'The user cancelled the verification.');
          break;
        case 'failed':
          Alert.alert('Failed', `${result.error.type}: ${result.error.message}`);
          break;
      }
    } catch (error) {
      Alert.alert('Error', `Unexpected error: ${error}`);
    } finally {
      setLoading(false);
    }
  }, [token]);

  return (
    <SafeAreaView style={{ flex: 1, padding: 24, justifyContent: 'center' }}>
      <TextInput
        placeholder="Enter session token..."
        value={token}
        onChangeText={setToken}
        autoCapitalize="none"
        style={{
          borderWidth: 1,
          borderColor: '#ccc',
          borderRadius: 8,
          padding: 12,
          marginBottom: 16,
        }}
      />
      <TouchableOpacity
        onPress={handleVerify}
        disabled={loading}
        style={{
          backgroundColor: '#1a1a1a',
          borderRadius: 8,
          padding: 16,
          alignItems: 'center',
          opacity: loading ? 0.6 : 1,
        }}
      >
        {loading ? (
          <ActivityIndicator color="#fff" />
        ) : (
          <Text style={{ color: '#fff', fontWeight: '600' }}>
            Start Verification
          </Text>
        )}
      </TouchableOpacity>
    </SafeAreaView>
  );
}
```***


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