Skip to main content
Version: 1.521.0

Usage

Basic Example​

import Trustchex from '@trustchex/react-native-sdk';

<Trustchex
baseUrl="https://your-api.com"
sessionId="session-123"
onCompleted={() => console.log('Done')}
onError={(error) => console.error(error)}
/>

Props​

PropTypeRequiredDescription
baseUrlstring✅Your API base URL
sessionIdstring❌Session identifier
brandingobject❌Colors and logo
locale'en' | 'tr'❌Language
onCompleted() => void❌Called when the verification process finishes
onError(error) => void❌Error callback
onDocumentRead(result: DocumentReadResult) => void❌Called when document is read (NFC or OCR)
skipNfcResultScreenboolean❌Skip the NFC document review screen and proceed automatically after a successful NFC scan. Default: false
skipSuccessScreenboolean❌Skip the final success screen and call onCompleted immediately when the process finishes. Default: false

Document Read Event​

The onDocumentRead callback fires as soon as document data is available — immediately after a successful NFC chip read or after a successful camera OCR scan. It receives a unified DocumentReadResult object regardless of source.

import Trustchex, { type DocumentReadResult } from '@trustchex/react-native-sdk';

<Trustchex
baseUrl="https://your-api.com"
sessionId="session-123"
onDocumentRead={(result: DocumentReadResult) => {
const { document } = result;

console.log(document.documentType); // "P" (passport) | "I" (ID card)
console.log(document.issuingCountry); // "DEU"
console.log(document.nationality); // "DEU"
console.log(document.documentNumber); // "C01X00T478"
console.log(document.personalNumber); // "8512310074" | null
console.log(document.lastName); // "MÜLLER"
console.log(document.firstName); // "JÜRGEN KARL"
console.log(document.sex); // "M" | "F" | "X" | "U"
console.log(document.dateOfBirth); // "1985-03-10" (ISO 8601)
console.log(document.dateOfExpiry); // "2030-11-05" (ISO 8601)
}}
onCompleted={() => console.log('Done')}
onError={(error) => console.error(error)}
/>

DocumentReadResult​

interface DocumentReadResult {
document: {
documentType: string; // "P" (passport) | "I" (ID card)
issuingCountry: string; // 3-letter ICAO country code, e.g. "TUR"
nationality: string;
documentNumber: string;
personalNumber: string | null;
lastName: string; // Best available name, e.g. "MÜLLER"
firstName: string; // Best available name, e.g. "JÜRGEN"
sex: 'M' | 'F' | 'X' | 'U';
dateOfBirth: string | null; // ISO 8601, e.g. "1990-05-15"
dateOfExpiry: string | null; // ISO 8601, e.g. "2028-03-01"
};
name: {
rawLast: string; // MRZ ASCII surname
rawFirst: string; // MRZ ASCII given name
displayLast: string; // Best Unicode form, e.g. "MÜLLER"
displayFirst: string; // Best Unicode form, e.g. "JÜRGEN"
source: 'dg11' | 'reverse_table' | 'raw';
};
face?: {
data: string; // Base64-encoded image
mimeType: string; // e.g. "image/jpeg"
};
}

Name Sources​

SourceDescription
dg11Exact printed name read from the NFC chip's DG11 file (UTF-8). Highest accuracy.
reverse_tableReconstructed via ICAO 9303 reverse transliteration (e.g. OE→Ö, UE→Ü). Applied for known countries.
rawNo conversion — display equals the raw MRZ ASCII value.

Flow Control​

Skip NFC Result Screen​

By default, after a successful NFC chip read the SDK shows a review screen where the user can verify their document data before proceeding. Set skipNfcResultScreen to bypass this screen entirely — the SDK advances automatically as soon as the NFC scan completes.

<Trustchex
baseUrl="https://your-api.com"
sessionId="session-123"
skipNfcResultScreen
onCompleted={() => console.log('Done')}
onError={(error) => console.error(error)}
/>

Use onDocumentRead alongside this prop if you need to access the scanned document data without showing the review screen.

Skip Success Screen​

By default, after the verification process completes the SDK shows a success animation for 3 seconds before calling onCompleted. Set skipSuccessScreen to call onCompleted immediately with no animation or delay.

<Trustchex
baseUrl="https://your-api.com"
sessionId="session-123"
skipSuccessScreen
onCompleted={() => {
// Called immediately when verification is complete
navigation.navigate('Home');
}}
onError={(error) => console.error(error)}
/>

Both props can be combined:

<Trustchex
baseUrl="https://your-api.com"
sessionId="session-123"
skipNfcResultScreen
skipSuccessScreen
onDocumentRead={(result) => console.log(result.name.displayFirst)}
onCompleted={() => navigation.navigate('Home')}
onError={(error) => console.error(error)}
/>

With Branding​

<Trustchex
baseUrl="https://your-api.com"
sessionId="session-123"
branding={{
logoUrl: 'https://your-logo.png',
primaryColor: '#1E40AF',
secondaryColor: '#F8FAFC',
tertiaryColor: '#DC2626'
}}
locale="en"
onCompleted={() => console.log('Done')}
/>

Deep link functionality is an optional feature if you want to publish a standalone app. To process deep links with the SDK, you need to configure deep links in your app and set up the required hooks to handle incoming URLs.

iOS - Add to Info.plist:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>yourapp</string>
</array>
</dict>
</array>

Android - Add to AndroidManifest.xml. Keep android:launchMode="singleTask" so a deep link that arrives while the app is already open is delivered to the existing activity instead of starting a new one:

<activity android:name=".MainActivity" android:launchMode="singleTask">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="yourapp" />
</intent-filter>
</activity>

Import and use the handleDeepLink function to process incoming URLs:

import React from 'react';
import { AppState, Linking } from 'react-native';
import Trustchex, { handleDeepLink } from '@trustchex/react-native-sdk';

const App = () => {
const appState = React.useRef(AppState.currentState);
const [baseUrl, setBaseUrl] = React.useState<string | undefined>();
const [sessionId, setSessionId] = React.useState<string>('');
const lastHandledUrl = React.useRef<string | null>(null);

const processDeepLink = React.useCallback((url: string | null) => {
// Ignore empty URLs and re-processing the same URL (getInitialURL returns
// the last intent on every foreground, so this would otherwise re-fire).
if (!url || url === lastHandledUrl.current) return;
const [bUrl, sId] = handleDeepLink({ url });
if (bUrl && sId) {
lastHandledUrl.current = url;
setBaseUrl(bUrl);
setSessionId(sId);
}
}, []);

React.useEffect(() => {
// Cold start (app launched by the link).
Linking.getInitialURL().then(processDeepLink);

// Warm start (link arrives while the app is running).
const urlSub = Linking.addEventListener('url', ({ url }) =>
processDeepLink(url)
);

// On Android's New Architecture (bridgeless) the warm-start 'url' event can
// be dropped ("Tried to access onNewIntent while context is not ready"), so
// re-read the launch intent whenever the app returns to the foreground to
// recover it. Requires the MainActivity.onNewIntent override below.
const appStateSub = AppState.addEventListener('change', (next) => {
if (appState.current.match(/inactive|background/) && next === 'active') {
Linking.getInitialURL().then(processDeepLink);
}
appState.current = next;
});

return () => {
urlSub.remove();
appStateSub.remove();
};
}, [processDeepLink]);

return (
<Trustchex
baseUrl={baseUrl}
sessionId={sessionId}
onCompleted={() => console.log('Done')}
onError={(error) => console.error(error)}
/>
);
};

A link that arrives while the app is already open needs a small native override on each platform. Without these, the link is silently dropped and the user stays on the first screen even though the JavaScript above is correct.

Android — override onNewIntent in your MainActivity to store the fresh intent, so Linking.getInitialURL() (used by the foreground re-check above) returns the new link rather than the original launch URL:

// MainActivity.kt
import android.content.Intent

override fun onNewIntent(intent: Intent) {
setIntent(intent)
super.onNewIntent(intent)
}

iOS — forward incoming URLs to RCTLinkingManager in your AppDelegate. This is what emits the JavaScript 'url' event while the app is running:

// AppDelegate.swift
import React // exposes RCTLinkingManager

func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
return RCTLinkingManager.application(app, open: url, options: options)
}

// Universal Links (https://…):
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
return RCTLinkingManager.application(
application, continue: userActivity, restorationHandler: restorationHandler)
}

The handleDeepLink function parses URLs with the format:

scheme://app-url/your-api.com/verification-session/session-123

And returns [baseUrl, sessionId] that you can use with the Trustchex component.

Sessions​

Create sessions using the REST API.

Session Access Methods​

The SDK provides multiple ways for users to access their verification session:

Users click a link that opens the app directly with the session:

// Deep link format: yourapp://app-url/your-api.com/verification-session/session-123
<Trustchex
baseUrl="https://your-api.com"
sessionId="session-123" // From deep link
onCompleted={() => console.log('Done')}
/>

Benefits:

  • Seamless user experience - one tap to start
  • Direct navigation to verification
  • No manual input required
  • Works great for email and SMS campaigns

Users scan a QR code that contains the session information. The SDK includes a built-in QR scanner accessible from the welcome screen.

Benefits:

  • Quick and contactless
  • No typing required
  • Ideal for in-person verification
  • Built-in scanner included in SDK

3. Session Code Entry (Alternative)​

Users can manually enter an 8-character alphanumeric code:

<Trustchex
baseUrl="https://your-api.com"
// No sessionId prop needed - user enters code manually
onCompleted={() => console.log('Done')}
/>

When no sessionId is provided, the SDK displays a screen where users can:

  • Enter the 8-character session code
  • Scan a QR code

Use Cases:

  • Fallback when QR/deep link unavailable
  • Phone/voice support scenarios
  • Print media without QR capability

Creating Sessions​

When creating a session via the REST API, you'll receive access methods in the response:

const response = await fetch('https://your-api.com/api/v1/verification-sessions', {
method: 'POST',
headers: { 'x-api-key': 'YOUR_API_KEY' },
body: JSON.stringify({
workflowId: 'workflow-123',
email: 'user@example.com'
})
});

const { deepLink, qrCodeLink, sessionCode } = await response.json();

// Use deepLink for direct app navigation (recommended)
// Use qrCodeLink to generate QR code (recommended)
// Use sessionCode as alternative access method