Back to Blog
How to implement Strong Customer Authentication (SCA) for your React Native app
If you read our earlier primer “What is SCA?” you already know that the EU’s Payment Services Directive 2 (PSD2) raised the bar for payment security across Europe. Strong Customer Authentication (SCA) is the practical expression of that mandate: every sensitive action—logging in, moving money, authorising a card payment—must be indisputably linked to the real customer and protected against tampering.
In this follow-up we take a look at what this means when you’re shipping a React Native fintech app. SCA is not a single library you can npm-install; it is a bundle of requirements that must be woven into your design, your native modules, and even your screen layouts. Fundamentally there are three requirements that go beyond the typical “use biometry to log in”:
- Strong Dynamic Linking between screen and signature. Every time the customer taps “Approve,” your app must sign exactly what they saw: amount, currency, merchant, and context. The Okay SDK generates a one-time signature over that payload and renders the data in a hardened view with optional server-side verification. If an overlay attack or MITM tweak changes even a single cent, the signature validation fails instantly and the back-end can mark the transaction as suspect. The customer signs what they see, and nothing else.
- Two truly independent factors. PSD2’s RTS requires that no single compromised element can unlock an account, so your app must combine possession with either inherence or knowledge. In practice, that means binding the handset during onboarding (the possession proof) and then prompting Face ID or a fingerprint for every high-risk action. The Okay SDK wraps these platform biometric calls and tracks the device binding for you; if biometrics fail or aren’t available, it can fall back to an encrypted in-app PIN without breaking compliance.
- A Secure Execution Environment that malware can’t touch. All cryptographic keys, factor checks, and transaction signatures need to live outside React Native’s JavaScript realm. iOS’s Secure Enclave and Android’s Keystore/TEE give you the hardware layer, but you still have to orchestrate it. The Okay back-end supplies a rotating, just-in-time enclave that your mobile SDK spins up on demand, so critical code executes in a compartment the OS (and any root/jail-break malware) can’t see—even on devices stuck on old security patches.
Why React Native Needs Special Care for SCA
React Native is a cross-platform technology that allows developers to create applications that run on multiple mobile platforms. React Native uses JavaScript and CSS to style the mobile application. This core feature of React Native allows developers with web development experience to conveniently create mobile applications using the same skills and knowledge. React Native is an extension of the React family of libraries, which uses the React reconciler and the React JSI (formerly React Bridge on React Native versions older than v0.76) API to extend its functionality to different mobile platforms. The React JSI (Bridge) is an abstraction layer that allows developers to run React on multiple platforms.
The React Renderer maps React Native components directly to a mobile platform's native UI component. A good example would be to compare Flutter and React. Flutter is a cross-platform package that allows developers to create mobile applications using the Dart programming language. The difference between React and Flutter is that Flutter comes with its own rendering engine that is used to draw UI components that are rendered by the Flutter engine, different from the host platform. React, on the other hand, does not embed any rendering engine; instead, it just maps directly to the host platform’s native components.
While this is a good thing for the React Native community because they can get a good deal of native platform UI features and behaviours without needing to manage them separately, it also comes with some risks associated with using standard system components for secure transactions. One such risk is the malware/robot attacks on PIN pads using native UI components.
Server Setup
Before we can start using the React Native SDK, we strongly recommend that you go through our server guide. This guide allows you to understand how the Okay service works and how the mobile SDK/App is connected to the backend.
Minimal React Native setup for SCA
The Okay SCA platform uses the mobile device as the possession factor for the user when authorising a transaction. One of the steps it takes in order to ensure that the device is ready for SCA is to enroll the device that is to be used for SCA. During the enrollment process, the SDK establishes a secure storage on that device that is unique only to the device. No two devices can have the same secure storage. Once the enrollment is completed, the user proceeds to dynamic linking. This process allows the Okay server to associate a unique user ID provided by the customer with the enrolled device. Upon completion of this step, the user is now ready to start authorising transactions with that device.
Installing the Okay React Native module in a React Native project
You can grab the Okay module from this Github repository https://github.com/Okaythis/OkayRNModule.
Add OkayRNModule as a local dependency to your package.json file:
"react-native-okay-sdk": "file:custom_modules/OkayRNModule"
Run the following to install the package: $ yarn install
We will skip all platform-specific setup as this is already documented on the project’s README.md file.
Initialise the Okay SDK
The Okay SDK provides the initOkay function that allows you to initialise the SDK. You will have to provide the URL of the instance of the Okay server that you are using.
initOkay({ okayUrlEndpoint: 'https://demostand.okaythis.com', })
Implement Firebase Push Notification
The Okay SDK provides the updateDeviceToken(token) function. This function allows you to update the push notification token from the push notification provider. The Okay service allows the customer to use any push notification service of their choice, but the SDK provides an interface that allows the user to use Firebase for both Android and iOS. Please see this documentation on how to set up Firebase push notifications for your application.
import messaging from '@react-native-firebase/messaging';// Snippet of permission request using Firebase SDK const authStatus = await messaging().requestPermission(); console.log('status: ', authStatus); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) { console.log('Authorization status:', authStatus); messaging().getToken().then(token => {' updateDeviceToken(token || ''); }) }
Enroll the device
The Okay SDK provide the startEnrollment(SpaEnrollData) function that enrols the user’s device for SCA.
The function accepts the following interface:
interface SpaEnrollData { pubPss: string; installationId: string; appPns?: string; pageTheme?: PSATheme; enrollInBackground?: boolean;}
"appPns": This is your push notification token from Firebase(or Firebase registration token for iOS devices if you are using Firebase for push notification on iOS) or APNS token if you are using APNS. This allows us to send 2FA notifications to your apps.
"installationId": The installationId is a unique value that identifies unique installation keys for the Okay SDK in an app. For testing purposes, we ask our users to use this value **9990** as their installationId on Android and **9980** on iOS.
"pubPss": This is a public key we provide to applications that use our SDK for secure communication with the Okay server. For testing purposes, we ask our users to use the value below as their *"pubPss"* key.
const pubPssBase64 = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxgyacF1NNWTA6rzCrtK60se9fVpTPe3HiDjHB7MybJvNdJZIgZbE9k3gQ6cdEYgTOSG823hkJCVHZrcf0/AK7G8Xf/rjhWxccOEXFTg4TQwmhbwys+sY/DmGR8nytlNVbha1DV/qOGcqAkmn9SrqW76KK+EdQFpbiOzw7RRWZuizwY3BqRfQRokr0UBJrJrizbT9ZxiVqGBwUDBQrSpsj3RUuoj90py1E88ExyaHui+jbXNITaPBUFJjbas5OOnSLVz6GrBPOD+x0HozAoYuBdoztPRxpjoNIYvgJ72wZ3kOAVPAFb48UROL7sqK2P/jwhdd02p/MDBZpMl/+BG+qQIDAQAB';
startEnrollment({ appPns: deviceToken, pubPss: pubPssBase64, enrollInBackground: true installationId: installationID, }) .then((response) => { console.log(response); // setExternalId(response.externalId); }) .catch((e) => { console.log(e); });
Linking a user
The Okay SDK provides a linkTenant(code: string, spaStroageData?: SpaStroageData) function that allows customers to link their app users. Please see this guide on how to generate the linking code from the Okay server.
interface SpaStorageData { externalId?: string; enrollmentId?: string; appPns: string; pubPss: string; installationId: string;}
await linkTenant( linkingCode, { appPns: token, pubPss: pubPssBase64, externalId: 'DEVICE_EXTERNAL_ID', installationId: "9990", })
The externalId can be retrieved from the startEnrollment(...).then( externalId => ...) method, if the method was called and executed successfully.
Starting a Session
We have been able to enroll and link a user on the Okay platform. We are not ready to start the authorisation process on the mobile app. Please see this guide on how to start an authorisation session on the Okay server.
In order to be able to authorise a transaction using the Okay platform, we need to set up push notifications using Firebase.
If Firebase push notifications have been set up correctly, then we can use the Okay startAuthorisation method on the Okay SDK to start a session. Please see the following code snippet below for an example of how to start an authorisation session on the Okay platform.
import messaging from '@react-native-firebase/messaging';
messaging().onMessage(async message => { let data = JSON.parse(message.data.data); let response = await startAuthorization({ clientServerUrl: data.clientServerUrl, extSessionId: data.sessionExternalId, isDisableMultipleRetry: false, userExternalId: 'user-123445558999', deviceUiType: data.params.DEVICE_UI_TYPE, sessionId: data.sessionId, appPns: appPushNotificationToken, }); console.log(response);});
The Okay SDK uses the data sent from the payload of the push notification to start the session.
Sign Up for Our Newsletter
Unlock updates, insights, and exclusive content delivered to you.
What does the Okay platform do in the background to secure your transactions?
The Okay platform uses a secure storage mechanism that encrypts all data being stored or transferred between the Okay server and the Okay SDK. All transaction-related information is deleted from the device after every session is completed. The system creates a clean slate when a new transaction is started. All transaction-sensitive data, such as a user’s PIN, is encrypted upon collection using a unique public key set by the customer. The encrypted data is sent to the customer’s backend, which holds the private key that can decrypt the transaction data. The Okay server also compiles a secure execution environment that is transferred just in time, which is executed to render the transaction details. Fresh code blocks are compiled for every transaction. This is to ensure that every transaction is unique.
Using a separate back-end to verify transactions
In order to verify transaction details from the Okay server, you would need to set up a webhook endpoint on your server that will handle all artifacts and information from the Okay side. We have created a dedicated page on our website to document the callback process.