cashless2ecash

cashless2ecash: pay with cards for digital cash (experimental)
Log | Files | Refs | README

commit a74af4ab88f39800cd02df7fa52efb4398123032
parent b71b7bb8133b63908a59177df9c156a23f4cbe17
Author: Joel-Haeberli <haebu@rubigen.ch>
Date:   Sun, 24 Nov 2024 16:56:57 +0100

improve: process flow and state handling

Diffstat:
Dwallee-c2ec/.idea/other.xml | 330-------------------------------------------------------------------------------
Mwallee-c2ec/app/release/app-release.apk | 0
Mwallee-c2ec/app/release/baselineProfiles/0/app-release.dm | 0
Mwallee-c2ec/app/release/baselineProfiles/1/app-release.dm | 0
Mwallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AuthorizePaymentScreen.kt | 80+++++++++++++++++++++++++++++++++++++------------------------------------------
Mwallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterParametersScreen.kt | 7++++---
6 files changed, 41 insertions(+), 376 deletions(-)

diff --git a/wallee-c2ec/.idea/other.xml b/wallee-c2ec/.idea/other.xml @@ -1,329 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="direct_access_persist.xml"> - <option name="deviceSelectionList"> - <list> - <PersistentDeviceSelectionData> - <option name="api" value="27" /> - <option name="brand" value="DOCOMO" /> - <option name="codename" value="F01L" /> - <option name="id" value="F01L" /> - <option name="manufacturer" value="FUJITSU" /> - <option name="name" value="F-01L" /> - <option name="screenDensity" value="360" /> - <option name="screenX" value="720" /> - <option name="screenY" value="1280" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="28" /> - <option name="brand" value="DOCOMO" /> - <option name="codename" value="SH-01L" /> - <option name="id" value="SH-01L" /> - <option name="manufacturer" value="SHARP" /> - <option name="name" value="AQUOS sense2 SH-01L" /> - <option name="screenDensity" value="480" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2160" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="Lenovo" /> - <option name="codename" value="TB370FU" /> - <option name="id" value="TB370FU" /> - <option name="manufacturer" value="Lenovo" /> - <option name="name" value="Tab P12" /> - <option name="screenDensity" value="340" /> - <option name="screenX" value="1840" /> - <option name="screenY" value="2944" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="31" /> - <option name="brand" value="samsung" /> - <option name="codename" value="a51" /> - <option name="id" value="a51" /> - <option name="manufacturer" value="Samsung" /> - <option name="name" value="Galaxy A51" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2400" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="google" /> - <option name="codename" value="akita" /> - <option name="id" value="akita" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 8a" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2400" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="33" /> - <option name="brand" value="samsung" /> - <option name="codename" value="b0q" /> - <option name="id" value="b0q" /> - <option name="manufacturer" value="Samsung" /> - <option name="name" value="Galaxy S22 Ultra" /> - <option name="screenDensity" value="600" /> - <option name="screenX" value="1440" /> - <option name="screenY" value="3088" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="32" /> - <option name="brand" value="google" /> - <option name="codename" value="bluejay" /> - <option name="id" value="bluejay" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 6a" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2400" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="google" /> - <option name="codename" value="caiman" /> - <option name="id" value="caiman" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 9 Pro" /> - <option name="screenDensity" value="360" /> - <option name="screenX" value="960" /> - <option name="screenY" value="2142" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="google" /> - <option name="codename" value="comet" /> - <option name="id" value="comet" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 9 Pro Fold" /> - <option name="screenDensity" value="390" /> - <option name="screenX" value="2076" /> - <option name="screenY" value="2152" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="29" /> - <option name="brand" value="samsung" /> - <option name="codename" value="crownqlteue" /> - <option name="id" value="crownqlteue" /> - <option name="manufacturer" value="Samsung" /> - <option name="name" value="Galaxy Note9" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="2220" /> - <option name="screenY" value="1080" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="samsung" /> - <option name="codename" value="dm3q" /> - <option name="id" value="dm3q" /> - <option name="manufacturer" value="Samsung" /> - <option name="name" value="Galaxy S23 Ultra" /> - <option name="screenDensity" value="600" /> - <option name="screenX" value="1440" /> - <option name="screenY" value="3088" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="samsung" /> - <option name="codename" value="e1q" /> - <option name="id" value="e1q" /> - <option name="manufacturer" value="Samsung" /> - <option name="name" value="Galaxy S24" /> - <option name="screenDensity" value="480" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2340" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="33" /> - <option name="brand" value="google" /> - <option name="codename" value="felix" /> - <option name="id" value="felix" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel Fold" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="2208" /> - <option name="screenY" value="1840" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="google" /> - <option name="codename" value="felix" /> - <option name="id" value="felix" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel Fold" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="2208" /> - <option name="screenY" value="1840" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="33" /> - <option name="brand" value="google" /> - <option name="codename" value="felix_camera" /> - <option name="id" value="felix_camera" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel Fold (Camera-enabled)" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="2208" /> - <option name="screenY" value="1840" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="33" /> - <option name="brand" value="samsung" /> - <option name="codename" value="gts8uwifi" /> - <option name="id" value="gts8uwifi" /> - <option name="manufacturer" value="Samsung" /> - <option name="name" value="Galaxy Tab S8 Ultra" /> - <option name="screenDensity" value="320" /> - <option name="screenX" value="1848" /> - <option name="screenY" value="2960" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="google" /> - <option name="codename" value="husky" /> - <option name="id" value="husky" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 8 Pro" /> - <option name="screenDensity" value="390" /> - <option name="screenX" value="1008" /> - <option name="screenY" value="2244" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="30" /> - <option name="brand" value="motorola" /> - <option name="codename" value="java" /> - <option name="id" value="java" /> - <option name="manufacturer" value="Motorola" /> - <option name="name" value="G20" /> - <option name="screenDensity" value="280" /> - <option name="screenX" value="720" /> - <option name="screenY" value="1600" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="google" /> - <option name="codename" value="komodo" /> - <option name="id" value="komodo" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 9 Pro XL" /> - <option name="screenDensity" value="360" /> - <option name="screenX" value="1008" /> - <option name="screenY" value="2244" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="33" /> - <option name="brand" value="google" /> - <option name="codename" value="lynx" /> - <option name="id" value="lynx" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 7a" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2400" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="31" /> - <option name="brand" value="google" /> - <option name="codename" value="oriole" /> - <option name="id" value="oriole" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 6" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2400" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="33" /> - <option name="brand" value="google" /> - <option name="codename" value="panther" /> - <option name="id" value="panther" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 7" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2400" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="samsung" /> - <option name="codename" value="q5q" /> - <option name="id" value="q5q" /> - <option name="manufacturer" value="Samsung" /> - <option name="name" value="Galaxy Z Fold5" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1812" /> - <option name="screenY" value="2176" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="samsung" /> - <option name="codename" value="q6q" /> - <option name="id" value="q6q" /> - <option name="manufacturer" value="Samsung" /> - <option name="name" value="Galaxy Z Fold6" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1856" /> - <option name="screenY" value="2160" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="30" /> - <option name="brand" value="google" /> - <option name="codename" value="r11" /> - <option name="id" value="r11" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel Watch" /> - <option name="screenDensity" value="320" /> - <option name="screenX" value="384" /> - <option name="screenY" value="384" /> - <option name="type" value="WEAR_OS" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="30" /> - <option name="brand" value="google" /> - <option name="codename" value="redfin" /> - <option name="id" value="redfin" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 5" /> - <option name="screenDensity" value="440" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2340" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="google" /> - <option name="codename" value="shiba" /> - <option name="id" value="shiba" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 8" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2400" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="33" /> - <option name="brand" value="google" /> - <option name="codename" value="tangorpro" /> - <option name="id" value="tangorpro" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel Tablet" /> - <option name="screenDensity" value="320" /> - <option name="screenX" value="1600" /> - <option name="screenY" value="2560" /> - </PersistentDeviceSelectionData> - <PersistentDeviceSelectionData> - <option name="api" value="34" /> - <option name="brand" value="google" /> - <option name="codename" value="tokay" /> - <option name="id" value="tokay" /> - <option name="manufacturer" value="Google" /> - <option name="name" value="Pixel 9" /> - <option name="screenDensity" value="420" /> - <option name="screenX" value="1080" /> - <option name="screenY" value="2424" /> - </PersistentDeviceSelectionData> - </list> - </option> - </component> -</project> -\ No newline at end of file diff --git a/wallee-c2ec/app/release/app-release.apk b/wallee-c2ec/app/release/app-release.apk Binary files differ. diff --git a/wallee-c2ec/app/release/baselineProfiles/0/app-release.dm b/wallee-c2ec/app/release/baselineProfiles/0/app-release.dm Binary files differ. diff --git a/wallee-c2ec/app/release/baselineProfiles/1/app-release.dm b/wallee-c2ec/app/release/baselineProfiles/1/app-release.dm Binary files differ. diff --git a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AuthorizePaymentScreen.kt b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AuthorizePaymentScreen.kt @@ -48,6 +48,29 @@ fun AuthorizePaymentScreen(model: WithdrawalViewModel, activity: Activity, clien .ListBuilder(uiState.encodedWopid, uiState.amount.plus(uiState.withdrawalFees).toBigDecimal()) .build() + LaunchedEffect(Unit) { + + println("LaunchedEffect: starting authorization") + + if (uiState.transactionState == TransactionState.READY_FOR_AUTHORIZATION) { + val transaction = Transaction.Builder(withdrawalAmount) + .setCurrency(Currency.getInstance(uiState.currency)) + .setInvoiceReference(uiState.encodedWopid) + .setMerchantReference(uiState.encodedWopid) + .setTransactionProcessingBehavior(TransactionProcessingBehavior.COMPLETE_IMMEDIATELY) + .build() + + try { + client.authorizeTransaction(transaction) + model.setAuthorizing() + } catch (e: Exception) { + println("FAILED authorizing transaction ${e.message}") + model.withdrawalOperationFailed(activity) + e.printStackTrace() + } + } + } + Column( Modifier.width(configuration.screenWidthDp.dp), verticalArrangement = Arrangement.Center, @@ -56,16 +79,11 @@ fun AuthorizePaymentScreen(model: WithdrawalViewModel, activity: Activity, clien when (uiState.transactionState) { TransactionState.UNREADY_FOR_AUTHORIZATION -> model.withdrawalOperationFailed(activity) - TransactionState.READY_FOR_AUTHORIZATION -> WalleeAuthorizePayment( - withdrawalAmount = withdrawalAmount, - uiState = uiState, - model = model, - activity = activity, - client = client - ) + TransactionState.READY_FOR_AUTHORIZATION -> WalleeProcessingTransaction() TransactionState.AUTHORIZATION_TRIGGERED -> WalleeProcessingTransaction() TransactionState.AUTHORIZATION_FAILED -> model.withdrawalOperationFailed(activity) - TransactionState.AUTHORIZED -> WalleeProcessingTransaction() // Maybe following is not needed because completion immediately is specified... WalleeCompletingPayment(client, model) + // TODO : Coordination of Wallee SDK components and this app must be looked at + TransactionState.AUTHORIZED -> WalleeCompletingPayment(client, model) // TODO: Maybe following is not needed because completion immediately is specified... WalleeCompletingPayment(client, model) TransactionState.COMPLETION_TRIGGERED -> WalleeProcessingTransaction() TransactionState.COMPLETED -> model.talerCheckWalleeRequest(activity) TransactionState.COMPLETION_FAILED -> model.withdrawalOperationFailed(activity) @@ -83,14 +101,17 @@ private fun WalleeCompletingPayment( Text(text = "completing transaction...") - LaunchedEffect(Unit) { - model.setCompleting() - client.completeTransaction( - TransactionCompletion.Builder(uiState.transaction!!.transaction.lineItems) - .setCurrency(uiState.transaction!!.transaction.currency) - .setReserveReference(uiState.transaction!!.reserveReference!!) - .build() - ) + LaunchedEffect(key1 = Unit) { + + if (uiState.transactionState == TransactionState.AUTHORIZED) { + client.completeTransaction( + TransactionCompletion.Builder(uiState.transaction!!.transaction.lineItems) + .setCurrency(uiState.transaction!!.transaction.currency) + .setReserveReference(uiState.transaction!!.reserveReference!!) + .build() + ) + model.setCompleting() + } } } @@ -98,30 +119,3 @@ private fun WalleeCompletingPayment( private fun WalleeProcessingTransaction() { Text(text = "processing transaction...") } - -@Composable -private fun WalleeAuthorizePayment( - withdrawalAmount: List<LineItem>, - uiState: WithdrawalOperationState, - model: WithdrawalViewModel, - activity: Activity, - client: ApiClient -) = LaunchedEffect(Unit) { - if (uiState.transactionState == TransactionState.READY_FOR_AUTHORIZATION) { - val transaction = Transaction.Builder(withdrawalAmount) - .setCurrency(Currency.getInstance(uiState.currency)) - .setInvoiceReference(uiState.encodedWopid) - .setMerchantReference(uiState.encodedWopid) - .setTransactionProcessingBehavior(TransactionProcessingBehavior.COMPLETE_IMMEDIATELY) - .build() - - try { - model.setAuthorizing() - client.authorizeTransaction(transaction) - } catch (e: Exception) { - println("FAILED authorizing transaction ${e.message}") - model.withdrawalOperationFailed(activity) - e.printStackTrace() - } - } -} diff --git a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterParametersScreen.kt b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterParametersScreen.kt @@ -33,7 +33,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.dp -private const val MAX_RETRIES = 3 // one retry runs 10sec -> 3x10sec = 30sec +private const val MAX_RETRIES = 6 // one retry runs 10sec (long-poll) -> 6x10sec = 1min @Composable fun RegisterParametersScreen( @@ -45,7 +45,7 @@ fun RegisterParametersScreen( val uiState by model.uiState.collectAsState() val configuration = LocalConfiguration.current - LaunchedEffect(Unit) { + LaunchedEffect(uiState.setupWithdrawalRetries) { // this will run exactly once -> Unit as parameter to LaunchedEffect. if (ManageActivity.SIM_WALLET_ENABLED.value) { ManageActivity.simulateParameterRegistration( @@ -53,7 +53,8 @@ fun RegisterParametersScreen( uiState.encodedWopid ) } - if (model.uiState.value.setupWithdrawalRetries < 1) { + if (model.uiState.value.setupWithdrawalRetries < 1 && + model.uiState.value.transactionState == TransactionState.UNREADY_FOR_AUTHORIZATION) { println("starting authorization") model.startAuthorizationWhenReadyOrSetRetry() }