CARD91 NSDL AADHAAR KYC SDK React Native Implementation

Card91 NSDL AADHAAR KYC SDK React Native Implementation for Android

Card91 NSDL AADHAAR KYC Android Library Integration with React Native Android Apps

Description

Purpose of this document is to illustrate the method to add Card91 ‘Card91KYC’ android library to any react native application written in java and react native.

Card91 Card91KYC library allows developers to launch the Card91KYCActivity activity from their application to process and complete the aadhaar XML full KYC for NSDL cards.

Developers need to launch Card91KYCActivity from their android native class on the react native application with some required parameters mentioned below and a library completing the aadhaar KYC for the NSDL cards.

Installation (Gradle and Manifest Configuration) Android

Android Minimum Requirements :

Gradle Version - 7.3.3
minSdkVersion - 26
compileSdkVersion - 33
targetSdkVersion - 33

Android Permission on Manifest:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />

Reference gradle-wrapper.properties

distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip

Gradle dependencies

Add the provided "aadhaarsdk2-1.0.7.aar","nsdlkyc_card91.aar" aar (AAR files will be provide by the Card91 team) file SDK on the given location of the react application (android folder).
Path: src/main/java/com/{project_folder_name}/lib

dependencies {
  implementation fileTree(dir: "src/main/java/com/{project_folder_name}/lib", include: ["aadhaarsdk2-1.0.7.aar","nsdlkyc_card91.aar"])
    // Add the "aadhaarsdk2-1.0.7.aar","nsdlkyc_card91.aar"
    // The version of react-native is set by the React Native Gradle Plugin
    implementation("com.facebook.react:react-android")
    implementation 'com.facebook.react:react-native:+'  // From node_modules

    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.navigation:navigation-fragment:2.5.3'
    implementation 'androidx.navigation:navigation-ui:2.5.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.github.bumptech.glide:glide:4.12.0'

    debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
    debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.squareup.okhttp3', module:'okhttp'
    }

    debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
    if (hermesEnabled.toBoolean()) {
        implementation("com.facebook.react:hermes-android")
    } else {
        implementation jscFlavor
    }
}


📘

Note

Clean and Build the android app to get the dependencies added on to the application

Launch Card91KYCActivity (Aadhaar SDK) from react application android native module class

Library class will be ready to use after adding on gradle.
Launch Card91KYCActivity from react application android native module class.

Make sure to register the launch so as to get the result from the library when the library gets finish() or setResult(), after completing the KYC process or any other exception.
Below is the code snippet which will help developer understand how its supposed to be handled.
Prepare a call back listener.

📘

Note

Please refer to section "React Native Code Set Up" for setting up the react native code to communicate with Android native class "NsdlAadhaarKycModule"

Eg: NsdlAadhaarKycModule with onActivityResult()

 class NsdlAadhaarKycModule extends ReactContextBaseJavaModule implements ActivityEventListener {

    NsdlAadhaarKycModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }
   	private Callback callBack = null;

    @Override
    public void initialize() {
        super.initialize();
    }

    @Override
    public String getName() {
        return "NsdlAadhaarKycModule";
    }

    @ReactMethod
    void navigateToAadhaarKYCSDK(String MOBILE,String AUTH_TOKEN,String ENV,String PAN, Callback handleCallBack) {
        try {
          	callBack =handleCallBack;
            ReactApplicationContext context = getReactApplicationContext();
            context.addActivityEventListener(this);

            AppCompatActivity myActivity = (AppCompatActivity) getCurrentActivity();

            Intent intent = new Intent(context, Card91KYCActivity.class);
            intent.putExtra("MOBILE",MOBILE);// User registered mobile number
            intent.putExtra("AUTH_TOKEN",AUTH_TOKEN);// Auth token of card holder
            intent.putExtra("ENV",ENV); // "PROD_SANDBOX" for sandbox and "PROD" production environment
            intent.putExtra("PAN",PAN);//PAN of card holder 
            Bundle bundle = new Bundle();
            context.startActivityForResult(intent, 100,bundle);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, @Nullable Intent data) {
        Log.w("onActivityResult", "result code="+resultCode);

        if (resultCode == Activity.RESULT_OK || resultCode == Activity.RESULT_CANCELED)
        {
                Bundle bundle = data.getExtras();
                if (bundle != null)
                {
                    String type = bundle.getString("COMPLETE_KYC_SUCCESS");
                    Log.e("Type----",type.toString());
                    String code = bundle.getString("KYC_RESPONSE_DATA");
                    Log.e("Code----",code.toString());
                    String message = bundle.getString("KYC_RESPONSE_CODE");
                    Log.e("Message----",message.toString());
                  	callBack.invoke(type,code,message);

                }
                else
                {
                    Toast.makeText(activity, "No data found", Toast.LENGTH_LONG).show();
                }
        }

    }

    @Override
    public void onNewIntent(Intent intent) {
        Log.w("onNewIntent", "When new intent is called"+intent);

    }
}

Important

📘

Note

In order to make sure a registered user successful aadhaar KYC completion, user must invoke the SDK with same mobile number which is linked to aadhaar number and name should be same on PAN number and aadhaar number.

NSDL AADHAAR KYC PROCESS EVENTS

SDK went to through several steps to make sure KYC happens successfully.

KYC can be completed either through already downloaded aadhaar XML or by validating the aadhaar number through OTP.

Finally SDK validate all the information provided is correct and hence result in FAILED or SUCCESS event call back.
Below some event with meaning.

  Bundle bundle = data.getExtras();
  if (bundle != null)
  {
     String type = bundle.getString("COMPLETE_KYC_SUCCESS");
     Log.e("Type----",type.toString());
    /// SUCCESS when kyc completed successfully and FAILED when it failed 
     String code = bundle.getString("KYC_RESPONSE_DATA");
    // Response data will contain the message from the SDK
     Log.e("Code----",code.toString());
     String message = bundle.getString("KYC_RESPONSE_CODE");
     // Code signify whats the reponse "00" in case of success 
   	callBack.invoke(type,code,message); // Call the react native call back functiion with response data
    /*
    00—success
    06-Service Not Found
    07-Micro Panda services down
    99- Failure
    14 --Invalid checksum
    */
      Log.e("Message----",message.toString());

   }

INPUT PARAMETER DETAILS WHICH LAUNCHING THE SDK ACTIVITY

NameTypeRequiredDescription
MOBILEstringtrueRegistered card holder mobile number (12 digit) with 91
AUTH_TOKENstringtrueCard Holder auth token (Card91 API)
ENVstringtrue"PROD_SANDBOX" for sandbox and "PROD" production environment
PANstringtrueRegistered card holder valid pan number

DIFFERENT CALLBACK EVENTS

The events are as follows:

Event NameDescription
SUCCESSOn successful aadhaar KYC completion, developer needs to parse "bundle.getString("COMPLETE_KYC_SUCCESS")" for the same. In this scenario "KYC_RESPONSE_CODE" will comes as 00 and "COMPLETE_KYC_SUCCESS" key value will be "SUCCESS"
FAILEDOn un successful aadhaar KYC completion, developer needs to parse the key "COMPLETE_KYC_SUCCESS" from the bundle, value be "FAILED". In this scenario "KYC_RESPONSE_CODE" will not comes as 00 and detail reason will on the key "KYC_RESPONSE_DATA"

React Native Code Set Up (React Native and Android Native Class Communication)

Create a NsdlAadhaarKycModule Native Module

In the following guide you will create a native module, NsdlAadhaarKycModule, that will allow you to access Android’s native function to invoke the SDK from JavaScript. By the end, you will be able to call NsdlAadhaarKycModule.navigateToAadhaarKYCSDK('', '','',''); from JavaScript, invoking a Java/Kotlin method that invokes the aadhaar SDK.

📘

Note

Please refer https://reactnative.dev/docs/native-modules-android?android-language=java for detail on how to communicate with android native modules

SETUP

To get started, open up the Android project within your React Native application in Android Studio. You can find your Android project here within a React Native app:
We recommend using Android Studio to write your native code. Android studio is an IDE built for Android development and using it will help you resolve minor issues like code syntax errors quickly.

We also recommend enabling Gradle Daemon to speed up builds as you iterate on Java/Kotlin code.

Create A Custom Native Module File

The first step is to create the (NsdlAadhaarKycModule.java or NsdlAadhaarKycModule.kt) Java/Kotlin file inside android/app/src/main/java/com/your-app-name/ folder (the folder is the same for both Kotlin and Java). This Java/Kotlin file will contain your native module Java/Kotlin class.

Then add the following content:

package com.your-apps-package-name; // replace your-apps-package-name with your app’s package name  
import com.facebook.react.bridge.NativeModule;  
import com.facebook.react.bridge.ReactApplicationContext;  
import com.facebook.react.bridge.ReactContext;  
import com.facebook.react.bridge.ReactContextBaseJavaModule;  
import com.facebook.react.bridge.ReactMethod;  
import java.util.Map;  
import java.util.HashMap;

public class NsdlAadhaarKycModule extends ReactContextBaseJavaModule {  
   NsdlAadhaarKycModule(ReactApplicationContext context) {  
       super(context);  
   }  
}

As you can see, your NsdlAadhaarKycModule class extends the ReactContextBaseJavaModule class. For Android, Java/Kotlin native modules are written as classes that extend ReactContextBaseJavaModule and implement the functionality required by JavaScript.

📘

Note

It is worth noting that technically Java/Kotlin classes only need to extend the BaseJavaModule class or implement the NativeModule interface to be considered a Native Module by React Native.

📘

Note

However we recommend that you use ReactContextBaseJavaModule, as shown above. ReactContextBaseJavaModule gives access to the ReactApplicationContext (RAC), which is useful for Native Modules that need to hook into activity lifecycle methods. Using ReactContextBaseJavaModule will also make it easier to make your native module type-safe in the future. For native module type-safety, which is coming in future releases, React Native looks at each native module's JavaScript spec and generates an abstract base class that extends ReactContextBaseJavaModule.

Module Name

All Java/Kotlin native modules in Android need to implement the getName() method. This method returns a string, which represents the name of the native module. The native module can then be accessed in JavaScript using its name. For example, in the below code snippet, getName() returns "NsdlAadhaarKycModule".

// add to NsdlAadhaarKycModule.java  
@Override  
public String getName() {  
   return "NsdlAadhaarKycModule";  
}

Export a Native Method to JavaScript

Next you will need to add a method to your native module that will create calendar events and can be invoked in JavaScript. All native module methods meant to be invoked from JavaScript must be annotated with @ReactMethod.

Set up a method navigateToAadhaarKYCSDK() for NsdlAadhaarKycModule that can be invoked in JS through NsdlAadhaarKycModule.navigateToAadhaarKYCSDK(). For now, the method will take in a name as strings. Argument type options will be covered shortly.

@ReactMethod  
public void navigateToAadhaarKYCSDK(String MOBILE,String AUTH_TOKEN,String ENV,String PAN,Callback handleCallBack) {  
}

Add a debug log in the method to confirm it has been invoked when you call it from your application. Below is an example of how you can import and use the Log class from the Android util package:

import android.util.Log;

@ReactMethod  
public void navigateToAadhaarKYCSDK(String MOBILE,String AUTH_TOKEN,String ENV,String PAN,Callback handleCallBack ) { 
  // Write the code here to invoke the SDK
   Log.d("NsdlAadhaarKycModule", "Create event called with name: " + name);  
}

Once you finish implementing the native module and hook it up in JavaScript, you can follow these steps to view the logs from your app.

At the moment, we do not recommend this, since calling methods synchronously can have strong performance penalties and introduce threading-related bugs to your native modules. Additionally, please note that if you choose to enable isBlockingSynchronousMethod, your app can no longer use the Google Chrome debugger. This is because synchronous methods require the JS VM to share memory with the app. For the Google Chrome debugger, React Native runs inside the JS VM in Google Chrome, and communicates asynchronously with the mobile devices via WebSockets.

Register the Module (Android Specific)
Once a native module is written, it needs to be registered with React Native. In order to do so, you need to add your native module to a ReactPackage and register the ReactPackage with React Native. During initialization, React Native will loop over all packages, and for each ReactPackage, register each native module within.

React Native invokes the method createNativeModules() on a ReactPackage in order to get the list of native modules to register. For Android, if a module is not instantiated and returned in createNativeModules it will not be available from JavaScript.

To add your Native Module to ReactPackage, first create a new Java/Kotlin Class named (MyAppPackage.java or MyAppPackage.kt) that implements ReactPackage inside the android/app/src/main/java/com/your-app-name/ folder:

Then add the following content:

package com.your-app-name; // replace your-app-name with your app’s name  
import com.facebook.react.ReactPackage;  
import com.facebook.react.bridge.NativeModule;  
import com.facebook.react.bridge.ReactApplicationContext;  
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;  
import java.util.Collections;  
import java.util.List;

public class MyAppPackage implements ReactPackage {

   @Override  
   public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {  
       return Collections.emptyList();  
   }

   @Override  
   public List<NativeModule> createNativeModules(  
           ReactApplicationContext reactContext) {  
       List<NativeModule> modules = new ArrayList\<>();
               modules.add(new NsdlAadhaarKycModule(reactContext));

   return modules;
             }

}

This file imports the native module you created, NsdlAadhaarKycModule. It then instantiates NsdlAadhaarKycModule within the createNativeModules() function and returns it as a list of NativeModules to register. If you add more native modules down the line, you can also instantiate them and add them to the list returned here.

It is worth noting that this way of registering native modules eagerly initializes all native modules when the application starts, which adds to the startup time of an application. You can use TurboReactPackage as an alternative. Instead of createNativeModules, which return a list of instantiated native module objects, TurboReactPackage implements a getModule(String name, ReactApplicationContext rac) method that creates the native module object, when required. TurboReactPackage is a bit more complicated to implement at the moment. In addition to implementing a getModule() method, you have to implement a getReactModuleInfoProvider() method, which returns a list of all the native modules the package can instantiate along with a function that instantiates them, example here. Again, using TurboReactPackage will allow your application to have a faster startup time, but it is currently a bit cumbersome to write. So proceed with caution if you choose to use TurboReactPackages.

To register the CalendarModule package, you must add MyAppPackage to the list of packages returned in ReactNativeHost's getPackages() method. Open up your MainApplication.java or MainApplication.kt file, which can be found in the following path: android/app/src/main/java/com/your-app-name/.

Locate ReactNativeHost’s getPackages() method and add your package to the packages list getPackages() returns:

@Override  
  protected List<ReactPackage> getPackages() {  
    @SuppressWarnings("UnnecessaryLocalVariable")  
    List<ReactPackage> packages = new PackageList(this).getPackages();  
    // below MyAppPackage is added to the list of packages returned  
    packages.add(new MyAppPackage());  
    return packages;  
  }

You have now successfully registered your native module for Android!

Test What You Have Built
At this point, you have set up the basic scaffolding for your native module in Android. Test that out by accessing the native module and invoking its exported method in JavaScript.

Find a place in your application where you would like to add a call to the native module’s createCalendarEvent() method. Below is an example of a component, NewModuleButton you can add in your app. You can invoke the native module inside NewModuleButton's onPress() function.

/**
 * Sample React Native App
 *
 * adapted from App.js generated by the following command:
 *
 * react-native init example
 *
 * https://github.com/facebook/react-native
 */

import React, {Component} from 'react';

import {Button, NativeModules, StyleSheet, Text, View} from 'react-native';

export default class App extends Component<{}> {
  render() {
    const callbackSuccess = (type: string, code: string, message: string) => {
      console.log('callback', type, code, message);
    };
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>☆React Native CARD91 Sdk example☆</Text>
        <Text style={styles.instructions}>STATUS: loaded</Text>
        <Text style={styles.welcome}>☆☆☆</Text>
        <Button
          onPress={() => {
            try {
              NativeModules.NsdlAadhaarModule.navigateToCustomerSDK(
                '918056225447',
                'C91CHg5N5dc4UTyE/5wAaC1nvic1zo/aM7ArW8hQRcC37OGk=',
                'PROD_SANDBOX',
                'AJHPL7288B',
                callbackSuccess,
              );
            } catch (error) {
              console.log(error);
            }
          }}
          title="Open new SDK"
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

export default NewModuleButton;

In order to access your native module from JavaScript you need to first import NativeModules from React Native:

import {NativeModules} from 'react-native';

You can then access the NsdlAadhaarKycModule native module off of NativeModules.

const {NsdlAadhaarKycModule} = NativeModules;

Now that you have the CalendarModule native module available, you can invoke your native method navigateToCustomerSDK(). Below it is added to the onPress() method in NewModuleButton:

try {
              NativeModules.NsdlAadhaarModule.navigateToCustomerSDK(
                '918056225447', /// Register user mobile number
                'C91CHD/NXtVRyz6g1jYN8MybBXjOlXvxJ2mjHY7dkjUNf3zs=',// Card holder auth token
                'PROD_SANDBOX', // "PROD_SANDBOX" for production sandbox and "PROD" for production 
                'AJHPL7288B', // card holder pan number for intitiating KYC
                callbackSuccess,// Call back instance to recieve the reponse data from android native class
              );
            } catch (error) {
              console.log(error);
            }

The final step is to rebuild the React Native app so that you can have the latest native code (with your new native module!) available. In your command line, where the react native application is located, run the following:

npm run android