Okay LogoOkay Logo

Get started with Android

Use our SDK for Android apps

Get started with Android
Example

If you want to test out the Okay solution, we strongly recommend that you first do a test using the Okaythis application, found either in the play store or app store, which already implements SDK. Use it with the with our guide on how to Integrate the Okay app with your service, and once that is done you can try to connect with the SDK.

If you would like to use our SDK with your Android application, we also recommend scheduling a demo, so we can help guide you through the integration steps. But, if both of those steps are done you’re in the right place.

Remember, if you are having trouble with our SDK or Push Notifications (which use Firebase), please send us an email at developer@okaythis.com.

Click here to see the full code sample on GitHub

In your app's build.gradle add this:

android {

...

// add these lines to your gradle file

dataBinding {

enabled = true

}

compileOptions {

sourceCompatibility 1.8

targetCompatibility 1.8

}

}

dependencies {

implementation 'com.okaythis.sdk:psa:XXX'

}

Add this to your project's build.gradle file:

allprojects {

repositories {

google()

jcenter()

maven {

url "https://gitlab.okaythis.com/api/v4/projects/15/packages/maven"

name "GitLab"

}

}

}

In your app, you need to configure the receiver for Firebase Cloud Messages.

You should save the Firebase instanceId for later usage - that will be your appPNS.

The Okay secure server will a send push notification to your app when the user authorisation scenario is launched. Okay secure server must be properly configured in order to send these push notifications.

You will also need to set up Firebase for our project. If you are not familiar with integrating Firebase messaging, please check out this document for more information, as Okay SDK depends on it!

dependencies {

implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

implementation 'androidx.appcompat:appcompat:1.1.0'

implementation 'androidx.core:core-ktx:1.1.0'

implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

implementation 'com.google.android.material:material:1.0.0'

testImplementation 'junit:junit:4.12'

androidTestImplementation 'androidx.test:runner:1.2.0'

androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

// Okay dependency

implementation 'com.okaythis.sdk:psa:XXX'

// Firebase dependency

implementation 'com.google.firebase:firebase-messaging:XXX'

}

We can now sync our app's gradle file to build.


The Okay service allows tenants to be able to configure the Okay service to use Firebase as the Push notification service provider for Android.

In order to have the Okay service send push notification requests through Firebase to Android devices, you are required to provide your Firebase cloud messaging server key on your tenant settings page which can be found here.

In order for the Okay SDK to work correctly, we will need to sync the SDK with Okay's secure server. Initialisation of the Okay secure SDK should be done within our Application class, using the onCreate() method.

We use the PsaManager class from Okay to initialise our PSA. We will be using two methods from the PsaManager class: the init() and setPssAddress() methods. The init() and setPssAddress() method from the PsaManager class has the following structure:

PsaManager psaManager = PsaManager.init(this, T extends ExceptionLogger);

psaManager.setPssAddress(PSS_SERVER_ENDPOINT);

Here is a typical illustration of what our Application class should look like at this point:

// OkayDemoApplication.kt

class OkayDemoApplication: Application() {

override fun onCreate() {

super.onCreate()

initPsa()

}

private fun initPsa() {

val psaManager = PsaManager.init(this, OkayDemoLogger())

psaManager.setPssAddress("https://demostand.okaythis.com")

}

}

This is what a minimal OkayDemoLogger class looks like:

class OkayDemoLogger: ExceptionLogger { override fun setUserIdentificator(p0: String?) { Log.e("SET ID: ", "Successfully set user identificator $p0 ") } override fun exception(p0: String?, p1: Exception?) { Log.e("Exception: ", "Okay Error $p0 -- Exception: $p1") } }

We will need to add our application class to our manifest file like so:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ogieben.okaydemo"> <application android:name=".OkayDemoApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> ... </application>

The Okay SDK requires certain kinds of permissions to work properly. We will have to ask our users to grant those permissions before we proceed. We can easily create helper-methods to handle permission resolution for us:

// PermissionHelper.kt class PermissionHelper(private val activity: Activity) { val REQUEST_CODE = 204 fun hasPermissions(ctx: Context, permission: Array<String>): Boolean = permission.all { ActivityCompat.checkSelfPermission(ctx, it) == PackageManager.PERMISSION_GRANTED } fun requestPermissions(permission: Array<String>) = ActivityCompat.requestPermissions(activity, permission, REQUEST_CODE) }

The Okay SDK comes with a pre-packaged PsaManager.getRequiredPermissions() method which helps us fetch an array of required permissions:

// MainActivity.kt val permissionHelper = PermissionHelper(activity) private fun checkPermissions() { // prepacked method val requiredPermissions = PsaManager.getRequiredPermissions() if (!permissionHelper.hasPermissions(this, requiredPermissions)) { permissionHelper.requestPermissions(requiredPermissions) } }

We can now use the checkPermission() method within our MainActivity’s onCreate method to request for full permission:

// MainActivity.kt override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) checkPermissions() }

Firebase PNS Token

We will need our device token from Firebase to be able to use the SDK for enrolment, linking, and authorisation.

If Firebase has been successfully set up, we can request our device token using the code sample below. If you do not have Firebase correctly set up, please refer to this document, as the Okay SDK requires this service to work correctly.

// MainActivity.kt

private var preferenceRepo: PreferenceRepo = PreferenceRepo(context)

private fun fetchInstanceId () {

FirebaseInstanceId.getInstance().instanceId

.addOnCompleteListener(OnCompleteListener { task ->

if (!task.isSuccessful) {

Log.w("", "getInstanceId failed", task.exception)

Toast.makeText(this@MainActivity, "Error could not fetch token", Toast.LENGTH_LONG).show()

return@OnCompleteListener

}

val token = task.result?.token

// save token to SharedPreference storage for easy retrieval

preferenceRepo.persistAppPns(token.toString())

})

}

We can now invoke this method from our onCreate() method within our activity like so:


class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

setSupportActionBar(toolbar)

// request permissions

checkPermissions()

// fetch token

fetchInstanceId()

}

}

If all permissions have been granted and our appPns (also know as Firebase token) has been retrieved successfully, we can now proceed with device enrolment.

PsaManager.startEnrollmentActivity(activity Activity, data SpaEnrollData);

activity - An activity reference that will receive enrollment result from onActivityResult callback.

SpaEnrollData contains:

  • String appPns - Firebase instanceId
  • String pubPss - Should be the same on both app and server.
  • String installationId - Should be the same on both app and server.
  • PageTheme pageTheme - Can be used for the Authorisation UI customisation Document (pass null if you don't need UI customisation)
  • PsaType psaType - Use PsaType.OKAY


private fun beginEnrollment() {

val appPns = preferenceRepo.getAppPns() // retrieve Firebase token from SharedPreference storage

val pubPssB64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxgyacF1NNWTA6rzCrtK60se9fVpTPe3HiDjHB7MybJvNdJZIgZbE9k3gQ6cdEYgTOSG823hkJCVHZrcf0/AK7G8Xf/rjhWxccOEXFTg4TQwmhbwys+sY/DmGR8nytlNVbha1DV/qOGcqAkmn9SrqW76KK+EdQFpbiOzw7RRWZuizwY3BqRfQRokr0UBJrJrizbT9ZxiVqGBwUDBQrSpsj3RUuoj90py1E88ExyaHui+jbXNITaPBUFJjbas5OOnSLVz6GrBPOD+x0HozAoYuBdoztPRxpjoNIYvgJ72wZ3kOAVPAFb48UROL7sqK2P/jwhdd02p/MDBZpMl/+BG+qQIDAQAB"

val installationId = "9990"

val spaEnroll = SpaEnrollData(appPns,

pubPssB64,

installationId,

null,

PsaType.OKAY)

PsaManager.startEnrollmentActivity(this, spaEnroll)

}

After successful enrolment, Okay SDK will trigger an onActivityResult() callback for the activity we passed to startEnrollmentActivity(), returning an intent with the result of our enrolment data. Use PsaIntentUtils.enrollResultFromIntent() to extract enrolment data from Intent. For example:

// MainActivity.kt

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

super.onActivityResult(requestCode, resultCode, data)

if (requestCode == PsaConstants.ACTIVITY_REQUEST_CODE_PSA_ENROLL) {

if (resultCode == RESULT_OK) {

//We should save data from Enrollment result, for future usage

data?.run {

val resultData = PsaIntentUtils.enrollResultFromIntent(this)

resultData.let {

preferenceRepo.saveExternalID(it.externalId)

}

Toast.makeText(applicationContext, "Successfully got this externalId " + resultData.externalId, Toast.LENGTH_SHORT).show()

}

} else {

Toast.makeText(this, "Error Retrieving intent after enrollment", Toast.LENGTH_SHORT).show()

}

}

}

In order to successfully finish the initialisation stage, we need to link the user with Okay. This allows us to authorise/authenticate a particular user's action. The linkingCode is a six-digit number generated for this purpose.

To enable linking on your app, you will need to add a line of code to your app's Application file. In this case, it is going to be OkayDemoApplication.kt.

class OkayDemoApplication: Application() {

override fun onCreate() {

super.onCreate()

initPsa()

// Added this method call

initGatewayServer()

}

private fun initPsa() {

val psaManager = PsaManager.init(this, OkayDemoLogger())

psaManager.setPssAddress("https://demostand.okaythis.com")

}

// Added this method

private fun initGatewayServer() {

GatewayRestServer.init(PsaGsonFactory().create(), "https://demostand.okaythis.com/gateway/")

}

}

This section is divided into two sub-sections. The first section is for developers who do not have a hosted server of their own, but wants to implement linking in their apps. The second section is for developers who already have a hosted server, and want to link their users with Okay. The hosted server can also be a local server, hosted through a tunnelling service such as Ngrok.

For Users Without a Hosted Server

We have created a demo server that illustrates how to generate linking codes, send authorisation requests, and handle Okay webhook callbacks here. You can run this server on your local machine to generate the required linking code.

You can also read more about how the server works on our Integrate Okay app with your service guide.

//MainActivity.kt

class MainActivity : AppCompatActivity() {

private lateinit var preferenceRepo: PreferenceRepo

private val permissionHelper = PermissionHelper(this)

private val retrofitWrapper = RetrofitWrapper()

private val transactionHandler = retrofitWrapper.handleTransactionEndpoints()

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

setSupportActionBar(toolbar)

preferenceRepo = PreferenceRepo(this)

checkPermissions()

fetchInstanceId()

handleIntent(intent)

preferenceRepo.putInstallationId(BuildConfig.INSTALLATION_ID)

preferenceRepo.putPubPssBase64(BuildConfig.PUB_PSS_B64)

enrollmentButton.setOnClickListener { view ->

beginEnrollment()

}

manualLinkButton.setOnClickListener{

// retreive the linkingCode (i.e the linkingCode from editText)

// from the EditTextView entered into the app

val linkingCode = linkingCodeEditText.text.toString()

if(linkingCode.isEmpty()){

Toast.makeText(this, "Linking code can't be empty. Please enter linking code in the input field", Toast.LENGTH_LONG).show()

return@setOnClickListener

}

linkUser(linkingCode)

}

}

fun linkUser(linkingCode: String) {

// grab PsaManager instance

val psaManager = PsaManager.getInstance()

// LinkingScenarioListener listener

val linkingScenarioListener: LinkingScenarioListener = object: LinkingScenarioListener{

override fun onLinkingCompletedSuccessful(var1: Long, var3: String){

Toast.makeText(this@MainActivity, "Linking Successful", Toast.LENGTH_LONG).show()

}

override fun onLinkingFailed(var1: ApplicationState) {

Toast.makeText(this@MainActivity, "Linking not Successful: linkingCode: ${linkingCodeEditText.text} errorCode: ${var1.code} ", Toast.LENGTH_LONG).show()

}

}

// call PsaManager linkTenant method

psaManager.linkTenant(linkingCode, preferenceRepo, linkingScenarioListener)

}

}


For Users With a Hosted Server

We will send a request to our server to start the linking process. If our request was processed successfully, we will receive a response with the linking code required to finish linking.

We created a wrapper class called RetrofitWrapper to handle network requests.

// /network/RetrofitWrapper.kt

class RetrofitWrapper {

private val BASE_URL = "URL_TO_YOUR_SERVER"

fun createClient(): Retrofit {

return Retrofit.Builder()

.baseUrl(BASE_URL)

.addConverterFactory(GsonConverterFactory.create())

.build()

}

fun handleTransactionEndpoints(): TransactionEndpoints {

val retrofit: Retrofit = this.createClient()

return retrofit.create(TransactionEndpoints::class.java)

}

}

We make a very simple POST request to our server to initiate the linking process using our retrofit wrapper like so:

//MainActivity.kt

class MainActivity : AppCompatActivity() {

private lateinit var preferenceRepo: PreferenceRepo

private val permissionHelper = PermissionHelper(this)

private val retrofitWrapper = RetrofitWrapper()

private val transactionHandler = retrofitWrapper.handleTransactionEndpoints()

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

setSupportActionBar(toolbar)

preferenceRepo = PreferenceRepo(this)

checkPermissions()

fetchInstanceId()

handleIntent(intent)

preferenceRepo.putInstallationId(BuildConfig.INSTALLATION_ID)

preferenceRepo.putPubPssBase64(BuildConfig.PUB_PSS_B64)

enrollmentButton.setOnClickListener { view ->

beginEnrollment()

}

linkingButton.setOnClickListener{

// userId is the user's identifier for your service.

// You are required to retrieve this from your server

startServerLinking(userId)

}

}

private fun startServerLinking(userId: String?) {

transactionHandler.linkUser(userId).enqueue(object: Callback<OkayLinking>{

override fun onFailure(call: Call<OkayLinking>, t: Throwable) {

Toast.makeText(this@MainActivity, "Error making request to Server ${t.localizedMessage}", Toast.LENGTH_LONG).show()

t.printStackTrace()

}

override fun onResponse(call: Call<OkayLinking>, response: Response<OkayLinking>) {

// Retrieve user linkingCode here after network call

// then link user afterwards by passing linkingCode

// to PsaManager.linkingTenant() method

}

})

}

}

After we successfully generated the linking code, we can now proceed to link the user with Okay SDK.

PsaManager provides us with a helper function that allows us to link users with SPS right from Okay SDK. This is what the method’s signature looks like:

PsaManager.linkTenant(linkingCode: String, spaStorage: SpaStorage, linkingScenarioListener: LinkingScenarioListener)

The last parameter is a LinkingScenarioListener which must be implemented. This listener allows us to listen for two possible events: onLinkingCompletedSuccessful and onLinkingFailed. We will be implementing this listener in one of the code snippets below. See linkUser(linkingCode: String) method body.

We will also need to implement the SpaStorage interface in our application. The easiest way to implement this class is to implement it as one of your repositories (PreferenceRepo class as shown in the following example).

This is a typical example of what an implementation of the SpaStorage interface class looks like:

class PreferenceRepo(context: Context): SpaStorage { private val prefStorage: SharedPreferences = context.getSharedPreferences(PREFERENCE_KEY, Context.MODE_PRIVATE) override fun getPubPssBase64(): String? { return prefStorage.getString(PUB_PSS_B64, "") } override fun putAppPNS(p0: String?) { with(prefStorage.edit()) { putString(APP_PNS, p0) commit() } } override fun putPubPssBase64(p0: String?) { with(prefStorage.edit()) { putString(PUB_PSS_B64, p0) commit() } } override fun getAppPNS(): String? { return prefStorage.getString(APP_PNS, "") } override fun getEnrollmentId(): String? { return prefStorage.getString(ENROLLMENT_ID, "") } override fun putInstallationId(p0: String?) { with(prefStorage.edit()) { putString(INSTALLATION_ID, p0) commit() } } override fun putExternalId(p0: String?) { with(prefStorage.edit()) { putString(EXTERNAL_ID, p0) commit() } } override fun putEnrollmentId(p0: String?) { with(prefStorage.edit()) { putString(ENROLLMENT_ID, p0) commit() } } override fun getInstallationId(): String? { return prefStorage.getString(INSTALLATION_ID, "") } override fun getExternalId(): String? { return prefStorage.getString(EXTERNAL_ID, "") } companion object { const val PREFERENCE_KEY = "firebase_instance_id" const val APP_PNS = "app_pns" const val EXTERNAL_ID = "external_id" const val PUB_PSS_B64 = "pub_pss_b64" const val ENROLLMENT_ID = "enrollment_id" const val INSTALLATION_ID = "installation_id" } }

The following code snippet is a practical illustration of how we can successfully implement user linking:

// MainActivity.kt

class MainActivity : AppCompatActivity() {

private lateinit var preferenceRepo: PreferenceRepo

private val permissionHelper = PermissionHelper(this)

private val retrofitWrapper = RetrofitWrapper()

private val transactionHandler = retrofitWrapper.handleTransactionEndpoints()

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

setSupportActionBar(toolbar)

preferenceRepo = PreferenceRepo(this)

checkPermissions()

fetchInstanceId()

handleIntent(intent)

preferenceRepo.putInstallationId(BuildConfig.INSTALLATION_ID)

preferenceRepo.putPubPssBase64(BuildConfig.PUB_PSS_B64)

enrollmentButton.setOnClickListener { view ->

beginEnrollment()

}

linkingButton.setOnClickListener{

// userId is the users's identifier for your service

// You are required to retrieve this from your server

startServerLinking(userId)

}

}

...

private fun linkUser(linkingCode: String) {

val psaManager = PsaManager.getInstance()

val linkingScenarioListener: LinkingScenarioListener = object: LinkingScenarioListener{

override fun onLinkingCompletedSuccessful(var1: Long, var3: String){

Toast.makeText(this@MainActivity, "Linking Successful", Toast.LENGTH_LONG).show()

}

override fun onLinkingFailed(var1: ApplicationState) {

Toast.makeText(this@MainActivity, "Linking not Successful: linkingCode: ${linkingCodeEditText.text} errorCode: ${var1.code} ", Toast.LENGTH_LONG).show()

}

}

// pass in linkingCode to PsaManager here to

// initiate the linking process

psaManager.linkTenant(linkingCode, preferenceRepo, linkingScenarioListener)

}

...

private fun startServerLinking(userId: String?) {

transactionHandler.linkUser(userId).enqueue(object: Callback<OkayLinking>{

override fun onFailure(call: Call<OkayLinking>, t: Throwable) {

Toast.makeText(this@MainActivity, "Error making request to Server ${t.localizedMessage}", Toast.LENGTH_LONG).show()

t.printStackTrace()

}

override fun onResponse(call: Call<OkayLinking>, response: Response<OkayLinking>) {

// Retrieve user linkingCode here after netwok call

// we retrieve the user linkingCode here and

// we pass in the linkingCode to linkUser method to start linking

linkUser(response?.body()!!.linkingCode)

}

})

}

}

Firebase push notification services send push notifications as a RemoteMessage object. This object contains two properties: type and data.

From this remote message, you can extract a map that contains these properties:

Map<String, String> notificationData = remoteMessage.getData(); String type = notificationData.get("type"); String data = notificationData.get("data");

After retrieving the notification data map from the RemoteMessage object, we check if the type property is equal to 10. If "type" equals 10, then it is a "WakeUpNotification". A wake-up notification is a notification that is sent to the SDK to start an authorisation process. It's "data" property contains the following object:


 { tenantId: <int>, sessionId: <int> }

If we have successfully linked our user, we can now proceed to authorising transactions or authenticating users.

The steps are pretty straight forward:

1. We make a request to our server to begin our authorisation.
2. Our server will make a call to the Okay secure server.
3. The server will, in turn, send a push notification to our app with the current tenantId of our server and the current transaction sessionId field.
4. Once we receive the push notification from Okay Servers, we start the authorisation process by calling the SDK's PsaManager.startAuthorizationActivity (activity: Activity, spaAuthorizationData :SpaAuthorizationData) method.
5. We pass in the current instance of our activity and an instance of SpaAuthorizationData class to the method.

Starting an authorisation begins with a simple request to your server using Retrofit in Android:


//MainActivity.kt

private val retrofitWrapper = RetrofitWrapper() // A simple wrapper around retrofit for network calls

private val transactionHandler = retrofitWrapper.handleTransactionEndpoints()

private fun startServerAuthorization(userId: String?) {

transactionHandler.authorizeTransaction(userId).enqueue(object: Callback<AuthorizationResponse> {

override fun onFailure(call: Call<AuthorizationResponse>, t: Throwable) {

Toast.makeText(this@MainActivity, "Error making request to Server", Toast.LENGTH_LONG).show()

}

override fun onResponse(

call: Call<AuthorizationResponse>,

response: Response<AuthorizationResponse>

) {

Toast.makeText(this@MainActivity, "Request made successfully", Toast.LENGTH_LONG).show()

}

})

}

This code sends a request to your server that initiates the authorisation with Okay secure server. Our application will receive a Push Notification that will be handled by FirebaseMassagingService (This service is part of Firebase messaging. If you are yet to setup Firebase, please see this document). In this example, we extend this service in our app using the OkayDemoFirebaseMessagingService class.

This is what our OkayDemoFirebaseMessagingService class looks like:

// OkayDemoFirebaseMessagingService.kt class OkayDemoFirebaseMessagingService : FirebaseMessagingService() { override fun onNewToken(token: String) { super.onNewToken(token) token?.run { PreferenceRepo(this@OkayDemoFirebaseMessagingService).putExternalId(token) } } override fun onMessageReceived(remoteData: RemoteMessage) { if(remoteData.data.isNotEmpty()){ // handle notification val notificationData = NotificationHandler.extractRemoteData(remoteData) // You can handle the data from the push notification here // However you seem fit // But in this illustration we just send sessionId as an Intent extra to MainActivity startActivity(Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) putExtra(ACTIVITY_WAKE_UP_KEY, notificationData.sessionId!!.toLong() ) }) } } override fun onDeletedMessages() { super.onDeletedMessages() } companion object { val ACTIVITY_WAKE_UP_KEY = "wake_up_key" }

We simply receive this sessionId inside MainActivity.kt:

// MainActivity.kt

class MainActivity : AppCompatActivity() {

private lateinit var preferenceRepo: PreferenceRepo

private val permissionHelper = PermissionHelper(this)

private val retrofitWrapper = RetrofitWrapper()

private val transactionHandler = retrofitWrapper.handleTransactionEndpoints()

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

setSupportActionBar(toolbar)

preferenceRepo = PreferenceRepo(this)

checkPermissions()

fetchInstanceId()

handleIntent(intent)

preferenceRepo.putInstallationId(BuildConfig.INSTALLATION_ID)

preferenceRepo.putPubPssBase64(BuildConfig.PUB_PSS_B64)

enrollmentButton.setOnClickListener { view ->

beginEnrollment()

}

linkingButton.setOnClickListener{

// userId is the users's identifier for your service

// You are required to retrieve this from your server

startServerLinking(userId)

}

authorizeButton.setOnClickListener {

// userId is the users's identifier for your service

// You are required to retrieve this from your server

startServerAuthorization(userId)

}

}

private fun handleIntent(intent: Intent?) {

intent?.apply {

val sessionId = getLongExtra(OkayDemoFirebaseMessagingService.ACTIVITY_WAKE_UP_KEY, 0)

if (sessionId > 0) {

Toast.makeText(this@MainActivity, "Current sessionId $sessionId ", Toast.LENGTH_LONG).show()

// Start Authorization with retrieved session Id

startAuthorization(sessionId)

}

}

}

...

private fun startAuthorization(sessionId: Long) {

PsaManager.startAuthorizationActivity(this, SpaAuthorizationData(sessionId,

preferenceRepo.appPNS,

BaseTheme(this).DEFAULT_PAGE_THEME,

PsaType.OKAY))

}

private fun startServerAuthorization(userId: String?) {

transactionHandler.authorizeTransaction(userId).enqueue(object: Callback<AuthorizationResponse> {

override fun onFailure(call: Call<AuthorizationResponse>, t: Throwable) {

Toast.makeText(this@MainActivity, "Error making request to Server", Toast.LENGTH_LONG).show()

}

override fun onResponse(

call: Call<AuthorizationResponse>,

response: Response<AuthorizationResponse>

) {

// Notify user request was sent

Toast.makeText(this@MainActivity, "Request made successfully", Toast.LENGTH_LONG).show()

}

})

}

}

If you successfully retrieved the sessionId from the push notification data, the Authorisation process begins immediately, allowing the Okay SDK to communicate with Okay secure server. This should present an authorisation screen in the running application.

You can start authorization requests to the SDK in two ways:

9.1 With Activity

PsaManager.startAuthorizationActivity(Activity activity, SpaAuthorizationData authorizationData)

By triggering an authorisation this way, you must implement onActivityResult inside the activity you passed to PsaManager.startAuthorizationActivity(). The status of the authorisation will be sent to this method, where you can check if the transaction was successful or not.

Sample

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

super.onActivityResult(requestCode, resultCode, data)

if (requestCode == PsaConstants.ACTIVITY_REQUEST_CODE_PSA_ENROLL) {

if (resultCode == RESULT_OK) {

//We should save data from Enrollment result, for future usage

data?.run {

val resultData = PsaIntentUtils.enrollResultFromIntent(this)

resultData.let {

preferenceRepo.putExternalId(it.externalId)

}

Toast.makeText(applicationContext, "Successfully got this externalId " + resultData.externalId, Toast.LENGTH_SHORT).show()

}

} else {

Toast.makeText(this, "Error Retrieving intent after enrollment:- code: ${linkingCodeEditText.text} errorCode: $resultCode", Toast.LENGTH_SHORT).show()

}

}

if (requestCode == PsaConstants.ACTIVITY_REQUEST_CODE_PSA_AUTHORIZATION) {

if (resultCode == RESULT_OK) {

Toast.makeText(this, "Authorization granted", Toast.LENGTH_SHORT).show()

} else {

Toast.makeText(this, "Authorization not granted", Toast.LENGTH_SHORT).show()

}

}

}

9.2 For Flutter UI

PsaManager.getInstance().startAuthorizationWithAbstractUI(Activity activity, SpaAuthorizationData authorizationData){ resultCode, intent ->

if (resultCode == RESULT_OK) {

Toast.makeText(this, "Authorization granted", Toast.LENGTH_SHORT).show()

} else {

Toast.makeText(this, "Authorization not granted", Toast.LENGTH_SHORT).show()

}

}

//And remember to add DeviceUiType "Flutter" in SpaAuthorizationData.

//You will get DeviceUiType from notification data.