- Overview
- Getting started
- Handling callbacks
- Customising SDK
- Creating checks
- User Analytics
- Going live
- Cross platform frameworks
- Migrating
- Security
- Accessibility
- Getting notified about releases
- Licensing
- More information
This SDK provides a drop-in set of screens and tools for Android applications to allow capturing of identity documents and face photos/live videos for the purpose of identity verification. The SDK offers a number of benefits to help you create the best onboarding/identity verification experience for your customers:
- Carefully designed UI to guide your customers through the entire photo/video-capturing process
- Modular design to help you seamlessly integrate the photo/video-capturing process into your application flow
- Advanced image quality detection technology to ensure the quality of the captured images meets the requirement of the Onfido identity verification process, guaranteeing the best success rate
- Direct image upload to the Onfido service, to simplify integration*
* Note: the SDK is only responsible for capturing and uploading photos/videos. You still need to access the Onfido API to create and manage checks.
The SDK supports API level 21 and above (distribution stats).
Version 7.4.0 was the last version that supports API level 16 and above.
Our configuration is currently set to the following:
minSdkVersion = 21
compileSdkVersion = 28
targetSdkVersion = 28
android.useAndroidX=true
Kotlin = 1.3+
In order to start integration, you will need the API token. You can use our sandbox environment to test your integration, and you will find these two sandbox tokens inside your Onfido Dashboard. You can create sandbox tokens inside your Onfido Dashboard.
Onfidoย offersย region-specificย environments.ย Referย toย theย Regionsย sectionย inย theย APIย documentationย forย tokenย formatย andย APIย baseย URLย information.
Starting on version 4.2.0
, we now offer a modularised SDK, which means you can integrate it in two different ways:
Complete, input quality-focused solution suited for better captures and faster IDV flows. This is the recommended integrated option. This version provides advanced on-device, real-time glare and blur detection as well as auto-capture (passport only) on top of a set of basic image validations.
repositories {
jcenter()
}
dependencies {
implementation 'com.onfido.sdk.capture:onfido-capture-sdk:+'
}
Due to the advanced validation support stated above, in the form of C++ code, we recommend that the integrator app performs multi-APK split to optimise the app size for individual architectures.
C++ code needs to be compiled for each of the CPU architectures (known as "ABIs") present on the Android environment. Currently, the SDK supports the following ABIs:
armeabi-v7a
: Version 7 or higher of the ARM processor. Most recent Android phones use thisarm64-v8a
: 64-bit ARM processors. Found on new generation devicesx86
: Most tablets and emulatorsx86_64
: Used by 64-bit tablets
The SDK binary contains a copy of the native .so
file for each of these four platforms.
You can considerably reduce the size of your .apk
by applying APK split by ABI, editing your build.gradle
as the following:
android {
splits {
abi {
enable true
reset()
include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a'
universalApk false
}
}
}
More information on the Android documentation
Average size (with Proguard enabled):
ABI | Size |
---|---|
armeabi-v7a | 6.30 Mb |
arm64-v8a | 7.33 Mb |
Lighter, app size-friendly version. This version provides a set of basic image validations mostly provided by the backend. Since there are no real-time validations on-device, ABI split is not needed.
repositories {
jcenter()
}
dependencies {
implementation 'com.onfido.sdk.capture:onfido-capture-sdk-core:+'
}
Average size (with Proguard enabled):
ABI | Size |
---|---|
universal | 3.84 Mb |
The sizes stated above were measured by building the minimum possible wrappers around our SDK, using the following stack. Different versions of dependencies such as Gradle or NDK may result in slightly different values.
Notes:
Until these packages get approved to be included in JCenter, the following snippet must be used to instruct gradle to search for them on Bintray:
repositories {
maven {
url "https://dl.bintray.com/onfido/maven"
}
}
Warning: In order to improve the security of our clients, we upgraded our infrastructure and SDK client SSL configurations to support TLSv1.2 only. According to the relevant Google documentation, this support comes enabled by default on every device running Android API 20+. In case you need to support devices older than that in your integration with the Onfido Android SDK, we need to access Google Play Services to install the latest security updates, which enable this support. As such, if you don't use Google Play Services on your integration yet, we require you to add the following dependency:
compile ('com.google.android.gms:play-services-base:x.y.z') {
exclude group: 'com.android.support' // to avoid conflicts with your current support library
}
You must create an Onfido applicant before you start the flow.
You must create applicants on your server. For a document or face check, the minimum applicant details required are first_name
and last_name
:
$ curl https://api.onfido.com/v3/applicants \
-H 'Authorization: Token token=YOUR_API_TOKEN' \
-d 'first_name=Theresa' \
-d 'last_name=May'
The JSON response has an id
field containing an UUID that identifies the applicant. Once you pass the applicant ID to the SDK, documents and live photos/videos uploaded by that instance of the SDK will be associated with that applicant.
Note: If you're using API v2, please check out API v2 to v3 migration guide to understand which changes need to be applied before starting to use API v3.
We now support two token mechanisms:
SDK token
Mobile token
We strongly recommend using a SDK token. It provides a more secure means of integration, as the token is temporary and applicant id-bound. Note that, if you're using an SDK token, you shouldn't call withApplicantId function.
You will need to generate and include a short-lived JSON Web Token (JWT) every time you initialise the SDK. To generate an SDK Token you should perform a request to the SDK Token endpoint in the Onfido API:
$ curl https://api.onfido.com/v3/sdk_token \
-H 'Authorization: Token token=YOUR_API_TOKEN' \
-F 'applicant_id=YOUR_APPLICANT_ID' \
-F 'application_id=YOUR_APPLICATION_ID'
Make a note of the token value in the response, as you will need it later on when initialising the SDK.
Warning: SDK tokens expire 90 minutes after creation. The SDK token configurator function has an optional tokenExpirationHandler
parameter. It will be called when sdk token expires and you can use it to pass a new one.
Note: If you're using API v2, please check out API v2 to v3 migration guide to understand which changes need to be applied before starting to use API v3.
class ExpirationHandler : TokenExpirationHandler {
override fun refreshToken(injectNewToken: (String?) -> Unit) {
TODO("Your network request logic to retrieve SDK token goes here")
injectNewToken("NEW_SDK_TOKEN") // if you pass `null` sdk exit with token expired error
}
}
val config = OnfidoConfig.builder(context)
.withSDKToken("YOUR_SDK_TOKEN_HERE", tokenExpirationHandler = ExpirationHandler()) // ExpirationHandler is optional
class ExpirationHandler implements TokenExpirationHandler {
@Override
public void refreshToken(@NotNull Function1<? super String, Unit> injectNewToken) {
//Your network request logic to retrieve SDK token goes here
injectNewToken.invoke("NEW_SDK_TOKEN"); // if you pass `null` sdk exit with token expired error
}
}
OnfidoConfig.Builder config = new OnfidoConfig.Builder(context)
.withSDKToken("YOUR_SDK_TOKEN", new ExpirationHandler()); // ExpirationHandler is optional
Note: If you want to use tokenExpirationHandler
you should pass concrete class instance, you should not pass an anonymous or activity class instance.
Note: Mobile token usage is still supported, but it will be removed in the future. If you are starting a project, we would strongly recommend that you use SDK tokens instead.
In order to start integration, you will need the API token and the mobile token. You can use our sandbox environment to test your integration, and you will find these two sandbox tokens inside your Onfido Dashboard.
Warning: You MUST use the mobile token and not the API token when configuring the SDK itself.
val config = OnfidoConfig.builder(context)
.withToken("YOUR_MOBILE_TOKEN_HERE")
.withApplicant("YOUR_APPLICANT_ID_HERE")
OnfidoConfig.Builder config = new OnfidoConfig.Builder(this)
.withToken("YOUR_MOBILE_TOKEN_HERE")
.withApplicant("YOUR_APPLICANT_ID_HERE");
To use the SDK, you need to obtain an instance of the client object:
final Context context = ...;
Onfido onfido = OnfidoFactory.create(context).getClient();
// start the flow. 1 should be your request code (customise as needed)
onfido.startActivityForResult(this, /*must be an Activity or Fragment (support library)*/
1, /*this request code will be important for you on onActivityResult() to identity the onfido callback*/
config);
Congratulations! You have successfully started the flow. Carry on reading the next sections to learn how to:
- Handle callbacks
- Customise the SDK
- Create checks
To receive the result from the flow, you should override the method onActivityResult
on your Activity/Fragment. Typically, on success, you would create a check on your backend server.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
...
onfido.handleActivityResult(resultCode, data, new Onfido.OnfidoResultListener() {
@Override
public void userCompleted(Captures captures) {
//communicate with your backend and initiate the check
}
@Override
public void userExited(ExitCode exitCode) {
//User left the sdk flow without completing it
}
@Override
public void onError(OnfidoException exception) {
// An exception occurred during the flow
}
});
}
When the user has successfully completed the flow, and the captured photos/videos have been uploaded, the userCompleted
method will be invoked. The Captures
object contains information about the document and face captures made during the flow.
With the applicant id, you can then create a check for the user via your backend. On the other hand, if the user exits the flow without completing it, the userExited
method will be invoked. Note that some images may have already been uploaded by this stage.
Sample of a Captures
instance returned by a flow with FlowStep.CAPTURE_DOCUMENT
and FlowStep.CAPTURE_FACE
:
Document:
Front: DocumentSide(id=document_id, side=FRONT, type=DRIVING_LICENCE)
Back: DocumentSide(id=document_id, side=BACK, type=DRIVING_LICENCE)
Type: DRIVING_LICENCE
Face:
Face(id=face_id, variant=PHOTO)
Note type
property refers to DocumentType
, variant refers to FaceCaptureVariant
As part of userCompleted
method, the DocumentType
property can only contain the values which are supported by Onfido backend APIs. Please check out our API documentation
You can customise the flow of the SDK via the withCustomFlow(FlowStep[])
method. You can remove, add and shift around steps of the SDK flow.
final FlowStep[] defaultStepsWithWelcomeScreen = new FlowStep[]{
FlowStep.WELCOME, //Welcome step with a step summary, Optional
FlowStep.CAPTURE_DOCUMENT, //Document Capture Step
FlowStep.CAPTURE_FACE, //Face Capture Step
FlowStep.FINAL //Final Screen Step, Optional
};
final OnfidoConfig config = OnfidoConfig.builder()
.withCustomFlow(defaultStepsWithWelcomeScreen)
.withSDKToken("YOUR_SDK_TOKEN")
.build();
Also, by calling the exitWhenSentToBackground()
method of the OnfidoConfig.Builder
, you can determine that the flow should be exited whenever the user sends the app to background.
This exit action will invoke the userExited(ExitCode exitCode)
callback described in the handling callbacks section.
In this step the user can pick which type of document to capture, the document origin country, and then use the phone camera to capture it.
To customise a document capture step you can use DocumentCaptureStepBuilder
class's functions for the corresponding document types.
Document Type | Configuration function | Configurable Properties |
---|---|---|
Passport | forPassport() | |
National Identity Card | forNationalIdentity() | - country - documentFormat |
Driving Licence | forDrivingLicence() | - country - documentFormat |
Residence Permit | forDrivingLicence() | - country |
Visa | forVisa() | - country |
Work Permit | forWorkPermit() | - country |
Generic | forGenericDocument() | - country |
Note GENERIC
document type doesn't offer an optimised capture experience for a desired document type.
This configuration allows you to specify country of origin of document
Note: You can specify country for all document types except Passport.
If you would like to specify country for driving license
FlowStep drivingLicenceCaptureStep = DocumentCaptureStepBuilder.forDrivingLicence()
.withCountry(CountryCode.GB)
.build();
val drivingLicenceCaptureStep = DocumentCaptureStepBuilder.forDrivingLicence()
.withCountry(CountryCode.GB)
.build()
This configuration allows you to specify format of document such as Card and Folded
Note: You can specify folded document format for only French driving licence, South African national identity and Italian national identity. If you would configure the SDK with unsupported
country configuration the SDK will throw InvalidDocumentFormatAndCountryCombinationException
If you would like to specify country and document format for driving license
FlowStep drivingLicenceCaptureStep = DocumentCaptureStepBuilder.forDrivingLicence()
.withCountry(CountryCode.FR)
.withDocumentFormat(DocumentFormat.FOLDED)
.build();
val drivingLicenceCaptureStep = DocumentCaptureStepBuilder.forDrivingLicence()
.withCountry(CountryCode.FR)
.withDocumentFormat(DocumentFormat.FOLDED)
.build()
Please be aware that we don't support every document - country combination, and unsupported documents will not be verified. So if you decide to bypass the default country selection screen by replacing the FlowStep.CAPTURE_DOCUMENT
with a CaptureScreenStep
, please make sure that you are specifying a supported document.
We provide an up-to-date list of the documents we support here
In this step the user is presented with a summary of the capture steps he/she is about to pass through.
In this step the user can capture either a photo of his/her face, or a live video by using the front camera. In case of choosing the second option,
the user will be prompted to perform some simple challenges. The photo option can be instantiated with FlowStep.CAPTURE_FACE
or
FaceCaptureStepBuilder.forPhoto()
and the video option with FaceCaptureStepBuilder.forVideo()
.
By default both face and video variants show an introduction screen. You can disable the intro using withIntro(false)
function.
FlowStep faceCaptureStep = FaceCaptureStepBuilder.forVideo()
.withIntro(false)
.build();
If you would like to not display the recorded video on the confirmation screen, you could hide it using withConfirmationVideoPreview
function.
FlowStep faceCaptureStep = FaceCaptureStepBuilder.forVideo()
.withConfirmationVideoPreview(false)
.build();
In case both types of FaceCaptureStep
are added to the same custom flow, a custom IllegalArgumentException
will be thrown at the beginning of the flow,
with the message "Custom flow cannot contain both video and photo variants of face capture"
.
It should be used at the end of the flow, but it's not necessary.
It explains to the user the purpose of the identity verification flow.
In order to enhance the user experience on the transition between your application and the SDK, you can provide some customisation by defining certain colors inside your own colors.xml
file:
onfidoColorPrimary
: Defines the background color of the Toolbar
which guides the user through the flow
onfidoColorPrimaryDark
: Defines the color of the status bar above the Toolbar
onfidoTextColorPrimary
: Defines the color of the title on the Toolbar
onfidoTextColorSecondary
: Defines the color of the subtitle on the Toolbar
onfidoColorAccent
: Defines the color of the FloatingActionButton
which allows the user to move between steps, as well as some details on the
alert dialogs shown during the flow
onfidoPrimaryButtonColor
: Defines the background color of the primary action buttons (e.g. proceed to the next flow step, confirm picture/video, etc),
the color of the text on the secondary action buttons (e.g. retake picture/video) and the background color of some icons and markers during the flow
onfidoPrimaryButtonColorPressed
: Defines the background color of the primary action buttons when pressed
onfidoPrimaryButtonTextColor
: Defines the color of the text inside the primary action buttons
Onfido Android SDK already comes with out-of-the-box translations for the following locales:
- English (en) ๐ฌ๐ง
- Spanish (es) ๐ช๐ธ
- French (fr) ๐ซ๐ท
- German (de) ๐ฉ๐ช
You could also provide custom translations for locales that we don't currently support, by having an additional XML strings file inside your resources folder for the desired locale (e.g. res/values-it/onfido_strings.xml
for ๐ฎ๐น translation), with the content of our strings.xml file, translated for that locale.
By default, we infer the language to use from the device settings.
However, you can also use the withLocale(Locale)
method of the OnfidoConfig.Builder
to select a specific language.
Notes:
- If the strings translations change it will result in a MINOR version change, therefore you are responsible for testing your translated layout in case you are using this feature. If you want a locale translated you can also get in touch with us at [email protected].
- When adding custom translations, please make sure you add the whole set of keys we have on strings.xml.
In particular,
onfido_locale
, which identifies the current locale being added, must be included. The value for this string should be the ISO 639-1 2-letter language code corresponding to the translation being added. Examples:- When adding a translations file inside
values-ru
(russian translation), theonfido_locale
key should haveru
as its value. - When adding a translations file inside
values-en-rUS
(american english translation), theonfido_locale
key should haveen
as its value.
- When adding a translations file inside
Without this string correctly translated, we won't be able to determine which language the user is likely to use when doing the video liveness challenge. It may result in our inability to correctly process the video, and the check may fail.
As the SDK is only responsible for capturing and uploading photos/videos, you would need to start a check on your backend server using the Onfido API.
All API requests must be made with an API token included in the request headers. You can find your API token (not to be mistaken with the mobile token) inside your Onfido Dashboard.
Refer to the Authentication section in the API documentation for details. For testing, you should be using the sandbox, and not the live, token.
You will need to create a check by making a request to the create check endpoint, using the applicant id. If you are just verifying a document, you only have to include a document report as part of the check. On the other hand, if you are verifying a document and a face photo/live video, you will also have to include a facial similarity report with the corresponding values: facial_similarity_photo
for the photo option and facial_similarity_video
for the video option.
$ curl https://api.onfido.com/v3/checks \
-H 'Authorization: Token token=YOUR_API_TOKEN' \
-d 'applicant_id=YOUR_APPLICANT_ID' \
-d 'report_names=[document,facial_similarity_photo]'
Note: you can also submit the POST request in JSON format.
You will receive a response containing the check id instantly. As document and facial similarity reports do not always return actual results straightaway, you need to set up a webhook to get notified when the results are ready.
Finally, as you are testing with the sandbox token, please be aware that the results are pre-determined. You can learn more about sandbox responses here.
Note: If you're using API v2, please check out API v2 to v3 migration guide to understand which changes need to be applied before starting to use API v3.
Refer to the Webhooks section in the API documentation for details.
The SDK allows you to track the user's journey through the verification process via an overrideable hook. This is meant to give some insight into how your user's make use of the SDK screens.
In order to expose the user's progress through the SDK an hook method must be overridden in the UserEventHandler.kt
object that's stored in the Onfido.kt
interface. This can be done anywhere within your application and might look something like the following:
Java:
Onfido.Companion.setUserEventHandler(new UserEventHandler() {
@Override
public void handleEvent(@NotNull String eventName, @NotNull Properties eventProperties) {
// Your code here
}
});
Kotlin:
Onfido.userEventHandler = object: UserEventHandler() {
override fun handleEvent(eventName: String, eventProperties: Properties) {
// Your code here
}
}
The code inside of the overridden method will now be called when a particular event is triggered, usually when the user reaches a new screen. For a full list of events see TRACKED_EVENTS.md.
The parameters being passed in are as follows:
eventName
: AString
indicating the type of event. This value will always return user's visiting SDK screen name. In the future more event types, such as other user actions inside the SDK screens, may become available for tracking.properties
: AMap
object containing the specific details of an event. This will contain things such as thename
of the screen visited.
Currently we recommend using the above hook to keep track of how many user's reach each screen in your flow. This can be done by storing the count of users that reach each screen and comparing them to the amount of user's who've made it to the Welcome
screen.
Once you are happy with your integration and are ready to go live, please contact [email protected] to obtain live versions of the API token and the mobile token. We will have to replace the sandbox tokens in your code with the live tokens.
A few things to check before you go live:
- Make sure you have set up webhooks to receive live events
- Make sure you have entered correct billing details inside your Onfido Dashboard
We provide integration guides and sample applications to help customers integrate the Onfido Android SDK with applications built using the following cross-platform frameworks:
We don't have out-of-the-box packages for such integrations yet, but these projects show complete examples of how our Android SDK can be successfully integrated in projects targeting these frameworks. Any issue or question about the existing integrations should be raised on the corresponding repository and questions about further integrations should be sent to [email protected].
You can find the migration guide in MIGRATION.md file.
This section is dedicated to every security aspect of the SDK
We provide integrators the ability to pin any communications between our SDK and server, through a .withCertificatePinning()
method in
our OnfidoConfig.Builder
configuration builder. This method accepts as parameter an Array<String>
with sha-1/sha-256 hashes of certificates' public keys.
In case you are interested in using this feature, for more information about the hashes, please reach out to us at [email protected].
The Onfido Android SDK has been optimised to provide the following accessibility support by default:
- Screen reader support: accessible labels for textual and non-textual elements available to aid TalkBack navigation, including dynamic alerts
- Dynamic font size support: all elements scale automatically according to the device's font size setting
- Sufficient color contrast: default colors have been tested to meet the recommended level of contrast
- Sufficient touch target size: all interactive elements have been designed to meet the recommended touch target size
Refer to our accessibility statement for more details.
In case you want to get notified about our releases, feel free to access our Bintray page and click the Watch
button.
Due to API-design constraints, and to avoid possible conflicts during the integration, we bundle some of our 3rd party dependencies as repackaged versions of the original libraries.
For those, we include the licensing information inside our .aar
, namely on the res/raw/onfido_licenses.json
.
This file contains a summary of our bundled dependencies and all the licensing information required, including links to the relevant license texts contained in the same folder.
Integrators of our library are then responsible for keeping this information along with their integrations.
We have included sample app to show how to integrate the Onfido SDK. Please check out our sample app
Further information about the underlying Onfido API is available in our documentation here.
Please open an issue through GitHub. Please be as detailed as you can. Remember not to submit your token in the issue. Also check the closed issues to check whether it has been previously raised and answered.
If you have any issues that contain sensitive information please send us an email with the ISSUE: at the start of the subject to [email protected].
Previous version of the SDK will be supported for a month after a new major version release. Note that when the support period has expired for an SDK version, no bug fixes will be provided, but the SDK will keep functioning (until further notice).
Copyright 2018 Onfido, Ltd. All rights reserved.