Onfido LogoOnfido Logo

Developers

Custom callbacks

Start here

It is possible to integrate with the Onfido Smart Capture SDKs and use the data captured from the user, without the requirement of using this data only through the Onfido API. Custom callbacks enable you to control the end user data collected by the SDK after the end user has submitted their captured media. As a result, you can leverage Onfido’s advanced on-device technology, including image quality validations, while still being able to handle end users’ data directly. This unlocks additional use cases, including compliance requirements and multi-vendor configurations, that require this additional flexibility.

Follow this guide to use custom callbacks with the Web, Android, iOS, React Native and Flutter Smart Capture SDKs.

This feature must be enabled for your account. Please contact your Onfido Solution Engineer or Customer Success Manager.

Web

Custom callbacks that are invoked when the end user submits their captured media allow you to control the end user data collected by the Onfido SDK. The callbacks provide all of the information that would normally be sent directly to the Onfido API to you and expects a promise in response that controls what the SDK does next.

Implementation

To use this feature, set useCustomizedApiRequests to true and provide the callbacks for onSubmitDocument, onSubmitSelfie and onSubmitVideo within the enterpriseFeatures block of the configuration options when initializing the SDK.

javascript
1Onfido.init({
2 // Other options here
3 enterpriseFeatures: {
4 useCustomizedApiRequests: true,
5 onSubmitDocument: (documentData) => {
6 // Your callback code here
7 },
8 onSubmitSelfie: (selfieData) => {
9 // Your callback code here
10 },
11 onSubmitVideo: (videoData) => {
12 // Your callback code here
13 },
14 },
15})

Cross-device flow

In order to also use this feature on the Web SDK cross-device flow, you must host the cross-device experience of the Onfido SDK yourself. You can do this by specifying a custom or whitelabel cross-device URL that the cross-device flow will redirect to instead of the Onfido default id.onfido.com.

  1. Generate an SDK token and use it to start the SDK.
bash
1$ curl https://api.onfido.com/v3.3/sdk_token \
2 -H 'Authorization: Token token=YOUR_API_TOKEN' \
3 -F 'applicant_id=YOUR_APPLICANT_ID' \
4 -F 'referrer=REFERRER_PATTERN' \
5 -F 'cross_device_url=YOUR_CUSTOM_URL'

Note: The custom URL can be a maximum of 24 characters long including the header (https://).

  1. Set up a server to host the Onfido Web SDK at the provided URL

Note: The server must use the same version of the Onfido Web SDK.

  1. Initialize the SDK with Onfido.init({ mobileFlow: true }) as well as the callbacks and useCustomizedApiRequests options

For more information see here.

User data

The callbacks return a FormData object, including the information that the SDK would send to Onfido. The callbacks are invoked when the end user confirms submission of their image through the SDK’s user interface.

Note: End user data will no longer be sent to the Onfido backend by default. If you want Onfido to process a check, you must upload the data to the Onfido API from your backend, or set continueWithOnfidoSubmission: true.

onSubmitDocument FormData Parameters:

javascript
1{
2 file: blob,
3 side: string,
4 type: string,
5 sdk_validations: object,
6 sdk_source: string,
7 sdk_version: string,
8 sdk_metadata: object
9}

onSubmitSelfie FormData Parameters:

javascript
1{
2 file: blob,
3 snapshot: blob,
4 sdk_source: string,
5 sdk_version: string,
6 sdk_metadata: object
7}

onSubmtiVideo FormData Parameters:

javascript
1{
2 file: blob,
3 challenge: { type: 'recite' / 'movement', query: number[] / string }
4 challenge_id: string,
5 challenge_switch_at: number, // seconds
6 languages: { source: 'sdk', language_code: string }
7 sdk_source: string,
8 sdk_version: string,
9 sdk_metadata: object
10}

Create a check with Onfido

After receiving the user data from the SDK, you can choose to create a check with Onfido. In this case, you must either allow the SDK to upload the user data to Onfido API or upload the user data yourself.

Please see our API documentation for more information on how to create a check.

Allow the SDK to upload data to Onfido

To allow the SDK to upload the user-submitted data directly to Onfido you can resolve the promise with an object containing continueWithOnfidoSubmission: true.

javascript
1onSubmitDocument: (data) => {
2 // Note: data is a FormData object, to view the contents you can use:
3 for (const [key, value] of data.entries()) {
4 console.log('data (key,value): ', key, value)
5 }
6
7 // Send data to your backend then resolve promise,
8 return Promise.resolve({ continueWithOnfidoSubmission: true })
9}

Upload user data to the Onfido API

You can upload the end user data to the Onfido API from your backend, after you have received it from the Onfido SDK callbacks. We strongly recommend that you include all of the data provided to you through the callbacks in your request to the appropriate endpoint.

/documents

/live_photos

Note: The /live_videos endpoint is not currently available for direct upload to the Onfido API.

Additionally, you should use the SDK token created for each applicant in the Authorization header of the request.

Authorization: Bearer <SDK token here>

Note: The SDK token is not included in the FormData provided by the callbacks. You may want to append this, or a different unique identifier that is mapped to the applicant's SDK token, on your backend before sending it off.

Once you have sent the request to Onfido from your backend, you can supply the Onfido SDK with the response so it can determine what the end user should be presented with. In the case where a success response is received, the promise should be resolved with onfidoSuccessResponse: <onfidoResponse>. Otherwise reject the promise with the Onfido error response.

Note: An error response could be returned due to image quality issues. In this case, the SDK will present the end user with the appropriate error message.

javascript
1onSubmitDocument: (data) => {
2 // Send request to Onfido API /documents via your backend proxy
3 .then(onfidoSuccessResponse =>
4 Promise.resolve({ onfidoSuccessResponse: <onfidoResponse> }))
5 .catch(onfidoError => Promise.reject(onfidoError))
6}

We provide a sample openAPI YAML file you could use as an example to start your own proxy.

Android

Implementation

To use this feature use .withMediaCallback and provide the callbacks for DocumentResult, SelfieResult and LivenessResult.

java
1onfidoConfigBuilder.withMediaCallback(new CustomMediaCallback());
2private static class CustomMediaCallback implements MediaCallback {
3
4 @Override
5 public void onMediaCaptured(@NonNull MediaResult result) {
6 if (result instanceof DocumentResult) {
7 //TODO
8 } else if (result instanceof LivenessResult) {
9 //TODO
10 } else if (result instanceof SelfieResult) {
11 //TODO
12 }
13 }
14}
kotlin
1onfidoConfigBuilder
2 .withMediaCallback { mediaResult ->
3 when(mediaResult){
4 is DocumentResult -> // Your callback code here
5 is SelfieResult -> // Your callback code here
6 is LivenessResult -> // Your callback code here
7 }
8 }

Note: If you are using Java, don’t forget to set the inner class to static if outer class is not Serializable. Note: If you are using Kotlin, don’t forget to use a nested class if the outer class is not Serializable.

User data

The callbacks return an object including the information that the SDK normally sends directly to Onfido. The callbacks are invoked when the end user confirms submission of their image through the SDK’s user interface.

Note: Currently, end user data will still automatically be sent to the Onfido backend. You are not required to use Onfido to process this data.

Documents

For documents the callback returns a DocumentResult object:

bash
1{
2 fileData: MediaFile
3 documentMetadata: DocumentMetadata
4 }

Note: If a document was scanned using NFC, the callback will only return the MediaFile.

The DocumentMetadata object contains the metadata of the captured document.

bash
1{
2 side: String,
3 type: String,
4 issuingCountry: String
5 }

Note: issuingCountry is optional based on end-user selection, and can be null.

Live photos and videos

For live photos the callback returns a SelfieResult object:

bash
1{
2 fileData: MediaFile
3 }

For live videos the callback returns a LivenessResult object:

bash
1{
2 fileData: MediaFile
3 }

The MediaFile object contains the raw data and MIME type of the captured photo or video.

bash
1{
2 fileData: ByteArray,
3 fileType: String
4 }

Create a check with Onfido

After receiving the user data from the SDK, you can choose to create a check with Onfido. In this case, you don’t need to re-upload the end user data as it is sent automatically from the SDK to the Onfido backend.

Please see our API documentation for more information on how to create a check.

iOS

Implementation

To use this feature, use .withMediaCallback and provide the callbacks for MediaDocumentResult for documents and MediaFile for live photos and live videos.

swift
1final class SwiftDynamicFrameworkOnfidoRunner: OnfidoRunner, MediaCallback {
2 func onMediaCaptured(result: MediaResult) {
3 switch result {
4 case let documentResult as MediaDocumentResult:
5 // Your callback code here
6 case let selfieResult as SelfieResult:
7 // Your callback code here
8 case let livenessResult as LivenessResult:
9 // Your callback code here
10 default:
11 Break
12 }
13 }
14 configBuilder.withMediaCallback(mediaCallback: self)
15}

User data

The callbacks return an object including the information that the SDK normally sends directly to Onfido. The callbacks are invoked when the end user confirms submission of their image through the SDK’s user interface.

Note: Currently, end user data will still automatically be sent to the Onfido backend, but you are not required to use Onfido to process this data.

Documents

For documents, the callback returns a MediaDocumentResult object:

json5
1{
2 metadata: DocumentMetadata
3 file: MediaFile
4 }

Note: If a document was scanned using NFC, the callback will return the passport photo in file but no additional data.

The DocumentMetadata object contains the metadata of the captured document.

json5
1{
2 side: String
3 type: String
4 issuingCountry: String?
5}

Note: issuingCountry is optional based on end-user selection, and can be null

Live photos and videos

For live photos, the callback returns a SelfieResult object:

json5
1{
2 fileData: MediaFile
3}

For live videos, the callback returns a LivenessResult object:

json5
1{
2 fileData: MediaFile
3}

The MediaFile object contains:

json5
1{
2 name: String
3 data: Data
4}

Create a check with Onfido

After receiving the user data from the SDK, you can choose to create a check with Onfido. In this case, you don’t need to re-upload the end user data as it is sent automatically from the SDK to the Onfido backend.

Please see our API documentation for more information on how to create a check.

React Native

Implementation

To use this feature, use Onfido.addCustomMediaCallback and provide the callback.

javascript
1Onfido.addCustomMediaCallback((mediaResult) => {
2 if (mediaResult.captureType === 'DOCUMENT') {
3 // Callback code here
4 } else if (mediaResult.captureType === 'FACE') {
5 // Callback code here
6 } else if (mediaResult.captureType === 'VIDEO') {
7 // Callback code here
8 }
9})

User data

The callbacks return an object including the information that the SDK normally sends directly to Onfido. The callbacks are invoked when the end user confirms submission of their image through the SDK’s user interface.

Note: Currently, end user data will still automatically be sent to the Onfido backend, but you are not required to use Onfido to process this data.

The callback returns 3 possible objects. Please note that captureType refers to the type of the media capture in each case. These can be DOCUMENT, FACE or VIDEO.

For documents (captureType is DOCUMENT), the callback returns:

json5
1{
2 captureType: String
3 side: String
4 type: String
5 issuingCountry: String?
6 fileData: String
7 fileName: String
8 fileType: String
9}

Notes:

  • issuingCountry is optional based on end-user selection, and can be null.
  • fileData is a String representation of the byte array data corresponding to the captured photo of the document.
  • If a document was scanned using NFC, the callback will return the passport photo in fileData but no additional data.

For live photos (captureType is FACE), the callback returns:

json5
1{
2 captureType: String
3 fileData: String
4 fileName: String
5 fileType: String
6}

Note: fileData is a String representation of the byte array data corresponding to the captured live photo.

For videos (captureType is VIDEO), the callback returns:

json5
1{
2 captureType: String
3 fileData: String
4 fileName: String
5 fileType: String
6}

Note: fileData is a String representation of the byte array data corresponding to the captured video.

Please note that, for your convenience, Onfido provides the byteArrayStringToBase64 helper function to convert the fileData from String to a Base64 format. Here is an example of how to use it:

javascript
1let byteArrayString = mediaResult.fileData
2let base64FileData = Onfido.byteArrayStringToBase64(byteArrayString)

Flutter

Implementation

To use this feature, implement the OnfidoMediaCallback interface and provide the callback for OnfidoMediaResult for documents, live photos and live videos.

dart
1class MediaCallback implements OnfidoMediaCallback {
2
3 Future<void> onMediaCaptured({required OnfidoMediaResult result}) async {
4 // Your callback code here
5 }
6}

Then you should pass this class to Onfido SDK builder as a parameter:

dart
1MediaCallback callback = MediaCallback();
2
3final Onfido onfido = Onfido(
4 sdkToken: sdkToken,
5 mediaCallback: callback,
6 enterpriseFeatures: EnterpriseFeatures(
7 hideOnfidoLogo: _hideOnfidoLogo,
8 )
9);