A Flutter SDK for identity verification with WebView integration. This SDK provides a simple way to add document and liveness verification to your Flutter application.
- π Secure: API key stays on your backend server
- π± Cross-platform: Works on Android and iOS
- π¨ Customizable: Configure base URL and other settings
- π Easy integration: Simple API with just a few lines of code
- πΈ Full verification: Document capture and liveness detection
Add this to your package's pubspec.yaml file:
dependencies:
flutter_verification_sdk: ^0.1.0Then run:
flutter pub get
flutter clean # Recommended to ensure proper manifest mergingThe SDK automatically includes required permissions and FileProvider configuration. However, verify your android/app/build.gradle has:
minSdkVersion 21Note: The SDK's AndroidManifest.xml automatically merges with your app's manifest, including:
- Camera, Internet, and Storage permissions
- FileProvider for camera capture (required by flutter_inappwebview)
If you encounter camera capture issues, ensure no conflicting FileProvider is defined in your app's manifest.
Add the following to your ios/Runner/Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is required for document and liveness verification</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access to upload document images</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location verification for identity confirmation</string>Important: Never include your API key in your mobile app. Always generate the verification ID on your secure backend server.
// Call YOUR backend endpoint
final response = await http.post(
Uri.parse('https://your-api.com/generate-verification'),
headers: {'Authorization': 'Bearer $yourAuthToken'},
);
final data = jsonDecode(response.body);
final verificationId = data['verificationId'];import 'package:flutter_verification_sdk/flutter_verification_sdk.dart';
final result = await VerificationSDK.startVerification(
context: context,
verificationId: verificationId,
config: VerificationConfig.production(), // Auto-closes after 2 seconds
);
// Handle the result
if (result.isSuccessful) {
print('Verification completed!');
print('Status: ${result.verificationStatus}');
// Update your UI, notify backend, navigate to next screen, etc.
} else if (result.wasCancelled) {
print('User cancelled');
} else if (result.hasError) {
print('Error: ${result.errorMessage}');
}// Production environment (auto-closes after 2 seconds)
VerificationConfig.production()
// Staging environment
VerificationConfig.staging()
// Custom configuration with auto-close
VerificationConfig(
baseUrl: 'https://your-custom-url.com',
debugMode: true,
timeout: Duration(minutes: 30),
autoClose: true, // Automatically close after completion
autoCloseDelay: Duration(seconds: 3), // Wait 3 seconds before closing
)
// Disable auto-close (user must manually close)
VerificationConfig(
baseUrl: 'https://verify.test.okid.io',
autoClose: false, // Stay on result screen, user closes manually
)By default, the SDK automatically closes the WebView 2 seconds after verification completes, allowing users to see the success/failure status briefly.
Options:
autoClose: true(default) - WebView closes automatically afterautoCloseDelayautoClose: false- WebView stays open on result screen, user closes manuallyautoCloseDelay- Duration to show result before auto-closing (default: 2 seconds)
The SDK uses 95% initial scale by default to ensure content fits without scrolling on mobile screens.
Options:
initialScale: 95(default) - 95% zoom, fits perfectly on most mobile screensinitialScale: 100- No scaling, may require slight scrolling on smaller screensinitialScale: 90- More compact, more space for smaller screens
VerificationConfig(
baseUrl: 'https://verify.test.okid.io',
initialScale: 100, // Use 100% if you prefer no scaling
)The VerificationResult object contains:
status: The outcome (completed, cancelled, error, expired)verificationId: The verification IDverificationStatus: Backend status (e.g., "verified", "rejected")errorMessage: Error details if status is errortimestamp: When the result was received
Convenience properties:
isSuccessful: True if verification completedwasCancelled: True if user cancelledhasError: True if an error occurredisExpired: True if session timed out
See the /example directory for a complete working example that demonstrates:
- Generating a verification ID
- Starting the verification flow
- Handling results
- Error handling
To run the example:
cd example
flutter pub get
flutter runYour backend server must provide an endpoint that generates verification IDs. See INTEGRATION.md for detailed backend implementation examples in various languages (Node.js, Python, PHP).
app.post('/api/mobile/generate-verification', async (req, res) => {
const response = await fetch('https://verify.test.okid.io/api/generate-verification', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-SDK-Key': process.env.OKID_API_KEY, // Your API key - server-side only!
},
body: JSON.stringify({
extra_data: {
user_id: req.user.id,
}
}),
});
const data = await response.json();
res.json({ verificationId: data.verificationId });
});- β DO generate verification IDs on your backend server
- β DO store your API key securely on your server
- β DO authenticate users before generating verification IDs
- β DON'T include your API key in your mobile app
- β DON'T call the verification API directly from your app
Android: The SDK automatically includes permissions. If camera still doesn't work:
- Check
android/app/build.gradlehasminSdkVersion 21or higher - Verify no conflicting FileProvider in your app's
AndroidManifest.xml - Run
flutter cleanand rebuild
iOS: Add camera usage descriptions to Info.plist (see Platform Setup above)
- Ensure you have internet permission
- Check that the base URL is correct
- Enable debug mode to see detailed logs:
config: VerificationConfig(
baseUrl: 'https://verify.test.okid.io',
debugMode: true,
)- Verify the verification ID is valid and not expired
- Check your backend is generating IDs correctly
- Ensure your API key is valid
This indicates FileProvider configuration issue:
- The SDK includes FileProvider automatically
- If you have a custom FileProvider in your app, ensure the authority is unique
- Check logs for
IllegalArgumentException: Couldn't find meta-data for provider - Run
flutter cleanto ensure manifest merging works correctly
For issues and questions:
- GitHub Issues: [Report an issue]
- Documentation: See
INTEGRATION.md - Example code: Check the
/exampledirectory
See LICENSE file for details.