React Native SDK

Overview

The AiPrise React Native SDK is designed to allow developers to seamlessly integrate our pre-built KYC user experience into their existing mobile applications with just 5 lines of code.

Install the AiPrise React Native SDK

Start by running the following command in the root folder of your React Native project:

npm install aiprise-react-native-sdk react-native-webview

Or if you use yarn:

yarn add aiprise-react-native-sdk react-native-webview

Permission Setup for Non-Expo Users

(i) Install this additonal package that helps us in requesting the camera permissions.

npm install react-native-permissions
# --- or ---
yarn add react-native-permissions

(ii) For iOS, setup this script in your Podfile:

# with react-native >= 0.72
- # Resolve react_native_pods.rb with node to allow for hoisting
- require Pod::Executable.execute_command('node', ['-p',
-   'require.resolve(
-     "react-native/scripts/react_native_pods.rb",
-     {paths: [process.argv[1]]},
-   )', __dir__]).strip

+ def node_require(script)
+   # Resolve script with node to allow for hoisting
+   require Pod::Executable.execute_command('node', ['-p',
+     "require.resolve(
+       '#{script}',
+       {paths: [process.argv[1]]},
+     )", __dir__]).strip
+ end

+ node_require('react-native/scripts/react_native_pods.rb')
+ node_require('react-native-permissions/scripts/setup.rb')
# with react-native < 0.72
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
+ require_relative '../node_modules/react-native-permissions/scripts/setup'

(iii) Then in the same file, add a setup_permissions call with the camera permissions:

# …

platform :ios, min_ios_version_supported
prepare_react_native_project!

setup_permissions([
   'Camera',
])

# …

(iv) Then execute pod install ( Note that it must be re-executed each time you update this config).

(v) Finally, update your Info.plist with the camera permissions usage descriptions:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>NSCameraUsageDescription</key>
  <string>We require camera permission to capture your ID documents.</string>

  <!-- … -->

</dict>
</plist>

(vi) For Android, add the camera permissions to your app android/app/src/main/AndroidManifest.xml file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.CAMERA" />

  <!-- … -->

</manifest>

Additonal steps for Expo Users

(i) Install this additonal package that helps us in requesting the camera permissions.

npm install expo-camera
# --- or ---
yarn add expo-camera

(ii) Update app.json to enable the expo-camera plugin.

{
  "expo": {
    "plugins": [
      [
        "expo-camera",
        {
          "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera."
        }
      ]
    ]
  }
}

(iii) Make sure to use the expo-camera plugin to request the camera permission before you start a verification session with us.

import { useState } from 'react';
import { Camera } from 'expo-camera';
import { Button, Text, View } from 'react-native';

export default function App() {
  const [permission, requestPermission] = Camera.useCameraPermissions();

  if (!permission) {
    // Camera permissions are still loading
    return <View />;
  }

  if (!permission.granted) {
    // Camera permissions are not granted yet
    return (
      <View>
        <Text style={{ textAlign: 'center' }}>We need your permission to show the camera</Text>
        <Button onPress={requestPermission} title="Grant Permission" />
      </View>
    );
  }

  return (
    <View>
      <!-- Add AiPrise SDK Components Here -->
    </View>
  );
}


Option 1: <AiPriseButton /> Component

The <AiPriseButton /> component lets you quickly integrate the onboarding screens in your React Native application. On clicking it, a modal will be launched where the user data will be collected. When user completes the flow, the modal will close and an even will be fired to inform your app that the session was successful.

Basic Usage

Just add the <AiPriseButton /> component in your page wherever you want to place it. The mode and templateID are the only required props. You can add others as per your requirements.

import { AiPriseButton } from "aiprise-react-native-sdk";

export const SomeRandomComponent = () => {
  return (
    <AiPriseButton
      mode="SANDBOX/PRODUCTION"
      templateID="YOUR_TEMPLATE_ID"
    />
  );
};

Advanced Usage

Apart from templateID and mode, there are a few more props that you can pass like the title, icon, etc that allow you to customize the button. All of them are listed in the example below.

In addition to the props, there are also five events fired by the button which you can listen to:
(i) onStart: Will be fired after the session starts. i.e. when the user clicks on the button, the modal opens and a new session gets created (event will be fired after the loading screen is completed).
(ii) onAbandoned: Will be fired when the user quits out of the verification flow by clicking the close button (or the back button on Android) and confirming that they want to stop the verification.
(iii) onSuccess: This will be fired when the user completes filing out the entire verification form and reaches the last page. They may not have clicked the close button yet so the modal is still visibile at this point but no other information has to be collected from them. Note: "successful" does not mean that the KYC is approved. It just means form is successfully filled by the user.
(iv) onComplete: This will be fired AFTER the user clicks the close or continue button on the last page. The SDK will handle closing of the modal automatically in that case so no action is required on your end. The event is just in case you want to perform any task in your application after this point.
(v) onError: This event is fired in case the session creation failed. This can happen for a number of reasons like invalid template ID, internet issues, etc. You can check the error message in the console to see why it's happening.

The example below shows all the extra props along with the events:

import { AiPriseButton } from "aiprise-react-native-sdk";

export const SomeRandomComponent = () => {
  return (
    <AiPriseButton
      mode="SANDBOX/PRODUCTION"
      templateID="YOUR_TEMPLATE_ID"

      callbackURL="http://yourcallbackurl.com"
      eventsCallbackURL="http://yourcallbackurl.com"

      clientReferenceID="SOME_ID_YOU_WANT_TO_ASSOCIATE_WITH_YOUR_REQUEST"
      clientReferenceData={{ some_data: "some_value" }}
  
      uiOptions={{
        id_verification_module: {
          allowed_country_code: "US", // 2-Letter Country Code. Disables all other countries.
        }
      }}
      verificationOptions={{
        AML_CONFIG: {
          fuzziness_score: 0.8, // Number
          exact_match: 0.8, // Number
          monitoring: false, // Boolean
        }
      }}
  
      // Optional / Only for KYC
      userData={{
        first_name: "Your User's First Name",
        middle_name: "Your User's Middle Name",
        last_name: "Your User's Last Name",
        date_of_birth: "YYYY-MM-DD",
        phone_number: "+11234567890",
        email_address: "[email protected]",
        ip_address: "0.0.0.0",
        address: {
          address_street_1: "...",
          address_street_2: "...",
          address_city: "...",
          address_state: "...",
          address_zip_code: "...",
          address_country: "...",
        },
      }}
      
      // Optional / Only for KYC
      additionalInfo={[
        {
          additional_info_type: "TYPE_HERE",
          additional_info_data: "DATA_HERE",
        },
        {
          additional_info_type: "TYPE_2_HERE",
          additional_info_data: "DATA_2_HERE",
        },
      ]}

      // CUSTOMIZATION
      title="YOUR_BUTTON_TEXT"
      icon="YOUR_LOGO_IMAGE"
      theme={{ /* Theme Options */ }}

      // EVENTS
      onStart={(sessionID) => {
        alert("Session started with id: " + sessionID);
      }}
      onBusinessProfileCreated={(businessProfileId) => {
        console.log("Business profile created with ID: " + businessProfileId);
      }}
      onAbandoned={(sessionID) => {
        alert("Session abandoned with id: " + sessionID);
      }}
      onSuccess={(sessionID) => {
        alert("Session success with id: " + sessionID);
      }}
      onComplete={(sessionID) => {
        alert("Session complete with id: " + sessionID);
      }}
      onError={(errorCode) => {
        alert("Error: " + errorCode);
        // SESSION_FAILED is fired when session creation fails (due to incorrect values, internet or server issues, etc)
        // SESSION_EXPIRED happens when you try to resume a session but the session ID has expired
        // SESSION_COMPLETED happens when you try to resume a session but the session has already been completed by the user
      }}
    />
  );
};

Styling the Button

There are 4 levels to customization.

(i) First is that the button component itself allows you to change the icon and the text using props.
(ii) To customize further than that, you can passing in the style prop to the button and change it's border color, padding, etc.
(iii) You can also pass style to inner elements of the button using the: iconContainerStyle, iconStyle, textContainerStyle and textStyle props.
(iv) To customize the verification UI you can pass in the theme options which are documented here.

import { AiPriseButton } from "aiprise-react-native-sdk";

export const SomeRandomComponent = () => {
  return (
    <AiPriseButton
      mode="SANDBOX/PRODUCTION"
      templateID="YOUR_TEMPLATE_ID"

      title="YOUR_BUTTON_TEXT"
      icon="YOUR_LOGO_IMAGE"

      style={{
        borderColor: "red",
        borderWidth: 2
      }}

      iconContainerStyle={{
        padding: 4
      }}
      iconStyle={{
        width: 32,
        height: 32,
      }}
      textContainerStyle={{
        backgroundColor: "red",
      }}
      textStyle={{
        color: "green"
      }}
  
      theme={{ /* Theme Options */ }}
    />
  );
};

The iconContainerStyle will be applied to the <View/> tag that contains the icon. iconStyle will be applied to the <Image /> tag that renders the icon. Similar is the case for the textContainerStyle and textStyle.

Option 2: <AiPriseFrame /> Component

This option allows you to integrate the verification flow pages directly into your app using a webview. You can pass a style prop to this component to set it's width, height, etc and ensure it fits within your UI. Without the width/height it will render with 0x0 size and won't be visible.

Unlike the button, in the AiPriseFrame component, you take the responsibility or showing the verification flow (after some user action like a button click) and hiding it when the user has filled the entire form.

Just like the button, the mode and templateID are the only required attribute. You can add others as per your needs.

Basic Usage

import { AiPriseFrame } from "aiprise-react-native-sdk";

export const SomeRandomComponent = () => {
  return (
    <AiPriseFrame
      style={{ width: 200, height: 200 }}
      mode="SANDBOX/PRODUCTION"
      templateID="YOUR_TEMPLATE_ID"
    />
  );
};

Advanced Usage

Similar to the button component, you can pass additional props here like callback URL, user data, etc. Full list of attributes are visible in the example below.

There are 4 events that you can listen to: onStart, onSuccess, onComplete & onError. These work exactly the same way as described in the button component above. Ideally, you may want to listen to the onComplete event to hide the frame after the verification is completed.
Note: There is no onAbandoned event here unlike the button since frame's cant be abandoned. It's always visible till the host application i.e. your app hides it.

import { AiPriseFrame } from "aiprise-react-native-sdk";

export const SomeRandomComponent = () => {
  return (
    <AiPriseFrame
      mode="SANDBOX/PRODUCTION"
      templateID="YOUR_TEMPLATE_ID"

      callbackURL="http://yourcallbackurl.com"
      eventsCallbackURL="http://yourcallbackurl.com"

      clientReferenceID="SOME_ID_YOU_WANT_TO_ASSOCIATE_WITH_YOUR_REQUEST"
      clientReferenceData={{ some_data: "some_value" }}
  
      uiOptions={{
        id_verification_module: {
          allowed_country_code: "US", // 2-Letter Country Code. Disables all other countries.
        }
      }}
      verificationOptions={{
        AML_CONFIG: {
          fuzziness_score: 0.8, // Number
          exact_match: 0.8, // Number
          monitoring: false, // Boolean
        }
      }}
  
      // Optional / Only for KYC
      userData={{
        first_name: "Your User's First Name",
        middle_name: "Your User's Middle Name",
        last_name: "Your User's Last Name",
        date_of_birth: "YYYY-MM-DD",
        phone_number: "+11234567890",
        email_address: "[email protected]",
        ip_address: "0.0.0.0",
        address: {
          address_street_1: "...",
          address_street_2: "...",
          address_city: "...",
          address_state: "...",
          address_zip_code: "...",
          address_country: "...",
        },
      }}
      
      // Optional / Only for KYC
      additionalInfo={[
        {
          additional_info_type: "TYPE_HERE",
          additional_info_data: "DATA_HERE",
        },
        {
          additional_info_type: "TYPE_2_HERE",
          additional_info_data: "DATA_2_HERE",
        },
      ]}

      // CUSTOMIZATION
      icon="YOUR_LOGO_IMAGE"
      theme={{ /* Theme Options */ }}

      // EVENTS
      onStart={(sessionID) => {
        alert("Session started with id: " + sessionID);
      }}
      onBusinessProfileCreated={(businessProfileId) => {
        console.log("Business profile created with ID: " + businessProfileId);
      }}
      onSuccess={(sessionID) => {
        alert("Session success with id: " + sessionID);
      }}
      onComplete={(sessionID) => {
        alert("Session complete with id: " + sessionID);
      }}
      onError={(errorCode) => {
        alert("Error: " + errorCode);
        // SESSION_FAILED is fired when session creation fails (due to incorrect values, internet or server issues, etc)
        // SESSION_EXPIRED happens when you try to resume a session but the session ID has expired
        // SESSION_COMPLETED happens when you try to resume a session but the session has already been completed by the user
      }}
    />
  );
};

Resuming Sessions

Each time you click on the <AiPriseButton /> component and each time the <AiPriseFrame /> component mounts, we create a new session. However in some cases, you may want to resume an old session.

For example you allow the user to go to another tab and come back. In such cases, you can provide us the old session ID and we will resume it directly instead of creating a new one.

import { AiPriseButton } from "aiprise-react-native-sdk";

export const SomeRandomComponent = () => {
  return (
    <AiPriseButton
      mode="SANDBOX/PRODUCTION"
      sessionId="THE_ID_OF_THE_SESSION_YOU_WANT_TO_RESUME"
      templateID="YOUR_TEMPLATE_ID" // This will be ignored when resuming but TypeScript requires this so always pass it
      title="YOUR_BUTTON_TEXT"
      icon="YOUR_LOGO_IMAGE"
      onStart={(sessionID) => {
        // Save the session ID in this step. Give it back to the component when you want to resume
      }}
      onResume={(sessionID) => {
        console.log("Session resumed with ID: " + sessionID);
      }}
    />
  );
};

This works the same way for both the button and frame component.