React Native integration
A native module with an event-driven challenge fetch, plus the TypeScript wrapper.
Step 1: Add dependency
In android/app/build.gradle:
dependencies {
implementation "io.github.blinc-technologies:blinc-pos-sdk-ui:0.1.2"
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.8.22"
}Step 2: Create native module
package com.your.app
import com.blinc.blincpos.BlincPosSdk
import com.facebook.react.bridge.*
import com.facebook.react.modules.core.DeviceEventManagerModule
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class BlincPosModule(reactContext: ReactApplicationContext)
: ReactContextBaseJavaModule(reactContext) {
private val scope = CoroutineScope(Dispatchers.Main)
private var pendingChallenge: CompletableDeferred<String?>? = null
private val terminalId = "T0001"
private val merchantId = "00000001"
private val paymentFacilitatorId = 1L
override fun getName(): String = "BlincPosModule"
@ReactMethod
fun provideChallenge(challenge: String?) {
pendingChallenge?.complete(challenge)
}
@ReactMethod
fun startTransaction(amount: Double, metadata: String, method: String, promise: Promise) {
val activity = currentActivity as? MainActivity
if (activity == null) {
promise.reject("ConfigError", "Activity not available")
return
}
activity.activePromise = promise
scope.launch {
val registered = BlincPosSdk.ensureRegistered(
context = reactApplicationContext,
terminalId = terminalId,
merchantId = merchantId,
paymentFacilitatorID = paymentFacilitatorId,
environment = Environment.TEST // Environment.LIVE for prod
challengeProvider = {
val deferred = CompletableDeferred<String?>()
pendingChallenge = deferred
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("BlincFetchChallenge", null)
deferred.await()
}
)
if (!registered) {
promise.reject("RegistrationError", "Could not register terminal")
activity.activePromise = null
return@launch
}
if (method == "QR") {
BlincPosSdk.startTransactionWithQR(
context = activity, amount = amount.toLong(), metadata = metadata
)
} else {
BlincPosSdk.startTransactionWithNFC(
context = activity, amount = amount.toLong(), metadata = metadata
)
}
}
}
}Step 3: Update MainActivity
class MainActivity : ReactActivity() {
var activePromise: Promise? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
BlincPosSdk.registerLauncher(this) { result ->
activePromise?.let { promise ->
val map = Arguments.createMap()
map.putString("status", result.status.name)
map.putString("transactionId", result.transactionId)
map.putString("message", result.message)
map.putString("currency", result.currency)
result.amount?.let { map.putDouble("amount", it.toDouble()) }
promise.resolve(map)
activePromise = null
}
}
}
}Step 4: Register the module
Add BlincPosModule to your ReactPackage list in MainApplication.kt.
TypeScript usage
import { NativeModules, NativeEventEmitter } from 'react-native';
const { BlincPosModule } = NativeModules;
const emitter = new NativeEventEmitter(BlincPosModule);
emitter.addListener('BlincFetchChallenge', async () => {
try {
const challenge = await YourBackendApiClient.fetchChallenge();
BlincPosModule.provideChallenge(challenge);
} catch {
BlincPosModule.provideChallenge(null);
}
});
export const BlincSDK = {
pay: async (amountKobo: number, method: 'NFC' | 'QR', metadata: string = '{}') => {
try {
return await BlincPosModule.startTransaction(amountKobo, metadata, method);
} catch (e) {
console.error(e);
throw e;
}
}
};
// Usage
const result = await BlincSDK.pay(199900, 'NFC', '{"orderId":"ORD-42"}');Updated 1 day ago
Did this page help you?