Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Div
classdeveloper-cookbook-inner-page-title
HTML Table
classtagline-page-title
Table Row (tr)
Table Cell (td)
classtitle-text

Learn how to integrate Cipher SDK on Android device.

Cipher SDK is a Two Factor Authentication (2FA) solution designed to provide a secure way of verifying transactions. This is achieved by enabling customers to verify their identity. Cipher SDK ensures a safe implementation of 2FA with minimum friction without the need of OTP generation .

In this article, you will learn how to integrate Android Cipher SDK.

Before you begin

Take care of the following prerequisites before you begin with SDK setup:

  • Minimum Android SDK version required: 19
  • Minimum Java Runtime Environment (JRE) version required: 8
  • Ensure you have a cipher.json file which contains configuration data necessary to set up the SDK. Contact Zeta in case if you haven't received the file.
  • Fusion uses authentication token to authenticate the SDK. To know how to generate an authentication token, see Authenticating SDK.
  • Set up a Firebase project for your app and register your Cloud Messaging server key in our dashboard. You need this to integrate the Swipe to Authenticate feature of SDK.

Getting Started with Android Cipher SDK

Follow the steps below to integrate SDK:

  1. First, you should add the SDK to your project or app.
  2. Prepare the SDK setup.
  3. Now the SDK setup is ready to begin with integration process.

Anchor
addthesdk
addthesdk
Step 1: Adding the SDK

The Android SDK is compatible with apps supporting Android with version 4.4 to 4.4.4 or API level 19 and above. To add the SDK to your project, follow these steps:

  1. Add the following rule to your project-level gradle file. This downloads the Maven repository which holds all the build artifacts and dependencies necessary for your project.

    Code Block
    themeMidnight
    titleProject build.gradle
    linenumberstrue
    collapsetrue
    allprojects {
        repositories {
            ....
            maven {
                credentials  {
                    username = "<username>"
                    password = "<password>"
                }
                url 'https://apollo-sdk.zetaapps.in/repository/maven-releases/'
                authentication {
                    basic(BasicAuthentication)
                }
            }
            maven {
                credentials  {
                    username = "<username>"
                    password = "<password>"
                }
                url 'https://apollo-sdk.zetaapps.in/repository/maven-snapshots/'
                authentication {
                    basic(BasicAuthentication)
                }
            }
            ....        
        }
    }
    configurations.all {
        // Add this if you face issue related to rxjava2
        resolutionStrategy.force "io.reactivex.rxjava2:rxandroid:2.1.0"
        }
    }
    Info
    • We recommend to maintain the order of including the repositories as mentioned in the above code for project-level gradle.
    • You will receive a document that contains maven user credentials for the above code.
  2. In your module app-level gradle file, add the following rules:

    Code Block
    themeMidnight
    titleapp build.gradle
    linenumberstrue
    collapsetrue
    android {
    …….
        defaultConfig {
    	//Use this for debug build 
    multiDexEnabled true
        }
        ........
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        
        kotlin_options = {
           jvmTarget = "1.8"
        }
        // Include this if you face packing errors ..
        packagingOptions {
            exclude 'META-INF/library_release.kotlin_module'
            exclude 'META-INF/DEPENDENCIES'
        }
        ........
    }
    
    dependencies {
      ………...
      implementation ("in.zeta.apollo:cipher:<cipher_version>")
    }

    Following are the descriptions of different modules in app-level gradle code:

    • multiDexEnabled: Optional. Add this for debugging the build if you overshoot the 64K methods ceiling.

    • compileOptions: Required. Add support for Java 8 language features.

    • packagingOptions: Optional. Add this only if you face packaging error.

    • dependencies: Required. Include Cipher SDK dependencies for the latest version.

Anchor
sdksetup
sdksetup
Step 2: Setting up the SDK

Follow the steps below to set up the SDK:

Add the configuration file

A configuration file contains all the properties necessary for activating the SDK. You should add the file to your project (app/src/main/assets/) to prepare your app to work with the SDK. You will receive the configuration file named cipher.json through email. If you haven't received the file, contact Zeta.

Initialize the SDK

In the onCreate() method of your application class, create a in.android.zeta.cipher instance.

Code Block
themeMidnight
titleCipherService instance
linenumberstrue
final CipherService cipherService = new CipherBuilder(this)
.setTenantSecuredStoreAccess(securedStoreAccess) // AppSecuredStoreAccess - To be provided when using the tenant secured store.
.setUseDeviceLock(false) // Enable this when you want to use device lock. Application when setUseCustomStore is set as false. This is set as true by default.
.setUseCustomStore(true)// Set this true if you want to provide an implementation of your own secured store. This is set as false by default.
.setSuperPinExceptionListener(superPinExceptionListener)
.setNotificationIcon(notificationResourceId) // Use this to set the notification icon when using Swipe to Authenticate. Required if using swipe to authenticate.
.build();
Info

If you are using Timber for logging, please initialize it after this step.

Set up the Secured Store

Cipher SDK maintains various pieces of sensitive information like Super PIN, secrets. The SDK stores this sensitive information in a Secured Store. Cipher SDK supports the following Secured Store implementations:

SDK implementation

Cipher SDK provides an implementation of the Secured Store out of the box. The SDK provided secured store supports the following:

  • Device lock:
    The device lock is enabled by default. To disable the device lock, add setUseDeviceLock(false) in CipherService instance of CipherBuilder.

  • SDK Super PIN:
    The SDK uses Super PIN by default if you don't enable device lock and access to your custom secured store. In this case, we prompt you to set up the SDK PIN for securing sensitive data.

Note

Ensure you run setParentActivityForAuth before accessing the Super PIN and Swipe to Authenticate functionalities .

Anchor
Hosting app’s custom implementation
Hosting app’s custom implementation
Hosting app’s custom implementation

If you want to use your custom secured store, use the setUseCustomStore(bool) API in CipherBuilder. Now you are ready to provide an implementation for the AppSecuredStoreAccess interface using setTenantSecuredStoreAccess() . This interface enables the secured store to store sensitive data.

Code Block
themeMidnight
titleApp Secured Store Access Interface
linenumberstrue
collapsetrue
public interface AppSecuredStoreAccess {
   interface SetaDataInSecureStoreListener {
       void done(final boolean success, final Exception exp);
   }
   void setDataInSecureStore(@NonNull final String key, final byte[] data, @NonNull final SetaDataInSecureStoreListener listener);
   interface GetDataInSecureStore {
       void done(final byte[] data, final Exception exp);
   }
   void getDataFromSecureStore(@NonNull final String key, @NonNull final GetDataInSecureStore listener);
   boolean contains(@NonNull final String key);
}

Anchor
VerifytheSDK
VerifytheSDK
Step 3: Integrating the SDK

Cipher SDK is a stateful SDK. Before you start using the Super PIN feature of SDK, take care of the following:

Set up a Secured Store

Use isSecureStoreSetupRequired() to check if you need to execute this step. Call setupSecuredStore(activity, listener) to set up the Secured Store.

Set up a Super PIN

Use isSuperPinSetupRequired() to check if you need to execute this step. Call setupSuperPin(listener) to set up a Super PINOnce the Super PIN integration flow is successful isSuperPinSetupDone() returns true.

Following is a code snippet to check the state of the SDK and take appropriate action:

Code Block
languagejs
themeMidnight
titleCipher Service Actions
linenumberstrue
if(cipherService.isSecureStoreSetupRequired()) {
	// You are now ready to setup the secure store as instructed by the AppSecuredStoreAccess
} else if(cipherService.isSuperPinSetupRequired()){
	// You are ready to call setupSuperPin()
} else if(cipherService.isSuperPinSetupDone()){
	// You are ready to trigger getSuperPin() API
}

Set up Swipe to Authenticate

The Swipe to Authenticate flow is set up along with the  set up of the Super PIN flow. At Zeta, we use Firebase Cloud Messaging (FCM) to deliver Swipe to Authenticate notifications to your app. You should set up a Firebase project for your app if you have not done that already. Here are the details on how to do this. After setting up the Firebase project for your app, please share your FCM server key with our team at Zeta. We will use your FCM server key to deliver notifications to your app from our server. You will receive senderId which you can use to identify the push sent by Zeta to your app. If you don’t receive a senderId, there is an alternate way to identify the Swipe to Authenticate push as mentioned in Listen to Swipe to Authenticate Push.

Note

Your app should have Draw over other apps permission to show Swipe to Authenticate prompt over other apps or when your app is closed. Otherwise, you will be notified about the a Swipe to Authenticate request on the notification tray.

Syncing the push token

You should override your onNewToken() inside your FirebaseMessagingService. Then call onPushTokenUpdated() whenever you receive a callback for the new push token. This helps us to keep the push token synced in our servers and ensure a hassle-free push experience. You can use the following code snippet.

Code Block
themeMidnight
linenumberstrue
override fun onNewToken(token: String) {
   cipherService.onPushTokenUpdated()
}

Listen to Swipe to Authenticate Push

When you receive a push notification inside the overridden onMessageReceived() method of your FirebaseMessagingService, you should relay that RemoteMessage received to Cipher SDK if you receive the message from our senderID. You can use  handleNotification() method to relay the push message object to the Cipher SDK. You can use the following code snippet.

Code Block
themeMidnight
linenumberstrue
override fun onMessageReceived(remoteMessage: RemoteMessage) {
      if(<zeta_sender_id>.equals(remoteMessage.from)) {
	     cipherService.handleNotification(remoteMessage)
      }
}

Alternatively, you can also look for the key acsRequestOTP in the data payload of the RemoteMessage. You can use the following code snippet

Code Block
themeMidnight
linenumberstrue
override fun onMessageReceived(remoteMessage: RemoteMessage) {
      if(remoteMessage.getData().containsKey("acsRequestOTP")) {
	     cipherService.handleNotification(remoteMessage)
      }
}

Anchor
ConfiguretheSDK
ConfiguretheSDK
API Reference

Cipher SDK provides a set of public APIs which are useful to set up the SDK and access its functionalities.

Authenticate the SDK

You can access the Cipher SDK by going through the authentication process. First, you should generate an authentication token (tenantAuthToken) and then call this API.  Ensure to call this API to refresh the authentication token in every launch of the app. 

Code Block
themeMidnight
authenticate(tenantAuthToken: String) - Returns void

Set up Secured Store

If a call to isSecureStoreSetUpRequired() returns true, you are ready to set up the Secured Store by triggering the setUpSecuredStore().

  1. Check the state of Cipher SDK.

    This API tells if the SDK needs a Secured Store setup. Only after this step, the SDK will be able to set up the Swipe To Authenticate and Super PIN.

    Code Block
    themeMidnight
    isSecureStoreSetupRequired() - Return boolean
  2. Call setupSecuredStore()

    A call to the API setupSecuredStore() triggers the setup of Secured Store. Ensure you call setupSecureStore() to set up the Secured Store only when isSecureStoreSetupRequired returns true. If the API returns an exception in the listener, call Logout() before retrying.

    Code Block
    themeMidnight
    setupSecuredStore(activity: Activity, listener: SecureStoreSetupListener) - Returns void

Set up the Super PIN

If a call to isSuperPinSetupDone() API returns true, you can generate a Super PIN to secure the store by triggering setupSuperPin(listener: SetupSuperPinListener) API.

  1. Check the state of Cipher SDK.

    This API tells if the Super PIN setup is done or not. If this method returns true, the Super PIN setup is done. If the Super PIN functionality doesn’t work, the SDK might be in an error state. You can get the error state using the superPinExceptionListener in CipherService instance.

    Code Block
    themeMidnight
    isSuperPinSetupDone() - Returns boolean
  2. Set up the Super PIN
    A call to this API creates a Super PIN. The Super PIN can be setup only when CipherSerivce.isSuperPinSetupRequired() returns true. If this setup fails and issue persists, contact Zeta.

    Code Block
    themeMidnight
    setupSuperPin(listener: SetupSuperPinListener)
  3. Retrieve the Super PIN

    This API returns the Super PIN and it’s Time To Live (TTL) on providing authentication to the Secured Store or device lock. Use this Super PIN to authorize the payment.

    Code Block
    themeMidnight
    getSuperPin(GetSuperPinListener listener)

Set up a parent activity for Secured Store

Set the parent activity on top of which we want to show the Super PIN or device lock. Use this option when you are setting up the Secured Store using the  SDK implementation.

Code Block
themeMidnight
setParentActivityForAuth(Activity activity)

Adding Listener

You can listen to any change in the state of Cipher SDK integration such as, when an authentication token is required, is Secured Store set up required, can Super PIN be generated.

Use this method is used to subscribe to SDK state updates.

Code Block
themeMidnight
setCipherStateUpdateListener(listener: CipherStateUpdateListener)
Note

This method is deprecated and no longer advised to be used. Instead use the the listeners in the different methods.

Handle notification

This method helps you to communicate the notification data payload to the Cipher SDK. If you receive a notification from our senderID, you should relay the notification to the SDK and it will take care of the notification .

Code Block
themeMidnight
handleNotification(data: Map<String, String>) - Returns void

Monitor token update

Please ensure that you call this method on every update of the firebase push token. See Monitor token generation for more details.

Code Block
themeMidnight
onPushTokenUpdated() - Return void

Logout

Ensure to call the Logout API in events like switching the user by logging out from the app. This ensures the latest token is in-place to set up the next authentication session. Thereby, this also validates the local authentication session. After a logout call, the SDK reaches the initial state, and then you should set up the SDK again from the first step. 

A simple logout is available by using:

Code Block
themeMidnight
titleLogout
cipherService.logout()

Exceptions and error codes

This section explains various exceptions and error codes thrown by the Cipher SDK and how to handle them. Exceptions provide system error codes along with Throwable message, that helps to recognize and troubleshoot the issue.

All the exceptions thrown will have the following fields in addition to the message:

  1. code: Error code related to the response.
  2. traceId: Trace ID which can be provided to Zeta support for identifying the root cause.
  3. errorType: Type of error.

There are two kinds of exceptions that Cipher SDK can throw:

  • SdkAuthException
  • CardsSdkException
Info

All the exception classes extend the ApolloException.

The sample error response below shows server-side error code and message returned in case of any error:

Code Block
themeMidnight
titleSample Error Response
apollo@console$ in.zeta.apollo.sdkauth.SdkAuthException: The tenantAuthToken token set seems invalid. Please check the parameters and signature to create the token
SdkAuthException.code: SDKAUTH_ERR_001


The following table lists the error codes, descriptions and possible solutions. If the issue persists, contact Zeta.

Error CodeDescription

ERR_001

Exception thrown due to bad request.
ERR_002Internal server error. Try again.
ERR_003Internal SDK error. Try logging out and then log in.
SDKAUTH_ERR_001

Following are the potential reasons for failure of an authentication token:

  • Token is signed with an invalid private key.
  • Token does not contain the configured claim.
  • Token has expired.
SDKAUTH_ERR_002Internal error caused while trying to authenticate the user.
CIPHERSDK_ERR_001Error occurred when user cancels the Secured Store setup.
Info

To know more about exceptions and error codes handling, contact Zeta.

Panel
Div
classalignLeftIcon

On this page:

Table of Contents

Div
classhelp-box

Need Help?

Drop a mail at fusion-support@zeta.tech or call us on 080-6690 5995.