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

# React Native KYC SDK：モバイル本人確認

> DiditのReact Native・Expo向けKYC SDK。TypeScript対応、iOS・Androidネイティブ、NFC電子パスポート読み取りに対応。フルKYCは1件$0.33から、毎月$10無料、契約不要。



React Native SDK連携用プロンプト
        プロンプトをクリップボードにコピー



      
      

\<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.9.1)

\## 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.9.1/DiditSDK.podspec'
The tag in that URL must equal diditNativeSdkVersions.ios in the package (4.9.1); 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>



      
      

貼り付け先

ネイティブのiOS SDKとAndroid SDKをラップし、本人確認のための統一されたTypeScript APIを提供するクロスプラットフォームのReact Native SDKです。> [card] [GitHubリポジトリ](https://github.com/didit-protocol/sdk-react-native)
>
> GitHubでソースコードとサンプルを確認する> [card] [npmパッケージ](https://www.npmjs.com/package/@didit-protocol/sdk-react-native)
>
> @didit-protocol/sdk-react-native> [!NOTE]
>
> ### **ネイティブSDK**: React NativeアプリとExpoアプリには、この方法を推奨します。このSDKはネイティブのiOS SDKとAndroid SDKをラップしており、最良のユーザー体験、最適化されたカメラ処理、完全なNFCサポートを提供します。***## 要件| 要件 | 最小バージョン |
| - | - |
| React Native | 0.76+ (New Architecture / TurboModules) |
| Node.js | 20+ |
| TypeScript | 5+ |### プラットフォーム要件| プラットフォーム | 最小バージョン | 備考 |
| - | - | - |
| iOS | 13.0+ | NFCによるパスポート読み取りにはiOS 15.0+が必要です |
| Android | API 24+ (7.0) | Kotlin 1.9+、Java 17+ |> [!NOTE]
>
> **生体認証への同意にはネイティブSDK 4.10.0以降が必要です。** イリノイ州、テキサス州、コロラド州の法律が適用される人については、Diditは最初の顔撮影の前に明示的な[生体認証への同意](https://docs.didit.me/ja/getting-started/biometric-consent.md)を求めることができます。ネイティブのiOSおよびAndroid SDKを4.10.0以降に固定したReact Native SDKのリリースでは、このステップが表示されます。それより前のバージョンではこのステップを表示できません。セッションは従来どおり実行され、判定では同意が取得されていないものとして報告されます(`biometric_consent.reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`)。これらの州の人を認証する場合はアップグレードしてください。***## インストール### Expo(推奨)```bash theme={null}
npx expo install @didit-protocol/sdk-react-native
```次に、`app.json`(または`app.config.js`)にconfig pluginを追加します。NFCはデフォルトで有効です。```json theme={null}
{
  "expo": {
    "plugins": ["@didit-protocol/sdk-react-native"]
  }
}
```このプラグインは両方のプラットフォームを自動的に設定します。- **Android:** GradleにDidit Mavenリポジトリを追加し、Gradleプロパティ`diditSdkAndroidNfcEnabled`を設定し、BouncyCastleの依存関係とパッケージングのルールを適用します
- **iOS:** PodfileにDiditSDKのpodspecを追加します(NFCが有効な場合はiOS 15に固定されます)このプラグインは`Info.plist`を編集しません。同じファイルの`ios.infoPlist`に、[iOSの権限キー](#ios)と、NFCを使う場合はISO7816のselect identifiersを追加してください。`D392F000260100000001`により、SDKは[JPKI](https://docs.didit.me/ja/core-technology/nfc-verification/overview.md#日本のマイナンバーカード-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"
        ]
      }
    }
  }
}
```#### NFC依存関係の無効化NFCサポートなしでビルドする場合(バイナリが小さくなり、NFC capabilityも不要になります)は、プラグインオプションを指定します。```json theme={null}
{
  "expo": {
    "plugins": [
      [
        "@didit-protocol/sdk-react-native",
        { "iosNfcEnabled": false, "androidNfcEnabled": false }
      ]
    ]
  }
}
```NFCを無効にした場合、iOSのNFC capability、NFC entitlement、NFC関連のプロビジョニング設定は不要です。> [!WARNING]
>
> このSDKは**Expo Goでは利用できない**ネイティブモジュール(カメラ、NFC)を使用します。[development build](https://docs.expo.dev/develop/development-builds/introduction/)を使用するか、`npx expo prebuild`を実行してネイティブプロジェクトを生成する必要があります。### React Native CLI```bash theme={null}
npm install @didit-protocol/sdk-react-native
# or
yarn add @didit-protocol/sdk-react-native
```#### iOSのセットアップ`Podfile`にDiditSDKのpodを追加します(CocoaPods trunkには公開されていません)。以下のブロックは環境変数`DIDIT_SDK_IOS_NFC_ENABLED`を参照するため、インストール時にNFCなしのsubspec(`DiditSDK/Core`)に切り替えられます。```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.9.1/DiditSDK.podspec'
```> [!WARNING]
>
> podspec URLのタグは、インストールしたパッケージバージョンの`diditNativeSdkVersions.ios`と一致している必要があります。
> React Native `4.9.1`はネイティブiOS `4.9.1`とネイティブAndroid `4.9.1`に固定されています。podspecの参照先を
> `main`にしないでください。パッケージはそのネイティブiOSバージョンに厳密に依存しているため、`main`が先に進んだ時点でCocoaPodsは
> `DiditSDK`に対して互換性のない2つの要件を検出し、すべての`pod install`が失敗します。Expoのconfig pluginはこのURLを自動的に生成します。手動で記述する必要があるのは、
> 素のReact Native CLIを使う場合のみです。次に依存関係をインストールします。```bash theme={null}
cd ios
bundle exec pod install
```NFC依存関係なしで再ビルドするには、CocoaPodsをクリーンアップし、環境変数を設定して再実行します。```bash theme={null}
cd ios
rm -rf Pods Podfile.lock
DIDIT_SDK_IOS_NFC_ENABLED=false bundle exec pod install
```#### Androidのセットアッププロジェクトレベルの`settings.gradle`にDidit Mavenリポジトリを追加します。```groovy theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url "https://raw.githubusercontent.com/didit-protocol/sdk-android/main/repository" }
    }
}
```アプリの`android/app/build.gradle`(`android { ... }`ブロック内)に以下を追加し、DiditSDKの推移的依存関係によって発生しうるBouncyCastleのクラス重複の競合と、OSGIの`MANIFEST.MF`の重複を解消します。```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'
        }
    }
}
```Android NFC依存関係なしでビルドする場合(`me.didit:didit-sdk`の代わりに`me.didit:didit-sdk-core`アーティファクトを使用します)は、`android/gradle.properties`に以下を追加します。```properties theme={null}
diditSdkAndroidNfcEnabled=false
```NFC対応の完全なAndroid SDKを使用するには、このプロパティを削除するか、`true`に設定してください。***## 権限### iOSアプリの`Info.plist`に以下のキーを追加してください。必須のiOSプライバシーキーが不足していると、SDKが該当する保護リソースにアクセスした時点でiOSがアプリを強制終了します。| 権限 | Info.plistキー | 説明 | 必須 |
| - | - | - | - |
| カメラ | `NSCameraUsageDescription` | 書類のスキャンと顔認証 | 必須 |
| マイク | `NSMicrophoneUsageDescription` | ライブネス動画の録画 | 必須 |
| フォトライブラリ | `NSPhotoLibraryUsageDescription` | 書類画像のアップロード | 必須 |
| 位置情報 | `NSLocationWhenInUseUsageDescription` | 不正防止のための位置情報取得 | 必須 |
| NFC | `NFCReaderUsageDescription` | パスポートや身分証明書のNFCチップの読み取り | NFC使用時 |```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>
```#### NFCの設定チップ付きのパスポートや身分証明書のNFC読み取りを有効にするには、次の手順を行います。1) Xcodeで**NFC Capabilityを追加**します。
   * ターゲットを選択 > **Signing & Capabilities** > **+ Capability** > **Near Field Communication Tag Reading**

2) `Info.plist`に**ISO7816識別子を追加**します。```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/ja/core-technology/nfc-verification/overview.md#日本のマイナンバーカード-jpki)を通じて日本のマイナンバーカードを読み取れるようになります。この識別子がない場合、iOSはカードをSDKに通知しません。マイナンバーカードの読み取りは本番環境ではまだ有効になっていませんが、この識別子は他の書類には何の影響もないため、今のうちに追加しておいても問題ありません。3) NFCタグ読み取りを有効にした**entitlementsファイルを追加**します。```xml theme={null}
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>TAG</string>
</array>
```アプリのプロビジョニングプロファイルにNFC Tag Reading capabilityが含まれていることを確認してください。NFCを無効にしている場合、このNFC設定は不要です。### Android以下の権限はSDKの`AndroidManifest.xml`で宣言されており、自動的にマージされます。| 権限 | 説明 | 必須 |
| - | - | - |
| `INTERNET` | API通信のためのネットワークアクセス | 必須 |
| `ACCESS_NETWORK_STATE` | ネットワークの利用可否の検出 | 必須 |
| `CAMERA` | 書類のスキャンと顔認証 | 必須 |
| `NFC` | パスポートや身分証明書のNFCチップの読み取り | NFC使用時 |カメラとNFCのハードウェア機能はオプション(`android:required="false"`)として宣言されているため、これらの機能を備えていないデバイスにもアプリをインストールできます。***## クイックスタート```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;
}
```***## 連携方法SDKは2つの連携方法に対応しています。### 方法1: セッショントークン(本番環境での推奨方法)[Create Verification Session API](https://docs.didit.me/ja/sessions-api/create-session.md)を使ってバックエンドでセッションを作成し、そのトークンを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);
```この方法では、次の項目を完全に制御できます。- セッションとユーザーの関連付け(`vendor_data`)
- カスタムメタデータの設定
- セッションごとのコールバックの設定### 方法2: ワークフローID(より簡単な連携)より簡単に連携したい場合は、ワークフローIDを使ってSDKから直接セッションを作成できます。```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 },
});
```***## 設定`DiditConfig`オブジェクトを渡すことで、SDKの動作をカスタマイズできます。```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
});
````startVerificationWithWorkflow`の場合は、`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,
  },
});
```### 設定オプション| プロパティ | 型 | デフォルト | 説明 |
| - | - | - | - |
| `languageCode` | `string` | デバイスのロケール | ISO 639-1言語コード(例: `"en"`、`"fr"`、`"ar"`) |
| `showLanguageSelector` | `boolean` | `false` | ウェルカム画面にWeb版と同様の言語セレクターを表示する |
| `fontFamily` | `string` | システムフォント | カスタムフォントファミリー名(ネイティブ側で登録されている必要があります) |
| `loggingEnabled` | `boolean` | `false` | SDKのデバッグログを有効にする |
| `showCloseButton` | `boolean` | `true` | 認証ステップの画面に閉じる(X)ボタンを表示する |
| `showExitConfirmation` | `boolean` | `true` | ユーザーが終了しようとしたときに確認ダイアログを表示する |
| `closeOnComplete` | `boolean` | `false` | 認証完了時に認証UIを自動的に閉じる |
| `defaultDocumentCamera` | `CameraLens?` | ネイティブのデフォルト(`CameraLens.Back`) | 書類撮影画面を開いたときに使用するレンズ |
| `defaultLivenessCamera` | `CameraLens?` | ネイティブのデフォルト(`CameraLens.Front`) | 顔(ライブネス)撮影画面を開いたときに使用するレンズ |
| `showDocumentCameraSwitchButton` | `boolean` | `true` | 書類撮影画面に撮影中のカメラ切り替えボタンを表示する |
| `showLivenessCameraSwitchButton` | `boolean` | `true` | 顔撮影画面に撮影中のカメラ切り替えボタンを表示する |### カメラオプションカメラオプションは[Web SDKのカメラオプション](https://docs.didit.me/ja/integration/web-sdks/javascript-sdk.md#カメラオプション)と同じです。
レンズには`CameraLens.Front`または`CameraLens.Back`を指定します。
指定したレンズがデバイスにない場合、SDKはデバイスで利用可能な最初のカメラを使用します。
カメラが1台しかないデバイスでは、カメラ切り替えボタンも非表示になります。
切り替えボタンのオプションを`false`に設定すると、ユーザーはそのステップのデフォルトのレンズに固定されます。```tsx theme={null}
import { startVerification, CameraLens } from '@didit-protocol/sdk-react-native';

await startVerification('your-session-token', {
  defaultLivenessCamera: CameraLens.Back,
  showLivenessCameraSwitchButton: false,
});
```> [!NOTE]
>
> **テーマとカラー**: カラー、背景、イントロ画面の設定は、SDKの設定ではなく、Didit Consoleの[ホワイトラベル設定](https://business.didit.me)で行います。これにより、すべてのプラットフォームで一貫したブランディングが保たれます。***## 言語サポートSDKは**54言語**に対応しています。言語が指定されていない場合、SDKはデバイスのロケールを使用し、フォールバックとして英語を使用します。```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 });
```**[対応言語の一覧を見る →](https://docs.didit.me/ja/integration/supported-languages.md)*****## 高度なオプションこれらのオプションは、SDKがお客様に代わってセッションを作成する`startVerificationWithWorkflow`でのみ利用できます。### 連絡先情報（事前入力と通知）連絡先情報を指定すると、認証フォームへの事前入力とメール通知が有効になります。```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
  },
});
```### 想定情報（クロスバリデーション）想定されるユーザー情報を指定すると、書類から抽出したデータとの自動クロスバリデーションが行われます。```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
  },
});
````ExpectedDetails`のフィールドはすべて任意です。完全な型定義は[`src/types.ts`](https://github.com/didit-protocol/sdk-react-native/blob/main/src/types.ts)を参照してください。### カスタムメタデータカスタムJSONメタデータをセッションに保存できます（ユーザーには表示されません）。```tsx theme={null}
const result = await startVerificationWithWorkflow('your-workflow-id', {
  vendorData: 'user-123',
  metadata: '{"internalId": "abc123", "source": "mobile-app"}',
});
```***## 結果の処理`startVerification`と`startVerificationWithWorkflow`はどちらも`Promise<VerificationResult>`を返します。結果は判別共用体であり、`type`フィールドで結果の種類を判定します。### 結果のケース| ケース | 説明 |
| - | - |
| `completed` | 検証フローが完了しました（結果は`session.status`で確認します） |
| `cancelled` | ユーザーが検証フローをキャンセルしました |
| `failed` | 検証中にエラーが発生しました |### SessionDataのプロパティ| プロパティ | 型 | 説明 |
| - | - | - |
| `sessionId` | `string` | 一意のセッション識別子 |
| `status` | `VerificationStatus` | `Approved`、`Pending`、`Declined`のいずれか |### エラーの種類| エラー | 説明 |
| - | - |
| `sessionExpired` | セッションの有効期限が切れています |
| `networkError` | ネットワーク接続の問題 |
| `cameraAccessDenied` | カメラの権限が許可されていません |
| `notInitialized` | SDKが初期化されていません（Androidのみ） |
| `apiError` | APIリクエストが失敗しました |
| `unknown` | メッセージ付きのその他のエラー |### 接続が切れた場合検証中にデバイスの接続が切れると、SDKはステップを読み込み中のまま放置せず、フローを覆う「No internet connection」画面を表示します。
SDKはバックグラウンドで接続の確認を続け、Diditに再び接続できるようになるとすぐに自動で画面を閉じます。ユーザーは中断したステップから続行できます。
この画面には**Try Again**が表示され、`showCloseButton`が`true`（デフォルト）の場合は**Exit Verification**も表示されます。
終了すると、検証はエラーが`networkError`の`failed`結果で終わるため、アプリはユーザーが接続の問題で離脱したことを把握できます。### 結果処理の完全な例```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;
  }
}
```***## エンドツーエンドの例 (バックエンドのセッション → React Native SDK → Webhook)本番環境向けの連携では、バックエンドがセッションを作成し、React Nativeアプリが`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. React Nativeでトークンをやりとりして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. バックエンドで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署名検証の詳細は[Webhookガイド](https://docs.didit.me/ja/integration/webhooks.md)を参照してください。***## 完全な例```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.