Production example
The full ViewModel pattern: challenge fetch off the main thread, with loading and retry states.
The challenge fetch is a network call and must run off the main thread. ensureRegistered() is a suspend function: call it from viewModelScope.
ViewModel
class PosViewModel(private val app: Application) : AndroidViewModel(app) {
private val terminalId = "T0001"
private val merchantId = "00000001"
private val paymentFacilitatorId = 1L
private val _isInitializing = MutableStateFlow(false)
val isInitializing: StateFlow<Boolean> = _isInitializing.asStateFlow()
private val _initError = MutableStateFlow<String?>(null)
val initError: StateFlow<String?> = _initError.asStateFlow()
fun ensureRegisteredThenRun(onReady: () -> Unit) {
viewModelScope.launch {
_isInitializing.value = true
_initError.value = null
val registered = BlincPosSdk.ensureRegistered(
context = app,
terminalId = terminalId,
merchantId = merchantId,
paymentFacilitatorID = paymentFacilitatorId,
environment = Environment.TEST // Environment.LIVE for prod
challengeProvider = {
withContext(Dispatchers.IO) {
YourBackendApiClient.fetchChallenge()
}
}
)
_isInitializing.value = false
if (registered) {
onReady()
} else {
_initError.value = "Could not register the terminal. Please try again."
}
}
}
fun clearError() { _initError.value = null }
}Activity
class PosActivity : ComponentActivity() {
private val viewModel: PosViewModel by viewModels()
private var lastResult by mutableStateOf<TransactionResult?>(null)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
BlincPosSdk.registerLauncher(this) { result ->
lastResult = result
}
setContent {
val isInitializing by viewModel.isInitializing.collectAsState()
val initError by viewModel.initError.collectAsState()
PosScreen(
isInitializing = isInitializing,
initError = initError,
lastResult = lastResult,
onClearError = { viewModel.clearError() },
onPayNfc = {
viewModel.ensureRegisteredThenRun {
BlincPosSdk.startTransactionWithNFC(
context = this,
amount = 199900L,
metadata = """{"orderId":"ORD-001"}"""
)
}
},
onPayQr = {
viewModel.ensureRegisteredThenRun {
BlincPosSdk.startTransactionWithQR(
context = this,
amount = 199900L
)
}
}
)
}
}
}Updated 1 day ago
Did this page help you?