Skip to main content

ID Verification Web Implementation Guide

This guide explains how to integrate ID Verification into a web application, configure workflows, display the verification journey, and retrieve results.

Initiating a ID Verification transaction

Call the RESTful API POST endpoint /initiate with a JSON object containing the properties described below to create a transaction for each user. You will receive a JSON object in the response containing a timestamp, Jumio transaction reference (scan reference), and a URL which you can use to present ID Verification to your user.

HTTP Request Method: POSTREST

note

Jumio Netverify customers are now subject to default rate limits of 3 per second and 180 per minute for initiate requests.

Authentication and Encryption

ID Verification API calls are protected using HTTP Basic Authentication. Your Basic Auth credentials are constructed using your API token as the user-id and your API secret as the password. You can view and manage your API token and secret in the Customer Portal under Settings > API credentials.

warning

Never share your API token, API secret, or Basic Auth credentials with anyone — not even Jumio Support.

The TLS Protocol is required to securely transmit your data, and we strongly recommend using the latest version. For information on cipher suites supported by Jumio during the TLS handshake see Supported cipher suites.

Request Headers

The following fields are required in the header section of your request:

Accept: application/json
Content-Type: application/jsonContent-Length: see [RFC-7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2)
Authorization: (see [RFC 7617](https://datatracker.ietf.org/doc/html/rfc7617)) User-Agent: YourCompany YourApp/v1.0
note

Jumio requires the User-Agent value to reflect your business or entity name for API troubleshooting.

Request Body

The body of your initiate API request allows you to

  • provide your own internal tracking information for the user and transaction.
  • specify what user information is captured and by which method.
  • indicate where the user should be directed after the user journey.
  • select the language to be displayed.
  • preset options to enhance the user journey.
info

Values set in your API request will override the corresponding settings configured in the Customer Portal.

Required items appear in bold type.

NameTypeMax. LengthDescription
customerInternalReference1string100Your internal reference for the transaction.
userReference1string100Your internal reference for the user.
reportingCriteriastring100Your reporting criteria for the transaction.
successUrl2string2047Redirects to this URL after a successful transaction. Overrides Success URL in the Customer Portal.
errorUrl2string255Redirects to this URL after an unsuccessful transaction. Overrides Error URL in the Customer Portal.
callbackUrl2string255Sends verification result to this URL upon completion. Overrides Callback URL in the Customer Portal.
workflowIdinteger3Applies this acquisition workflow to the transaction. Overrides Capture method in the Customer Portal. See supported workflowId values.
presets1JSON-Preset options to enhance the user journey. See supported preset values.
localestring5Renders content in the specified language. Overrides Default locale in the Customer Portal. See supported locale values.
tokenLifetimeInMinutesnumberMax. value: 86400Time in minutes until the authorization token expires. (minimum: 5, maximum: 86400). Overrides Authorization token lifetime in the Customer Portal.

1 Values must not contain Personally Identifiable Information (PII) or other sensitive data such as email addresses. 2 See URL constraints for Callback, Error, and Success URLs.

Supported workflowId Values

Acquisition workflows allow you to set a combination of verification and capture method options.

info

Identity Verification must be enabled for your account to use an ID + Identity workflowId.

ValueVerification typeCapture method
100ID onlycamera + upload
101ID onlycamera only
102ID onlyupload only
200ID + Identitycamera + upload
201ID + Identitycamera only
202ID + Identityupload only

Supported presets Values

It is possible to specify presets for ID Verification, for Identity Verification, for both together, or for neither. For each preset you use, all values must be passed together as a JSON array (see Sample request) for the request to be valid.

ID Verification presets

Preset country and document type - Preset the country and document type to bypass the selection screen.

Required items appear in bold type.

NameTypeMax. lengthDescription
indexinteger1must be set to 1
countrystring3Possible values:ISO 3166-1 alpha-3 country code and XKX (Kosovo)
typestring15Possible values:PASSPORT, DRIVING_LICENSE, ID_CARD

Identity Verification presets

Identity Verification in ID Verification allows you to make sure the person submitting the ID for verification is the same person in the ID photo. This comprises two steps: the Face Match step and the optional Liveness Check step. The Face Match step allows us to compare the face in the ID photo with the face of the person submitting the transaction for similarity, and the additional Liveness Check ensures that person is present during the transaction.

Identity Verification can be enabled with the Face Match step only or in conjunction with a Liveness Check.

Biometric Face Capture

ID Verification's liveness detection technology creates a three-dimensional map of your user's face, providing unprecedented accuracy for the Liveness Check, and creates an enrollment transaction for the use of the Authentication feature.

info

To use Biometric Face Capture, Identity Verification and Biometric Face Capture must be enabled for your account by Jumio Support.

Biometric Face Capture requires that the user has access to a camera. In order to ensure that Biometric Face Capture is always used for the Liveness Check, your users must be restricted to using their camera either for the entire transaction, or for the Identity Verification step.

This can be accomplished by:

  • changing your Capture method in the Settings area of the Customer Portal to Webcam only for the entire transaction.
  • including workflowId 201 to specify "ID + Identity, camera only" in the API request when you initate a ID Verification transaction.
  • asking Jumio Support to enable Force Camera for Identity to allow upload of the ID image, but force the user to use a camera for the Identity Verification step.
capture methodwhenresult
upload onlyalwaysuser asked to upload selfie
camera + uploaduser uploads ID imageuser asked to upload selfie
camera + uploadcamera not availableuser asked to upload selfie
camera + uploadbrowser not supporteduser asked to upload selfie
camera onlycamera not availableerror 9820
camera onlybrowser not supportederror 9820

Supported locale Values

Hyphenated combination of ISO 639-1:2002 alpha-2 language code plus ISO 3166-1 alpha-2 country (where applicable).

Expand the table below
ValueLocale
arArabic
bgBulgarian
csCzech
daDanish
deGerman
elGreek
enAmerican English (default)
en-GBBritish English
esSpanish
es-MXMexican Spanish
etEstonian
fiFinnish
frFrench
heHebrew
hrCroatian
huHungarian
hyArmenian
idIndonesian
itItalian
jaJapanese
kaGeorgian
kmKhmer
koKorean
ltLithuanian
ms

Response

Unsuccessful requests will return the relevant HTTP status code and information about the cause of the error.

Successful requests will return HTTP status code 200 OK along with a JSON object containing the information described below.

Required items appear in bold type.

NameTypeMax. lengthDescription
timestampString24Timestamp (UTC) of the response. Format: YYYY-MM-DDThh:mm:ss.SSSZ
transactionReferenceString36Jumio reference number for the transaction.
redirectUrlStringURL used to load the ID Verification client.

Examples

Sample Request

POST https://netverify.com/api/v4/initiate/ HTTP/1.1
Accept: application/json
Content-Type: application/json
Content-Length: 1234
User-Agent: Example Corp SampleApp/1.0.1
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

{
"customerInternalReference" : "transaction_1234",
"userReference" : "user_1234",
"successUrl" : "https://www.yourcompany.com/success",
"errorUrl" : "https://www.yourcompany.com/error",
"callbackUrl" : "https://www.yourcompany.com/callback",
"reportingCriteria" : "myReport1234",
"workflowId" : 200,
"presets" :
[
{
"index" : 1,
"country" : "AUT",
"type" : "PASSPORT"
}
],
"locale" : "en-GB"
}
warning

Sample requests cannot be run as-is. Replace example data with your own values.

Sample Response

{
"timestamp": "2018-07-03T08:23:12.494Z",
"transactionReference": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"redirectUrl": "https://yourcompany.netverify.com/web/v4/app?locale=en-GB&authorizationToken=xxx"
}

Configuring settings in the Customer Portal

In the Settings screen of the Customer Portal you can customize your settings and brand your ID Verification page. Save changes using your Customer Portal password to activate them.

info

Values set in your API request will override the corresponding settings configured in the Customer Portal.

Application settings — General

Callback, Error, and Success URLs

  • Define a Callback URL to receive verification results and extracted user data from Jumio when a transaction is completed. For more information, see our Callback documentation.
  • Define a Success URL to direct the user after images are accepted for processing. If no Success URL is specified in the Customer Portal or the initiate API request, the Jumio default success page will be displayed, including any custom images you have specified.
  • Define an Error URL to direct the user when the verification process ends with an error or a failure after 3 submission attempts. If no Error URL is specified in the Customer Portal or the initiate API request, the Jumio default error page will be displayed, including any custom images you have specified.

URL requirements:

URL restrictions:

  • IP addresses, ports, certain query parameters and fragment identifiers are not allowed.
  • Personally identifiable information (PII) is not allowed in any form.

Jumio appends the following parameters to your Success or Error URL to redirect your user at the conclusion of the user journey. These cannot be used as part of your Success or Error URL:

NameDescription
transactionStatusSUCCESS for successful submissions. ERROR for errors and failure after 3 attempts.
customerInternalReference1Your internal reference for the transaction.
transactionReferenceJumio reference number for the transaction.
errorCodeDisplayed when transactionStatus is ERROR.

1 - Values must not contain Personally Identifiable Information (PII) or other sensitive data such as email addresses.

Capture method

Specify how your user can submit their ID or Identity image for verification.

Choose from:

  • Webcam and image upload
  • Webcam only
  • Image upload only
important

Selecting "Webcam only" means some mobile browsers will not be supported.

Skip "Start ID verification" screen (deprecated) Select this checkbox to bypass the introductory screen in the ID Verification Web client.

Authorization token lifetime

Specify the duration of time for which your redirectUrl will remain valid. Enter the value in minutes (minimum 5, maximum 86400). The default value is 30 minutes.

Application settings — Redirect

Domain name prefix

You can optionally define a domain name prefix (https://yourcompany.netverify.com) for the URL of your ID Verification page.

  • Allowed characters are letters a-z, numbers 0-9, -
  • Must not start or end with -
  • Max. 63 characters

Default locale

Select a language from the dropdown list to set your display language for ID Verification. If no language is selected, ID Verification will be displayed in English (US).

Choose from the table below
Language
Arabic
Armenian
Bulgarian
Chinese (China)
Chinese (Hong Kong)
Croatian
Czech
Danish
Dutch
English
English (United Kingdom)
Estonian
Finnish
French
German
Georgian
Greek
Hebrew
Hungarian
Indonesian
Italian
Japanese
Khmer
Korean
Lithuanian
Malay
Norwegian
Polish
Portuguese
Portuguese (Brazil)
Romanian
Russian
Slovak
Spanish
Spanish (Mexico)
Swedish
Thai
Turkish
Vietnamese

Customize client

Colors

Specify primary and secondary colors for each locale to give ID Verification your own look and feel.

Any locale which is not configured will first default to the root language (e.g. EN_GB to EN), then to your default configuration, and finally to the Jumio default.

You can also reset all colors to the Jumio default.

Images

Add a Header image for each locale to brand your ID Verification page.

Add a Success image and Error image for each locale to be displayed on the Jumio default success and error pages when you do not specify your own Success URL and Error URL.

Any locale which is not configured will first default to the root language (e.g. EN_GB to EN), then to your default configuration, and finally to the Jumio default.

All images must be formatted as JPG or PNG and must not exceed 5 MB.

Displaying ID Verification

The redirectUrl returned in the response to your initate API call, which loads your customized ID Verification page, can be used in several ways:

  • within an iFrame on your web page
  • as a link on your web page
  • as a link shared securely with a user

Using ID Verification in an iFrame

If you want to embed ID Verification on a web page, place the iFrame tag in your HTML code where you want the client to appear. Use the redirectUrl as value of the src attribute.

warning
  • The allow="camera" attribute must be included to enable the camera for image capture in supported browsers.
  • In case you are nesting the iFrame in another iFrame the allow="camera" attribute must be added to every iFrame.
  • Do not add the iFrame element and its attributes with javascript dynamically at runtime. The iFrame must be present when the page loads.
  • The containing page where the iFrame is added has to be in a secure context (HTTPS).

Note: Due to security reasons the authorizationToken is automatically removed from the redirectUrl once the client is loaded in the browser and stored in a session instead. It will look like this:

https://yourcompany.netverify.com/web/v4/app?locale=en-GB

Width and height

We recommend adhering to the responsive breaking points in the table below.

Size classWidthHeight
Large≥ 900 px≥ 710 px
Medium640 px660 px
Small560 px600 px
X-Small≤ 480 px≤ 535 px
note
  • When specifying the width and height of your iFrame you may prefer to use percentage values so that the iFrame behaves responsively on your page.
  • The ID Verification Web client itself will responsively fill the iFrame that it is loaded into.

Liveness

For a better user experience when creating a three-dimensional map of your user's face, you must allow full screen mode. This will address the positioning and distance between the capture interface and the camera.

warning
  • The allow="camera;fullscreen;accelerometer;gyroscope;magnetometer" allowfullscreen attributes must be included to enable the camera for image capture in supported browsers in full screen mode.
  • In case you are nesting the iFrame in another iFrame the allow="camera;fullscreen;accelerometer;gyroscope;magnetometer" allowfullscreen attributes must be added to every iFrame.
  • Do not add the iFrame element and its attributes with javascript dynamically at runtime. The iFrame must be present when the page loads.
  • The containing page where the iFrame is added has to be in a secure context (HTTPS).
  • Liveness is not possible within an iFrame on incognito mode.
Example HTML

Absolute sizing example

<iframe src="https://yourcompany.netverify.com/web/v4/app?locale=en-GB&authorizationToken=xxx" width="930" height="750" allow="camera;fullscreen;accelerometer;gyroscope;magnetometer" allowfullscreen></iframe>

Responsive sizing example

<iframe src="https://yourcompany.netverify.com/web/v4/app?locale=en-GB&authorizationToken=xxx" width="70%" height="80%" allow="camera;fullscreen;accelerometer;gyroscope;magnetometer" allowfullscreen></iframe>

Biometric Face Capture example

<iframe src="https://yourcompany.netverify.com/web/v4/app?locale=en-GB&authorizationToken=xxx" width="70%" height="80%" allow="camera;fullscreen;accelerometer;gyroscope;magnetometer" allowfullscreen></iframe>

Optional iFrame logging

When the ID Verification client is embedded in an iFrame^1, it will communicate with the containing page using the JavaScript window.postMessage() method to send events containing pre-defined data. This allows the containing page to react to events as they occur (e.g., by directing to a new page once the success event is received). Events include data that allows the containing page to identify which ID Verification transaction triggered the event. Events are generated in a stateless way, so that each event contains general contextual information about the transaction (e.g., transaction reference, authorization token, etc.) in addition to data about the specific event that occurred.

Using JavaScript, the containing page can receive the notification and consume the data it contains by listening for the message event on the global window object and reacting to it as needed. The data passed by the ID Verification Web client in this notification is represented as JSON in the data string property of the listener method's event argument. Parsing this JSON string results in an object with the properties described below.

All data is encoded with UTF-8.

^1 This functionality is not available for instances of ID Verification running in a standalone window or tab.

event.data object

Required items appear in bold type.

PropertyTypeDescription
authorizationTokenstringAuthorization token, valid for a specified duration.
transactionReferencestringJumio reference number for the transaction.
customerInternalReference1stringYour internal reference for the transaction.
eventTypeintegerType of event that has occurred. Possible values: 510 (application state-change)
dateTimestringUTC timestamp of the event in the browser. Format: YYYY-MM-DDThh:mm:ss.SSSZ
payloadJSON objectInformation specific to the event generated. (see event.data.payload object)

1 Values must not contain Personally Identifiable Information (PII) or other sensitive data such as email addresses.

event.data.payload object

Required items appear in bold type.

NameTypeDescription
valuestringPossible values: loaded (ID Verification loaded in the user's browser.) success (Images were accepted for verification.) error (Verification could not be completed due to an error.)
metainfoJSON objectAdditional meta-information for error events. (see metainfo object)

event.data.payload.metainfo object

Required items appear in bold type.

PropertyTypeDescription
codeintegersee errorCode valuesin the table.

Example iFrame logging code

function receiveMessage(event) {
var data = window.JSON.parse(event.data);
console.log('Netverify Web was loaded in an iframe.');
console.log('auth token:', data.authorizationToken);
console.log('transaction reference:', data.transactionReference);
console.log('customer internal reference:', data.customerInternalReference);
console.log('event type:', data.eventType);
console.log('date-time:', data.dateTime);
console.log('event value:', data.payload.value);
console.log('event metainfo:', data.payload.metainfo);
}
window.addEventListener("message", receiveMessage, false);

Using ID Verification in a native WebView

ID Verification Web can be embedded within a WebView in your native mobile application.

See Native WebView for information about support on Android and iOS.

Android

The following sections explain the steps needed to embed ID Verification Web in a native Android WebView.

Please also refer to the sample code beneath.

Permissions and Settings

Make sure that the required permissions are granted.

  • android.permission.INTERNET - for remote resources access
  • android.permission.CAMERA - for camera capture
  • android.permission.READ_EXTERNAL_STORAGE - for upload functionality

The following settings are required for the native WebView for Android.

Embedding required script

To allow Jumio to identify the user runtime environment you will need to interact with the webview window object by embedding a required script. This script sets flag NVW_WEBVIEW to true.

Optional postMessage communication

You can handle messages from the ID Verification Web Client using the same method as described in Optional iFrame Logging.

You will need to register a postMessage handler and put the relevant code sections in the PostMessageHandler class as in the example mentioned below.

Sample code

AndroidManifest.xml example

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jumio.nvw4">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>

build.gradle example

dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0-beta01'
implementation 'androidx.webkit:webkit:1.2.0'
...
}

WebViewFragment.kt example

EXPAND WebViewFragment.kt
class WebviewFragment : Fragment() {

companion object {
var TAG: String = "NVW4"
var PERMISSION_REQUEST_CODE: Int = 1000
private var mUploadMessage: ValueCallback<Uri?>? = null
var uploadMessage: ValueCallback<Array<Uri>>? = null
const val REQUEST_SELECT_FILE = 1002
private const val FILECHOOSER_RESULTCODE = 1003

private var _binding: FragmentWebviewBinding? = null
private val binding get() = _binding!!


//Inject javascript code here that is executed after the page is loaded
val injectFunction = """
function () {
window['__NVW_WEBVIEW__'] = {
isAndroid: true
}
}
""".trimIndent()

private var mFilePathCallback: ValueCallback<Array<Uri>>? = null

fun newInstance(url: String): WebviewFragment {
val fragment = WebviewFragment()

val args = Bundle()
args.putString("url", url)
fragment.arguments = args

return fragment
}
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentWebviewBinding.inflate(inflater, container, false)
return binding.root
}

@SuppressLint("SetJavaScriptEnabled")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

WebView.setWebContentsDebuggingEnabled(true)

binding.webview.settings.javaScriptEnabled = true
binding.webview.settings.allowFileAccessFromFileURLs = true
binding.webview.settings.allowFileAccess = true
binding.webview.settings.allowContentAccess = true
binding.webview.settings.allowUniversalAccessFromFileURLs = true
binding.webview.settings.javaScriptCanOpenWindowsAutomatically = true
binding.webview.settings.mediaPlaybackRequiresUserGesture = false
binding.webview.settings.domStorageEnabled = true

binding.webview.addJavascriptInterface(PostMessageHandler(), "__NVW_WEBVIEW_HANDLER__")

binding.webview.webChromeClient = object : WebChromeClientFullScreen() {

// Grant permissions for cam
@TargetApi(Build.VERSION_CODES.M)
override fun onPermissionRequest(request: PermissionRequest) {
activity?.runOnUiThread {
if ("android.webkit.resource.VIDEO_CAPTURE" == request.resources[0]) {
if (ContextCompat.checkSelfPermission(
activity!!,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
) {
Log.d(
TAG,
String.format(
"PERMISSION REQUEST %s GRANTED",
request.origin.toString()
)
)
request.grant(request.resources)
} else {
ActivityCompat.requestPermissions(
activity!!,
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE
),
PERMISSION_REQUEST_CODE
)
}
}
}
}

// For Lollipop 5.0+ Devices
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
override fun onShowFileChooser(
mWebView: WebView?,
filePathCallback: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams
): Boolean {
if (uploadMessage != null) {
uploadMessage!!.onReceiveValue(null)
uploadMessage = null
}
try {
uploadMessage = filePathCallback
val intent = fileChooserParams.createIntent()
intent.type = "image/*"
try {
startActivityForResult(intent, REQUEST_SELECT_FILE)
} catch (e: ActivityNotFoundException) {
uploadMessage = null
Toast.makeText(
activity?.applicationContext,
"Cannot Open File Chooser",
Toast.LENGTH_LONG
).show()
return false
}
return true
} catch (e: ActivityNotFoundException) {
uploadMessage = null
Toast.makeText(
activity?.applicationContext,
"Cannot Open File Chooser",
Toast.LENGTH_LONG
).show()
return false
}
}

private fun openFileChooser(uploadMsg: ValueCallback<Uri?>) {
mUploadMessage = uploadMsg
val i = Intent(Intent.ACTION_GET_CONTENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "image/*"
startActivityForResult(
Intent.createChooser(i, "File Chooser"),
FILECHOOSER_RESULTCODE
)
}

override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
Log.d(TAG, consoleMessage.message())
return true
}

override fun getDefaultVideoPoster(): Bitmap {
return Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
}
}

binding.webview.webViewClient = object : WebViewClient() {

override fun onReceivedError(
view: WebView?,
errorCode: Int,
description: String?,
failingUrl: String?
) {
Toast.makeText(activity, description, Toast.LENGTH_SHORT).show()
}

override fun onReceivedSslError(
view: WebView?,
handler: SslErrorHandler?,
error: SslError?
) {
handler?.proceed()
}

override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
// Put your javascript function that you want to execute here
binding.webview.loadUrl("javascript:($injectFunction)()")
}
}

binding.webview.loadUrl(arguments?.get("url") as String)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode == REQUEST_SELECT_FILE) {
if (uploadMessage == null)
return
uploadMessage!!.onReceiveValue(
WebChromeClient.FileChooserParams.parseResult(
resultCode,
intent
)
)
uploadMessage = null
}
} else if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage)
return
val result =
if (intent == null || resultCode != AppCompatActivity.RESULT_OK) null else intent.data
mUploadMessage!!.onReceiveValue(result)
mUploadMessage = null
} else {
Toast.makeText(
activity?.applicationContext,
"Failed to Upload Image",
Toast.LENGTH_LONG
).show()
}
super.onActivityResult(requestCode, resultCode, intent)
}

class PostMessageHandler {
@JavascriptInterface
fun postMessage(json: String?, transferList: String?): Boolean {
/*
There we're handling messages from NVW4 client, its the same as for iFrame logging;
More details can be found here:
https://github.com/Jumio/implementation-guides/blob/master/netverify/netverify-web-v4.md#optional-iframe-logging
*/
Log.d(TAG, "postMessage triggered, json: " + json.toString())
return true
}
}

/**
* Custom WebChromClient to handle iProov full screen requirement
* More details can be found here:
* https://github.com/iProov/android/wiki/Java-WebView
*/
open inner class WebChromeClientFullScreen : WebChromeClient() {
private var customView: View? = null
private var customViewCallback: CustomViewCallback? = null
private var originalOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
private var originalVisibility = View.INVISIBLE

/**
* Callback will tell the host application that the current page would
* like to show a custom View in a particular orientation
*/
override fun onShowCustomView(view: View, callback: CustomViewCallback) {
//If we have custom view, that means that we are already in full screen, and need to go to original state
if (customView != null) {
onHideCustomView()
return
}
//going full screen
customView = view
//We need to store there parameters, so we can restore app state, after we exit full screen mode
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
originalVisibility = activity?.window?.decorView?.visibility!!
(activity?.window?.decorView as FrameLayout).addView(
customView,
FrameLayout.LayoutParams(-1, -1)
)
activity?.window?.setDecorFitsSystemWindows(false)
} else {
originalVisibility = activity?.window?.decorView?.windowSystemUiVisibility!!
(activity?.window?.decorView as FrameLayout).addView(
customView,
FrameLayout.LayoutParams(-1, -1)
)
activity?.window?.decorView?.systemUiVisibility =
3846 or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
originalOrientation = activity?.requestedOrientation!!
}

/**
* Callback will tell the host application that the current page exited full screen mode,
* and the app has to hide custom view.
*/
override fun onHideCustomView() {
(activity?.window?.decorView as FrameLayout).removeView(
customView
)
customView = null
//Restoring app state, as it was before we go to full screen
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
activity?.window?.setDecorFitsSystemWindows(true)
} else {
activity?.window?.decorView?.systemUiVisibility = originalVisibility
}
activity?.requestedOrientation = originalOrientation
if (customViewCallback != null) customViewCallback!!.onCustomViewHidden()
customViewCallback = null
}
}

Use of iProov

Please be aware that if iProov is included in your workflow, it is necessary to extend WebChromeClient class to implement a custom view, in order to handle certain iProov full screen requirements.

See WebViewFragment.kt code sample above, specifically WebChromeClientFullScreen inner class.

Sample App

Check out our Sample App for the Native Android WebView

iOS

Jumio supports two types of webview for iOS, you can choose either of these:

Safari WebView

ProsCons
Access to the camera during ID and IdentityNo optional postMessage communication
Fewer integration stepsFewer options for troubleshooting

Native iOS WebView

ProsCons
Optional postMessage communicationImage upload only (no access to the camera)
Better options for troubleshootingMore integration steps

Safari WebView

The following sections explain the steps needed to embed ID Verification Web in a Safari View Controller.

Please also refer to the sample code beneath.

Permissions and Settings

Make sure that camera permissions are granted.

Sample code

ViewController.swift example


import AVFoundation
import SafariServices
import UIKit

class ViewController: UIViewController {

@IBAction func loadButton(_ sender: Any) {
checkCameraPermission()
let url: String = "https://www.jumio.com/"
showSafariVC(inputText)
}

// present SFSafariViewController
private func showSafariVC(_ stringURL: String) {
guard let URL = URL(string: stringURL) else {
return
}


let safariVC = SFSafariViewController(url: URL)
present(safariVC, animated: true)
}

func safariViewControllerDidFinish(_ safariVC: SFSafariViewController) {
safariVC.dismiss(animated: true, completion: nil)
}

// ask for camera permissions
func checkCameraPermission() {
AVCaptureDevice.requestAccess(for: .video) { (granted) in
if !granted {
print("Camera permission denied")
}
}
}

}

Sample App

Check out our Sample App for the iOS Safari WebView

Native iOS WebView

The following sections explain the steps needed to embed ID Verification Web in a native iOS WebView.

Please also refer to the sample code beneath.

Permissions and Settings

No specific permissions are needed as we cannot access the camera due to native WebView limitations for iOS.

Embedding required script

To allow Jumio to identify the user runtime environment you will need to interact with the webview window object by embedding a required script. This script sets flag NVW_WEBVIEW to true.

Optional postMessage communication You can handle messages from the ID Verification Web Client using the same method as described in Optional iFrame Logging.

Please register a postMessage handler and put the relevant code sections in the userContentController function as mentioned below.

Sample code ViewController.swift example


class ViewController: UIViewController {
@IBOutlet weak var webView: WKWebView!

override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self;

/**
_ Registering handler for postMessage communication (iFrame logging equivalent - optional)
_/
webView.configuration.userContentController.add(self, name: "**NVW_WEBVIEW_HANDLER**")

webView.load( URLRequest("<<NVW4 SCAN REF LINK>>"));
}
}

extension ViewController: WKNavigationDelegate {
/**
_ Embedding script at very beginning, before NVW4 initialize (important)
_/
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
/\*\*
* Necesssary integration step - embedding script
*/
self.webView?.evaluteJavaScript("(function() { window['__NVW_WEBVIEW__'] = true })()") { _, error in
if let error = error {
print("ERROR while evalutaing javascript \(error)") // error handling whenever executing script fails
}
print("executed injected javascript")
};
}
}

extension ViewController: WKScriptMessageHandler {
/\*\*
_ PostMessage handler for iframe logging equivalent (optional)
_/
func userContentController(\_ userController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "**NVW_WEBVIEW_HANDLER**", let messageBody = message.body as? String {
/\*
_ See iFrame logging:
_ https://github.com/Jumio/implementation-guides/blob/master/netverify/netverify-web-v4.md#optional-iframe-logging
\*/
}
}
}

Sample App

Check out our Sample App for the Native iOS WebView

After the user journey

At the end of the user journey, the user is directed to your Success URL if the images they submitted were accepted for processing. If no Success URL has been defined, the Jumio default success page will be displayed, including any custom success image you have specified in the Customer Portal.

If acceptable images are not provided after three attempts (see Reject reasons), the user is directed to your Error URL. If no Error URL has been defined, the Jumio default error page will be displayed, including any custom error image you have specified in the Customer Portal.

To display relevant information on your success or error page, you can use the following parameters which we append when redirecting to your successUrl or errorUrl as HTTP GET query string parameters1. It is also possible to set successUrl and errorUrl to the same address, by using the query parameter transactionStatus.

Required items appear in bold type.

NameDescription
transactionStatusPossible values: SUCCESS for successful submissions. ERROR for errors and failure after 3 attempts.
customerInternalReference2Your internal reference for the transaction.
transactionReferenceJumio reference number for the transaction.
errorCodeDisplayed when transactionStatus is ERROR. Possible values: 9100 (Error occurred on our server.) 9200 (Authorization token missing, invalid, or expired.) 9210 (Session expired after the user journey started.) 9300 (Error occurred transmitting image to our server.) 9400 (Error occurred during verification step.) 9800 (User has no network connection.) 9801 (Unexpected error occurred in the client.) 9810 (Problem while communicating with our server.) 9820 (File upload not enabled and camera unavailable.) 9821 (The Biometric Face Capture face capture process failed, e.g. issue with iProov) 9822 (Browser does not support camera.) 9835 (No acceptable submission in 3 attempts.)

1 Because HTTP GET parameters can be manipulated on the client side, they may be used for display purposes only. 2 Values must not contain Personally Identifiable Information (PII) or other sensitive data such as email addresses.

Sample success redirect


https://www.yourcompany.com/success/?transactionStatus=SUCCESS&customerInternalReference=YOUR_REF&transactionReference=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Sample error redirect


https://www.yourcompany.com/error/?transactionStatus=ERROR&customerInternalReference=YOUR_REF&transactionReference=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&errorCode=9820

Supported environments

Jumio offers guaranteed support for ID Verification on the following browsers and the latest major version of each operating system.

Desktop browsers

BrowserMajor versionOperating systemSupports image uploadSupports camera captureSupports Biometric Face Capture
Google Chromecurrent + 1 previousWindows + MacXXX
Mozilla Firefoxcurrent + 1 previousWindows + MacXXX
Apple SafaricurrentMacXXX
Microsoft EdgecurrentWindowsXXX

Mobile browsers

Browser nameMajor browser versionOperating systemSupports image uploadSupports camera captureSupports Biometric Face Capture
Google ChromecurrentAndroid + iOSXXX
Samsung InternetcurrentAndroidXXX
Apple SafaricurrentiOSXXX1

1Fullscreen functionality during capture only supported for iPads. iPhone process works, but fullscreen is limited and capture may be less accurate.

Native WebView

Operating systemMajor versionSupports image uploadSupports camera captureSupports Biometric Face Capture
Native Android WebViewcurrent + 1 previousXXX
Native iOS WebView1current + 1 previousX
iOS Safari WebViewcurrent + 1 previousXXX

1If you are using a native WebView for iOS you will need to enable image upload to allow the end user to finish the user journey.