1.0.26

Fix Closing Session

This topic deals with the session end functionality, which is triggered when a customer, after starting a transaction, returns to the previous screen (the value entry screen). In this situation, the previous session remains in progress. Consequently, when trying to go back to the transaction screen, an error occurred when creating a new session, as there was already an active one.

We'll use the “Back” button in the React Native application to trigger the session termination method in the SDK. To do this, we'll use our DeviceInfoModule file, created earlier, which acts as a bridge (Native Module) between the native functions written in Kotlin (Android) and the React Native JavaScript environment. There is the flexibility of creating a new file dedicated to this functionality or keeping the functions in the same file. The method we're going to use is clearTerminalSession.

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import com.firsttech.taponphone.sdk.v2.utils.DeviceInformationUtils
import com.firsttech.taponphone.sdk.v2.utils.SessionHelper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import android.util.Log

class DeviceInfoModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
    override fun getName(): String = "DeviceInfoModule"

    @ReactMethod
    fun getDeviceId(promise: Promise) {
        try {
            val id = DeviceInformationUtils.getDeviceIdentifier(reactApplicationContext)
            promise.resolve(id)
        } catch (e: Exception) {
            promise.reject("ERROR", e.message)
        }
    }

    @ReactMethod
    fun getDeviceInfo(promise: Promise) {
        CoroutineScope(Dispatchers.Default).launch {
            try {
                val info = DeviceInformationUtils.getDeviceInfo(reactApplicationContext)
                promise.resolve(info)
            } catch (e: Exception) {
                promise.reject("DEVICE_INFO_ERROR", e.message)
            }
        }
    }
    //


    fun addListener(eventName: String?) {
        // Requerido pelo NativeEventEmitter
    }

    fun removeListeners(count: Int) {
        // Requerido pelo NativeEventEmitter
    }

    @ReactMethod
    fun clearTerminalSession() {
        try {
            SessionHelper.clearCurrentTerminalSession()
        } catch (e: Exception) {
            Log.e("TerminalModule", "Erro ao limpar sessão do terminal", e)
        }
    }
}

Now we'll define how to use our new method, located in the DeviceInfoModule file, via the JavaScript wrapper that we've used before for other functions. Feel free to create a new file dedicated to this functionality or integrate it into the existing file in our sample application.


import { NativeModules } from 'react-native';

const { DeviceInfoModule } = NativeModules;

export function getDeviceInfo(): Promise<string> {
  return DeviceInfoModule.getDeviceInfo();
}

export function clearTerminal(): void {
  DeviceInfoModule.clearTerminalSession();
}

In our index file (or index.tsx), which defines our application's payment processing screen, we will import the clearTerminal method - previously defined in our native module - to be used when the “Back” button is pressed.

import { clearTerminal } from '../../native-modules/DeviceInfoModule';

We will also carry out the following imports

import { ..., BackHandler } from 'react-native';
import { ..., useCallback } from 'react';
import { ..., useFocusEffect } from '@react-navigation/native';

BackHandler: Manages Android's physical "Back" button.

useFocusEffect: Executes effects (such as adding listeners from the BackHandler) when the screen gains focus and clears them when it loses focus.

useCallback: Memoizes the function passed to useFocusEffect, optimizing it and ensuring that it is stable, preventing unnecessary recreations and executions of the focus effect.

And in our component that works as a "Back" button, we'll call the clearTerminal() method, implemented earlier. This, in turn, will use the session clearing method implemented in the SDK.

     <BackButtonWrapper
            onPress={() => {
              clearTerminal(); 
              goBack();        
            }}
        >
        <BackButtonArrowLeftVector source={arrowLeftVector} />
      </BackButtonWrapper>

Last updated