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

# Flutter SDK: KYC के लिए Dart मोबाइल SDK

> Didit का Flutter Dart KYC SDK: native iOS और Android, बायोमेट्रिक लाइवनेस, NFC पासपोर्ट। पूर्ण KYC जाँच $0.33 से, $10 मासिक निःशुल्क, कोई अनुबंध नहीं।



Flutter SDK इंटीग्रेशन प्रॉम्प्ट
        प्रॉम्प्ट को क्लिपबोर्ड पर कॉपी करें



      
      

\<pre>

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

\## Requirements
\- Flutter 3.3+, Dart 3.11+
\- iOS 13.0+ (NFC requires iOS 15+)
\- Android API 23+ (Android 6.0)

\## Installation
flutter pub add didit_sdk

iOS — the plugin picks the native variant from the $DiditSdkIosVariant Ruby global in ios/Podfile (or the DIDIT_SDK_IOS_VARIANT env var); valid values are 'all' (default), 'core', 'autodetection', 'nfc'. At the top of ios/Podfile:
$DiditSdkIosVariant = 'all'
platform :ios, ['all', 'nfc'].include?($DiditSdkIosVariant) ? '15.0' : '13.0'
Inside the target block, add the matching subspec:
pod 'DiditSDK/All', :podspec => 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.13.2/DiditSDK.podspec'
The tag in that URL must equal the native iOS SDK version the didit_sdk release pins (4.13.2 pins 4.13.2); do not use 'main', because the plugin requires that exact version and pod install fails when the URL resolves to a different one.
'all' and 'nfc' require platform :ios, '15.0'; 'core' and 'autodetection' run on iOS 13.0+.
Then: cd ios && pod install
Info.plist must include NSCameraUsageDescription, NSMicrophoneUsageDescription, NSPhotoLibraryUsageDescription (required) and NFCReaderUsageDescription if using NFC.

Android — for no-NFC builds add to android/gradle.properties:
diditSdkAndroidNfcEnabled=false
For NFC-enabled (default), add to android/app/build.gradle.kts inside android block:
packaging {
  resources {
      pickFirsts += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
  }
}

\## 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 Flutter app (never expose DIDIT_API_KEY to the device).

\## Integration
import 'package:didit_sdk/sdk_flutter.dart';

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

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

// Handle result
switch (result) {
case VerificationCompleted(:final session):
if (session.status == VerificationStatus.approved) { /* grant access */ }
case VerificationCancelled():
// User dismissed the verification flow
case VerificationFailed(:final error):
// SDK error — show error.message
}

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

\## Error Types (VerificationErrorType enum)
sessionExpired, networkError, cameraAccessDenied, notInitialized, apiError, retryBlocked, unknown

\## Advanced Session Parameters
contact_details, expected_details, and metadata are only available via the Session Token method (your backend creates the session). The Dart startVerificationWithWorkflow API only accepts workflowId, vendorData, and config.

\## 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
\- Flutter SDK: https://docs.didit.me/integration/native-sdks/flutter-sdk
\- GitHub: https://github.com/didit-protocol/sdk-flutter
\- pub.dev: https://pub.dev/packages/didit_sdk
\- Webhooks: https://docs.didit.me/integration/webhooks
\- API Reference: https://docs.didit.me/api-reference/overview`

\</pre>



      
      

यहाँ पेस्ट करें

एक क्रॉस-प्लेटफ़ॉर्म Flutter प्लगइन जो नेटिव iOS और Android SDK को रैप करता है और पहचान सत्यापन के लिए एकीकृत Dart API प्रदान करता है।> [card] [GitHub रिपॉज़िटरी](https://github.com/didit-protocol/sdk-flutter)
>
> GitHub पर सोर्स कोड और उदाहरण देखें> [card] [pub.dev पैकेज](https://pub.dev/packages/didit_sdk)
>
> didit\_sdk> [!NOTE]
>
> ### **नेटिव SDK**: Flutter ऐप्स के लिए यही अनुशंसित तरीका है। यह SDK प्लेटफ़ॉर्म चैनल के ज़रिए नेटिव iOS और Android SDK को रैप करता है, जिससे बेहतर उपयोगकर्ता अनुभव, अनुकूलित कैमरा हैंडलिंग और पूर्ण NFC समर्थन मिलता है।***## आवश्यकताएँ| आवश्यकता | न्यूनतम संस्करण |
| - | - |
| Flutter | 3.3+ |
| Dart | 3.11+ |### प्लेटफ़ॉर्म आवश्यकताएँ| प्लेटफ़ॉर्म | न्यूनतम संस्करण | नोट्स |
| - | - | - |
| iOS | 13.0+ | NFC पासपोर्ट रीडिंग के लिए iOS 15.0+ आवश्यक है |
| Android | API 23+ (6.0) | Java 17+ |> [!NOTE]
>
> **बायोमेट्रिक सहमति के लिए नेटिव 4.10.0 या उसके बाद का संस्करण चाहिए।** Illinois, Texas या Colorado के कानून के तहत आने वाले लोगों के लिए, Didit पहले चेहरा कैप्चर से पहले स्पष्ट [बायोमेट्रिक सहमति](https://docs.didit.me/hi/getting-started/biometric-consent.md) माँग सकता है। ऐसी Flutter SDK रिलीज़ जो नेटिव iOS और Android के 4.10.0 या उसके बाद के संस्करण से जुड़ी है, यह चरण दिखाती है। इससे पुराने संस्करण यह चरण नहीं दिखा सकते: उनके सत्र पहले की तरह चलते हैं, और निर्णय में सहमति को एकत्र नहीं किया गया दर्ज होता है (`biometric_consent.reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`)। यदि आप उन राज्यों में लोगों का सत्यापन करते हैं, तो अपग्रेड करें।***## इंस्टॉलेशन```bash theme={null}
flutter pub add didit_sdk
```या इसे मैन्युअल रूप से अपनी `pubspec.yaml` में जोड़ें:```yaml theme={null}
dependencies:
  didit_sdk: ^4.13.2
```फिर यह चलाएँ:```bash theme={null}
flutter pub get
```### नेटिव SDK वैरिएंट`didit_sdk` में पूरा नेटिव SDK शामिल है।
छोटा बाइनरी बनाने के लिए, इसके बजाय कोई वैरिएंट पैकेज डिपेंड करें। वह बिल्कुल वही Dart API देता है और दोनों प्लेटफ़ॉर्म पर मेल खाने वाले नेटिव SDK को पिन करता है:| पैकेज | स्वचालित कैप्चर | NFC पासपोर्ट रीडिंग | न्यूनतम iOS |
| - | - | - | - |
| `didit_sdk` (डिफ़ॉल्ट) | हाँ | हाँ | 15.0 |
| `didit_sdk_core` | नहीं | नहीं | 13.0 |
| `didit_sdk_autodetection` | हाँ | नहीं | 13.0 |
| `didit_sdk_nfc` | नहीं | हाँ | 15.0 |```yaml theme={null}
dependencies:
  didit_sdk_core: ^4.13.2
```इन पैकेजों में से ठीक एक पर डिपेंड करें, और जिसे आपने चुना है उसी से इम्पोर्ट करें, उदाहरण के लिए `package:didit_sdk_core/sdk_flutter.dart`।### iOS सेटअपप्लगइन Flutter के दोनों iOS डिपेंडेंसी मैनेजरों (Swift Package Manager और CocoaPods) को सपोर्ट करता है।#### Swift Package Managerयदि आपके Flutter वर्शन में Swift Package Manager सपोर्ट सक्षम है (Flutter 3.24+ पर `flutter config --enable-swift-package-manager` से ऑप्ट इन करें), तो प्लगइन अपने आप एक Swift package के रूप में इस्तेमाल होता है।
इसके लिए Podfile कॉन्फ़िगरेशन की ज़रूरत नहीं है। नेटिव DiditSDK डिपेंडेंसी GitHub से खुद रिज़ॉल्व हो जाती है।
Xcode में अपने ऐप का iOS डिप्लॉयमेंट टार्गेट (Runner टार्गेट और प्रोजेक्ट दोनों) अपने चुने हुए पैकेज की न्यूनतम वैल्यू पर सेट करें: `didit_sdk` और `didit_sdk_nfc` के लिए 15.0, और `didit_sdk_core` और `didit_sdk_autodetection` के लिए 13.0।#### CocoaPods`didit_sdk` के साथ, प्लगइन नेटिव iOS SDK वैरिएंट को `$DiditSdkIosVariant` से चुनता है। यह एक Ruby ग्लोबल है, जिसे आप अपने ऐप की `ios/Podfile` में सेट करते हैं (DiditSDK pod CocoaPods trunk पर नहीं है):```ruby theme={null}
# Pick one: 'all', 'core', 'autodetection', 'nfc'
$DiditSdkIosVariant = 'all'

didit_sdk_ios_deployment_target = ['all', 'nfc'].include?($DiditSdkIosVariant) ? '15.0' : '13.0'
platform :ios, didit_sdk_ios_deployment_target

didit_sdk_ios_pod = case $DiditSdkIosVariant
                    when 'all' then 'DiditSDK/All'
                    when 'core' then 'DiditSDK/Core'
                    when 'autodetection' then 'DiditSDK/AutoDetection'
                    when 'nfc' then 'DiditSDK/NFC'
                    end
didit_sdk_ios_podspec = 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.13.2/DiditSDK.podspec'

target 'Runner' do
  use_frameworks!

  pod didit_sdk_ios_pod, :podspec => didit_sdk_ios_podspec

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = didit_sdk_ios_deployment_target
    end
  end
end
```यदि आप कोई वैरिएंट पैकेज (`didit_sdk_core`, `didit_sdk_autodetection`, `didit_sdk_nfc`) इस्तेमाल करते हैं, तो वह अपना नेटिव subspec सीधे पिन करता है और `$DiditSdkIosVariant` को अनदेखा करता है। अपनी Podfile की `pod` लाइन और डिप्लॉयमेंट टार्गेट को उस वैरिएंट से मेल खाते रखें (उदाहरण के लिए `pod 'DiditSDK/Core', :podspec => ...` के साथ `platform :ios, '13.0'`)।> [!NOTE]
>
> `all` और `nfc` वैरिएंट के लिए iOS 15.0+ का डिप्लॉयमेंट टार्गेट ज़रूरी है। `core` और `autodetection` iOS 13.0 को टार्गेट कर सकते हैं। वैरिएंट बदलते समय पहले CocoaPods को साफ़ करें (`rm -rf Pods Podfile.lock`), ताकि पिछला SDK वैरिएंट दोबारा इस्तेमाल न हो।> [!WARNING]
>
> podspec URL में मौजूद टैग को उस नेटिव iOS SDK वर्शन से मेल खाना चाहिए जिसे आपका `didit_sdk` रिलीज़ पिन करता है (`4.13.2` नेटिव `4.13.2` को पिन करता है)। यदि URL किसी पुराने टैग की ओर इशारा करता है, तो `pod install` रिज़ॉल्व करने में विफल हो जाता है। CocoaPods एक ऐसा podspec पाता है जो उस पुराने वर्शन की घोषणा करता है, जबकि प्लगइन एक सटीक मेल माँगता है। जब आप `didit_sdk` अपग्रेड करते हैं, तो इस URL का टैग भी उसी वर्शन पर बदलें।### Android सेटअपडिफ़ॉल्ट रूप से प्लगइन NFC सहित पूरा Android SDK डिपेंड करता है। NFC के बिना बनाने के लिए, `android/gradle.properties` में यह जोड़ें:```properties theme={null}
diditSdkAndroidNfcEnabled=false
```इससे डिपेंडेंसी `me.didit:didit-sdk` से बदलकर `me.didit:didit-sdk-core` हो जाती है, और NFC रीडर मॉड्यूल तथा उसकी JMRTD/SCUBA/BouncyCastle डिपेंडेंसी हट जाती हैं।जब NFC सक्षम हो (डिफ़ॉल्ट), तो BouncyCastle की एक डुप्लिकेट मेटाडेटा फ़ाइल को हल करने के लिए `android/app/build.gradle.kts` में यह packaging नियम जोड़ें:```kotlin theme={null}
android {
    packaging {
        resources {
            pickFirsts += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
        }
    }
}
```इस नियम के बिना बिल्ड `mergeDebugJavaResource` एरर के साथ विफल हो जाता है। जब `diditSdkAndroidNfcEnabled=false` हो, तब यह नियम ज़रूरी नहीं है।> [!NOTE]
>
> Android नेटिव SDK एक रिमोट GitHub Maven रिपॉज़िटरी से रिज़ॉल्व होता है (प्लगइन 3.4.0 से)। आपके ऐप में किसी मैन्युअल Maven कॉन्फ़िगरेशन की ज़रूरत नहीं है।***## अनुमतियाँ### iOSअपने ऐप की `Info.plist` में निम्नलिखित कुंजियाँ जोड़ें:| अनुमति | Info.plist कुंजी | विवरण | आवश्यक |
| - | - | - | - |
| कैमरा | `NSCameraUsageDescription` | दस्तावेज़ स्कैनिंग और चेहरा सत्यापन | हाँ |
| माइक्रोफ़ोन | `NSMicrophoneUsageDescription` | लाइवनेस जाँच के लिए वीडियो रिकॉर्डिंग | हाँ |
| फ़ोटो लाइब्रेरी | `NSPhotoLibraryUsageDescription` | डिवाइस की गैलरी से दस्तावेज़ अपलोड करना | हाँ |
| NFC | `NFCReaderUsageDescription` | पासपोर्ट/ID कार्ड में NFC चिप पढ़ना | NFC उपयोग करने पर |
| स्थान | `NSLocationWhenInUseUsageDescription` | धोखाधड़ी रोकथाम के लिए भू-स्थान | वैकल्पिक |> [!WARNING]
>
> अगर कोई आवश्यक iOS गोपनीयता कुंजी गायब है, तो जैसे ही SDK उस सुरक्षित संसाधन तक पहुँचने का प्रयास करता है, iOS ऐप को बंद कर देता है। उदाहरण के लिए, `NSCameraUsageDescription` गायब होने पर, उपयोगकर्ता के दस्तावेज़ कैमरा के "फ़ोटो लें" बटन पर टैप करते ही ऐप क्रैश हो जाता है।#### NFC कॉन्फ़िगरेशनचिप वाले पासपोर्ट और ID कार्ड के लिए NFC रीडिंग सक्षम करने हेतु:1) Xcode में **Add NFC Capability** जोड़ें:
   * अपना target चुनें > **Signing & Capabilities** > **+ Capability** > **Near Field Communication Tag Reading**

2) `Info.plist` में **ISO7816 Identifiers** जोड़ें:```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` SDK को [JPKI](https://docs.didit.me/hi/core-technology/nfc-verification/overview.md#japan-my-number-card-jpki) के माध्यम से जापान का My Number Card पढ़ने देता है: इसके बिना iOS कार्ड की जानकारी SDK को नहीं देता। My Number Card पढ़ना अभी प्रोडक्शन में सक्षम नहीं है, और यह पहचानकर्ता दूसरे दस्तावेज़ों पर कोई असर नहीं डालता, इसलिए आप इसे अभी जोड़ सकते हैं।3) NFC टैग रीडिंग सक्षम करने वाली एक **entitlements फ़ाइल** जोड़ें:```xml theme={null}
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>TAG</string>
</array>
```सुनिश्चित करें कि ऐप की प्रोविज़निंग प्रोफ़ाइल (provisioning profile) में NFC Tag Reading capability शामिल हो। अगर आपके Apple Developer account में bundle ID NFC के लिए कॉन्फ़िगर नहीं है, तो Xcode `com.apple.developer.nfc.readersession.formats` entitlement गायब होने के कारण signing विफल कर देगा।यह NFC कॉन्फ़िगरेशन `core` या `autodetection` variants (`$DiditSdkIosVariant`) के लिए, या `didit_sdk_core` / `didit_sdk_autodetection` packages के लिए आवश्यक नहीं है। इनमें से कोई भी चिप नहीं पढ़ता।### AndroidSDK की `AndroidManifest.xml` में निम्नलिखित अनुमतियाँ घोषित हैं और अपने-आप merge हो जाती हैं:| अनुमति | विवरण | आवश्यक |
| - | - | - |
| `INTERNET` | API संचार के लिए नेटवर्क एक्सेस | हाँ |
| `ACCESS_NETWORK_STATE` | नेटवर्क उपलब्धता का पता लगाना | हाँ |
| `CAMERA` | दस्तावेज़ स्कैनिंग और चेहरा सत्यापन | हाँ |
| `NFC` | पासपोर्ट/ID कार्ड में NFC चिप पढ़ना | NFC उपयोग करने पर |कैमरा और NFC हार्डवेयर फ़ीचर वैकल्पिक (`android:required="false"`) घोषित किए गए हैं, ताकि आपका ऐप इन फ़ीचर के बिना डिवाइस पर इंस्टॉल हो सके। जब `diditSdkAndroidNfcEnabled=false` होता है, तो SDK Android NFC अनुमति और फ़ीचर नहीं जोड़ता।#### रनटाइम अनुमतियाँSDK Android की रनटाइम अनुमति के अनुरोधों को अपने-आप संभालता है। जब उपयोगकर्ता कैमरा एक्सेस की ज़रूरत वाले चरण पर पहुँचता है:1) अगर अनुमति पहले से नहीं दी गई है, तो SDK कैमरा अनुमति माँगता है
2) अगर उपयोगकर्ता अनुमति **अस्वीकार** करता है, तो **Try Again** बटन के साथ एक त्रुटि संदेश दिखाया जाता है
3) अगर उपयोगकर्ता अनुमति **स्वीकार** करता है, तो सत्यापन प्रवाह जारी रहता है`startVerification()` कॉल करने से पहले आपको अपने ऐप कोड में कैमरा अनुमति माँगने की ज़रूरत नहीं है। SDK इसे अंदर से संभालता है।***## क्विक स्टार्ट```dart theme={null}
import 'package:didit_sdk/sdk_flutter.dart';

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

switch (result) {
  case VerificationCompleted(:final session):
    if (session.status == VerificationStatus.approved) {
      print('Identity verified!');
    }
  case VerificationCancelled():
    print('User cancelled');
  case VerificationFailed(:final error):
    print('Error: ${error.message}');
}
```***## इंटीग्रेशन के तरीकेSDK दो इंटीग्रेशन तरीके सपोर्ट करता है:### तरीका 1: सत्र टोकन (प्रोडक्शन के लिए अनुशंसित)[सत्यापन सत्र बनाने वाला API](https://docs.didit.me/hi/sessions-api/create-session.md) का उपयोग करके अपने बैकएंड पर एक सत्र बनाएँ, फिर टोकन SDK को पास करें:```dart theme={null}
import 'package:didit_sdk/sdk_flutter.dart';

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

// Pass the token to the SDK
final result = await DiditSdk.startVerification(sessionToken);
```यह तरीका आपको इन पर पूरा नियंत्रण देता है:- सत्रों को अपने उपयोगकर्ताओं से जोड़ना (`vendor_data`)
- कस्टम मेटाडेटा सेट करना
- प्रति सत्र कॉलबैक कॉन्फ़िगर करना### तरीका 2: वर्कफ़्लो ID (सरल इंटीग्रेशन)सरल इंटीग्रेशन के लिए, SDK आपके वर्कफ़्लो ID का उपयोग करके सीधे सत्र बना सकता है। इसके लिए बैकएंड की ज़रूरत नहीं है:```dart theme={null}
import 'package:didit_sdk/sdk_flutter.dart';

final result = await DiditSdk.startVerificationWithWorkflow(
  'your-workflow-id',
  vendorData: 'user-123',
  config: const DiditConfig(loggingEnabled: true),
);
```> [!NOTE]
>
> उन्नत सत्र पैरामीटर (`contact_details`, `expected_details`, `metadata`) **केवल** सत्र टोकन विधि के माध्यम से सपोर्ट होते हैं, जहाँ आपका बैकएंड [सत्र बनाने वाला API](https://docs.didit.me/hi/sessions-api/create-session.md) को पूर्ण पैरामीटर सपोर्ट के साथ कॉल करता है। लौटाए गए `session_token` को `DiditSdk.startVerification()` में पास करें।***## कॉन्फ़िगरेशन`DiditConfig` ऑब्जेक्ट पास करके SDK के व्यवहार को अपनी ज़रूरत के अनुसार बदलें:```dart theme={null}
final result = await DiditSdk.startVerification(
  'your-session-token',
  config: const DiditConfig(
    languageCode: 'es',       // Force Spanish language
    showLanguageSelector: true, // Let the user change language
    fontFamily: 'Avenir',     // Custom font
    loggingEnabled: true,     // Enable debug logging
  ),
);
````startVerificationWithWorkflow` के लिए, `config` को नामित पैरामीटर के रूप में पास करें:```dart theme={null}
final result = await DiditSdk.startVerificationWithWorkflow(
  'your-workflow-id',
  vendorData: 'user-123',
  config: const DiditConfig(
    languageCode: 'es',
    showLanguageSelector: true,
    loggingEnabled: true,
  ),
);
```### कॉन्फ़िगरेशन विकल्प| गुण | प्रकार | डिफ़ॉल्ट | विवरण |
| - | - | - | - |
| `languageCode` | `String?` | डिवाइस लोकेल | ISO 639-1 भाषा कोड (उदाहरण के लिए `"en"`, `"fr"`, `"ar"`) |
| `showLanguageSelector` | `bool` | `false` | स्वागत स्क्रीन पर वेब-शैली भाषा चयनकर्ता दिखाएँ |
| `fontFamily` | `String?` | सिस्टम फ़ॉन्ट | कस्टम फ़ॉन्ट फ़ैमिली का नाम (नेटिव रूप से रजिस्टर होना ज़रूरी है) |
| `loggingEnabled` | `bool` | `false` | SDK डीबग लॉगिंग चालू करें |
| `showCloseButton` | `bool` | `true` | सत्यापन चरण की स्क्रीन पर बंद करने (X) बटन दिखाएँ |
| `showExitConfirmation` | `bool` | `true` | जब उपयोगकर्ता बाहर निकलने की कोशिश करे, तब पुष्टि डायलॉग दिखाएँ |
| `closeOnComplete` | `bool` | `false` | पूरा होने पर सत्यापन UI अपने आप बंद करें |
| `defaultDocumentCamera` | `CameraLens?` | नेटिव डिफ़ॉल्ट (`CameraLens.back`) | दस्तावेज़ कैप्चर स्क्रीन खुलने पर उपयोग होने वाला लेंस |
| `defaultLivenessCamera` | `CameraLens?` | नेटिव डिफ़ॉल्ट (`CameraLens.front`) | चेहरे (लाइवनेस डिटेक्शन) कैप्चर स्क्रीन खुलने पर उपयोग होने वाला लेंस |
| `showDocumentCameraSwitchButton` | `bool` | `true` | दस्तावेज़ कैप्चर स्क्रीन पर कैप्चर के दौरान कैमरा स्विचर दिखाएँ |
| `showLivenessCameraSwitchButton` | `bool` | `true` | चेहरा कैप्चर स्क्रीन पर कैप्चर के दौरान कैमरा स्विचर दिखाएँ |### कैमरा विकल्पकैमरा विकल्प [Web SDK कैमरा विकल्पों](https://docs.didit.me/hi/integration/web-sdks/javascript-sdk.md#कैमरा-विकल्प) से मेल खाते हैं।
हर लेंस `CameraLens.front` या `CameraLens.back` होता है।
अगर डिवाइस में माँगा गया लेंस नहीं है, तो SDK उसका पहला उपलब्ध कैमरा इस्तेमाल करता है।
जिन डिवाइसों में सिर्फ़ एक कैमरा है, उन पर कैमरा स्विचर भी छिपा रहता है।
किसी स्विचर विकल्प को `false` पर सेट करें, ताकि उपयोगकर्ता उस चरण के डिफ़ॉल्ट लेंस तक सीमित रहे।```dart theme={null}
config: const DiditConfig(
  defaultLivenessCamera: CameraLens.back,
  showLivenessCameraSwitchButton: false,
),
```> [!NOTE]
>
> **थीमिंग और रंग**: रंग, बैकग्राउंड और इंट्रो स्क्रीन सेटिंग्स आपकी Didit Console में [व्हाइट लेबल सेटिंग्स](https://business.didit.me) के ज़रिए कॉन्फ़िगर की जाती हैं, SDK कॉन्फ़िगरेशन में नहीं। इससे सभी प्लेटफ़ॉर्म पर ब्रांडिंग एक जैसी रहती है।***## भाषा समर्थनSDK **54 भाषाएँ** सपोर्ट करता है। अगर कोई भाषा तय नहीं की गई है, तो SDK डिवाइस की लोकेल का उपयोग करता है और फ़ॉलबैक के रूप में अंग्रेज़ी का उपयोग करता है।```dart theme={null}
// Use device locale (default)
await DiditSdk.startVerification(token);

// Force specific language
await DiditSdk.startVerification(token,
  config: const DiditConfig(languageCode: 'fr'),
);

// Let the user change language on the welcome screen
await DiditSdk.startVerification(token,
  config: const DiditConfig(showLanguageSelector: true),
);
```**[सभी समर्थित भाषाएँ देखें →](https://docs.didit.me/hi/integration/supported-languages.md)*****## उन्नत सत्र पैरामीटर`contact_details`, `expected_details` और `metadata` जैसे पैरामीटर **केवल** सत्र token विधि के ज़रिए समर्थित हैं। आपका बैकएंड पूर्ण पैरामीटर समर्थन के साथ [`POST /v3/session/`](https://docs.didit.me/hi/sessions-api/create-session) को कॉल करता है, और फिर लौटाया गया `session_token` SDK को पास करता है।```dart theme={null}
// Your backend handles the full session creation:
// POST /v3/session/ with contact_details, expected_details, metadata, etc.
final sessionToken = await yourBackend.createSession(userId);

// The SDK only needs the token
final result = await DiditSdk.startVerification(sessionToken);
```> [!NOTE]
>
> Dart का `startVerificationWithWorkflow` मेथड केवल `workflowId`, `vendorData` और `config` स्वीकार करता है। 3.4.0 से पहले के संस्करणों में `contactDetails`, `expectedDetails` और `metadata` पैरामीटर उपलब्ध थे, लेकिन इन्हें हटा दिया गया है, क्योंकि Unilink endpoint इन्हें नहीं मानता।***## परिणामों को संभालना`startVerification` और `startVerificationWithWorkflow`, दोनों `Future<VerificationResult>` लौटाते हैं। परिणाम एक sealed क्लास है। नतीजा जानने के लिए पैटर्न मैचिंग का उपयोग करें।### परिणाम के मामले| मामला | विवरण |
| - | - |
| `VerificationCompleted` | सत्यापन प्रवाह पूरा हुआ (परिणाम के लिए `session.status` देखें) |
| `VerificationCancelled` | उपयोगकर्ता ने सत्यापन प्रवाह रद्द किया |
| `VerificationFailed` | सत्यापन के दौरान एक त्रुटि हुई |### SessionData गुण| गुण | प्रकार | विवरण |
| - | - | - |
| `sessionId` | `String` | अनोखा सत्र पहचानकर्ता |
| `status` | `VerificationStatus` | `approved`, `pending`, या `declined` |### त्रुटि प्रकार`VerificationErrorType` enum में ये मामले उपलब्ध हैं:| त्रुटि | विवरण |
| - | - |
| `sessionExpired` | सत्र की समय-सीमा समाप्त हो चुकी है |
| `networkError` | नेटवर्क कनेक्टिविटी की समस्या |
| `cameraAccessDenied` | कैमरे की अनुमति नहीं मिली |
| `notInitialized` | SDK इनिशियलाइज़ नहीं हुआ (केवल Android) |
| `apiError` | API अनुरोध विफल हुआ |
| `retryBlocked` | मौजूदा चरण के लिए पुनः प्रयास की अधिकतम संख्या पार हो चुकी है |
| `unknown` | अन्य त्रुटि; विवरण के लिए `error.message` देखें |### कनेक्शन टूटनाअगर सत्यापन के दौरान डिवाइस का कनेक्शन टूट जाता है, तो SDK किसी चरण को लोड होता हुआ छोड़ने के बजाय "No internet connection" स्क्रीन दिखाता है।
वह बैकग्राउंड में लगातार जाँच करता रहता है, और जैसे ही Didit तक पहुँच बनती है, स्क्रीन अपने आप बंद हो जाती है। उपयोगकर्ता वहीं से आगे बढ़ता है जहाँ वह था।
इस स्क्रीन पर **Try Again** और, जब तक बंद करने वाला बटन बंद न किया गया हो, **Exit Verification** दिखता है।
बाहर निकलने पर सत्यापन `VerificationFailed` परिणाम के साथ समाप्त होता है, जिसका त्रुटि प्रकार `networkError` होता है, ताकि आपका ऐप जान सके कि उपयोगकर्ता कनेक्शन की वजह से बाहर गया।### परिणाम संभालने का पूरा उदाहरण```dart theme={null}
import 'package:didit_sdk/sdk_flutter.dart';

Future<void> verify(String token) async {
  final result = await DiditSdk.startVerification(token);

  switch (result) {
    case VerificationCompleted(:final session):
      switch (session.status) {
        case VerificationStatus.approved:
          print('Approved! Session: ${session.sessionId}');
          // User is verified — grant access
        case VerificationStatus.pending:
          print('Under review. Session: ${session.sessionId}');
          // Show "verification in progress" UI
        case VerificationStatus.declined:
          print('Declined. Session: ${session.sessionId}');
          // Handle declined verification
      }

    case VerificationCancelled(:final session):
      print('User cancelled.');
      if (session != null) {
        print('Session: ${session.sessionId}');
      }
      // Maybe show retry option

    case VerificationFailed(:final error):
      print('Error [${error.type}]: ${error.message}');
      // Handle error — show retry or contact support
  }
}
```***## एंड-टू-एंड उदाहरण (बैकएंड सत्र → Flutter SDK → Webhook)एक प्रोडक्शन-तैयार इंटीग्रेशन: आपका बैकएंड सत्र बनाता है, आपका Flutter ऐप `session_token` प्राप्त करता है, और SDK प्रवाह चलाता है। अंतिम निर्णय webhook के ज़रिए आपके बैकएंड तक पहुँचता है। क्लाइंट-साइड परिणाम पर अकेले भरोसा कभी न करें।### 1. बैकएंड: सत्र बनाएँ```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. Flutter: token का आदान-प्रदान करें और SDK शुरू करें```dart theme={null}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:didit_sdk/sdk_flutter.dart';

class VerifyButton extends StatefulWidget {
  const VerifyButton({super.key, required this.userId});
  final String userId;

  @override
  State<VerifyButton> createState() => _VerifyButtonState();
}

class _VerifyButtonState extends State<VerifyButton> {
  bool _loading = false;

  Future<void> _verify() async {
    setState(() => _loading = true);
    try {
      final resp = await http.post(
        Uri.parse('https://your-backend.example.com/api/verification/start'),
        headers: const {'Content-Type': 'application/json'},
        body: jsonEncode({'userId': widget.userId}),
      );
      final sessionToken = (jsonDecode(resp.body) as Map)['session_token'] as String;

      final result = await DiditSdk.startVerification(sessionToken);

      switch (result) {
        case VerificationCompleted(:final session):
          if (session.status == VerificationStatus.approved) {
            // Optimistic UI; rely on the webhook delivered to your backend as the source of truth.
          }
        case VerificationCancelled():
          // User dismissed the flow
          break;
        case VerificationFailed(:final error):
          // Show retry — error.type / error.message
          break;
      }
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _loading ? null : _verify,
      child: Text(_loading ? 'Starting...' : 'Verify identity'),
    );
  }
}
```### 3. बैकएंड: 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);
});
```HMAC हस्ताक्षर सत्यापन के विवरण के लिए [Webhooks गाइड](https://docs.didit.me/hi/integration/webhooks.md) देखें।***## पूरा उदाहरण```dart theme={null}
import 'package:flutter/material.dart';
import 'package:didit_sdk/sdk_flutter.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Didit SDK Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF1A1A1A)),
        useMaterial3: true,
      ),
      home: const VerificationScreen(),
    );
  }
}

class VerificationScreen extends StatefulWidget {
  const VerificationScreen({super.key});

  @override
  State<VerificationScreen> createState() => _VerificationScreenState();
}

class _VerificationScreenState extends State<VerificationScreen> {
  final _tokenController = TextEditingController();
  bool _loading = false;

  @override
  void dispose() {
    _tokenController.dispose();
    super.dispose();
  }

  Future<void> _startVerification() async {
    final token = _tokenController.text.trim();
    if (token.isEmpty) {
      _showAlert('Error', 'Please enter a session token.');
      return;
    }

    setState(() => _loading = true);

    try {
      final result = await DiditSdk.startVerification(
        token,
        config: const DiditConfig(loggingEnabled: true),
      );

      switch (result) {
        case VerificationCompleted(:final session):
          _showAlert(
            'Verification Complete',
            'Status: ${session.status.name}\nSession: ${session.sessionId}',
          );
        case VerificationCancelled():
          _showAlert('Cancelled', 'The user cancelled the verification.');
        case VerificationFailed(:final error):
          _showAlert('Failed', '${error.type.name}: ${error.message}');
      }
    } catch (e) {
      _showAlert('Error', 'Unexpected error: $e');
    } finally {
      setState(() => _loading = false);
    }
  }

  void _showAlert(String title, String message) {
    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text(title),
        content: Text(message),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx),
            child: const Text('OK'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              TextField(
                controller: _tokenController,
                decoration: InputDecoration(
                  hintText: 'Enter session token...',
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(8),
                  ),
                ),
                autocorrect: false,
              ),
              const SizedBox(height: 16),
              ElevatedButton(
                onPressed: _loading ? null : _startVerification,
                style: ElevatedButton.styleFrom(
                  backgroundColor: const Color(0xFF1A1A1A),
                  foregroundColor: Colors.white,
                  padding: const EdgeInsets.symmetric(vertical: 16),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(8),
                  ),
                ),
                child: _loading
                    ? const SizedBox(
                        height: 20,
                        width: 20,
                        child: CircularProgressIndicator(
                          strokeWidth: 2,
                          color: Colors.white,
                        ),
                      )
                    : const Text(
                        'Start Verification',
                        style: TextStyle(fontWeight: FontWeight.w600),
                      ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
```***


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