cashless2ecash

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

commit 24a60ce054930f9070f757413b1b06cec5bc5636
parent 477569e5cda84886924b5c2781c02ed382e1d61c
Author: Joel-Haeberli <haebu@rubigen.ch>
Date:   Wed,  8 May 2024 07:57:48 +0200

fix: app basic auth and serialization

Diffstat:
Mwallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt | 16+++++++++++-----
Mwallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt | 20++++++++++----------
Mwallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt | 56+++++++++++++++++++++++++++++++-------------------------
Mwallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt | 12++++++------
Mwallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt | 43+++++++++++++++++++++++++++----------------
5 files changed, 85 insertions(+), 62 deletions(-)

diff --git a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt @@ -8,6 +8,7 @@ import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalSetup import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalSetupResponse import ch.bfh.habej2.wallee_c2ec.client.taler.model.WithdrawalOperationStatus import com.squareup.moshi.Moshi +import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import kotlinx.coroutines.asCoroutineDispatcher import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Interceptor @@ -46,7 +47,10 @@ class TerminalClientImplementation ( .addPathSegment(encodedWopid) .build() - private fun <T> serializer(clazz: Class<T>) = Moshi.Builder().build().adapter(clazz) + private fun <T> serializer(clazz: Class<T>) = Moshi.Builder() + .add(KotlinJsonAdapterFactory()) + .build() + .adapter(clazz) private fun withdrawalsConfirm(encodedWopid: String) = withdrawalsByWopid(encodedWopid) .newBuilder() @@ -66,6 +70,7 @@ class TerminalClientImplementation ( .url(terminalsConfigUrl()) .build() val response = client.newCall(req).execute() + println("terminal config response status: ${response.code}") callback(parseOrEmpty(response)) } @@ -165,13 +170,14 @@ class TerminalClientImplementation ( override fun intercept(chain: Interceptor.Chain): Response { val base64EncodedCredentials = java.util.Base64 - .getUrlEncoder() - .encode("${config.username}:${config.accessToken}".toByteArray()) - .toString() + .getEncoder() + .encodeToString("${config.username}:${config.accessToken}".toByteArray()) + val authorizationHeaderValue = "Basic $base64EncodedCredentials" + println("auth header: $authorizationHeaderValue") return chain.proceed( chain.request().newBuilder() - .header("Authorization", base64EncodedCredentials) + .header("Authorization", authorizationHeaderValue) .build() ) } diff --git a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt @@ -49,19 +49,19 @@ class TerminalClientMock: TerminalClient { BankWithdrawalOperationStatus( WithdrawalOperationStatus.SELECTED, Amount(10,0), - Amount(10,0), - Amount(0,0), - Amount(0,0), +// Amount(10,0), +// Amount(0,0), +// Amount(0,0), "wallee-transaction", - "http://mock.com/api", - "http://mock.com/api", - "", +// "http://mock.com/api", +// "http://mock.com/api", +// "", Array(0) {""}, mockWopidOrReservePubKey(), - "payto://IBAN/CH1111111111111", - aborted = false, - selectionDone = true, - transferDone = false +// "payto://IBAN/CH1111111111111", +// aborted = false, +// selectionDone = true, +// transferDone = false ) ) ) diff --git a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt @@ -1,27 +1,33 @@ package ch.bfh.habej2.wallee_c2ec.client.taler.model import ch.bfh.habej2.wallee_c2ec.withdrawal.Amount +import com.squareup.moshi.Json data class TerminalApiConfig( - val name: String, - val version: String, - val providerName: String, - val currency: String, - val wireType: String + @Json(name = "name") val name: String, + @Json(name = "version") val version: String, + @Json(name = "provider_name") val providerName: String, + @Json(name = "currency") val currency: String, + @Json(name = "wire_type") val wireType: String ) data class TerminalWithdrawalSetup( - val requestUid: String, - val amount: Amount + @Json(name = "request_uid") val requestUid: String, + @Json(name = "amount") val amount: Amount, + @Json(name = "suggested_amount") val suggestedAmount: Amount = Amount(0,0, ""), + @Json(name = "provider_transaction_id") val providerTransactionId: String = "", + @Json(name = "terminal_fees") val terminalFees: Amount = Amount(0,0, ""), + @Json(name = "user_uuid") val userUuid: String = "", + @Json(name = "lock") val lock: String = "" ) data class TerminalWithdrawalSetupResponse( - val withdrawalId: String + @Json(name = "withdrawal_id") val withdrawalId: String ) data class TerminalWithdrawalConfirmationRequest( - val providerTransactionId: String, - val terminalFees: Amount + @Json(name = "provider_transaction_id") val providerTransactionId: String, + @Json(name = "terminal_fees") val terminalFees: Amount ) enum class WithdrawalOperationStatus(val value: String) { @@ -33,19 +39,19 @@ enum class WithdrawalOperationStatus(val value: String) { } data class BankWithdrawalOperationStatus( - val status: WithdrawalOperationStatus, - val amount: Amount, - val suggestedAmount: Amount, - val maxAmount: Amount, - val cardFees: Amount, - val senderWire: String, - val suggestedExchange: String, - val requiredExchange: String, - val confirmTransferUrl: String, - val wireTypes: Array<String>, - val selectedReservePub: String, - val selectedExchangeAccount: String, - val aborted: Boolean, - val selectionDone: Boolean, - val transferDone: Boolean + @Json(name = "status") val status: WithdrawalOperationStatus, + @Json(name = "amount") val amount: Amount, +// @Json(name = "suggested_amount") val suggestedAmount: Amount, +// @Json(name = "max_amount") val maxAmount: Amount, +// @Json(name = "card_fees") val cardFees: Amount, + @Json(name = "sender_wire") val senderWire: String, +// @Json(name = "suggested_exchange") val suggestedExchange: String, +// @Json(name = "required_exchange") val requiredExchange: String, +// @Json(name = "confirm_transfer_url") val confirmTransferUrl: String, + @Json(name = "wire_types") val wireTypes: Array<String>, + @Json(name = "selected_reserve_pub") val selectedReservePub: String, +// @Json(name = "selected_exchange_acount") val selectedExchangeAccount: String, +// @Json(name = "aborted") val aborted: Boolean, +// @Json(name = "selection_done") val selectionDone: Boolean, +// @Json(name = "transfer_done") val transferDone: Boolean ) diff --git a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt @@ -21,22 +21,22 @@ val exchanges = listOf( TalerTerminalConfig( "KUDOS Exchange (BFH)", "http://taler-c2ec.ti.bfh.ch", - "", - "" + "Wallee-2", + "1A92pgloFR8WIgr0LDA+s9hbkO4EgyJlHj+3dQ9IJ9U=" ), TalerTerminalConfig( "CHF Exchange (PostFinance)", "https://taler-c2ec.ti.bfh.ch", - "", - "" + "Wallee-2", + "1A92pgloFR8WIgr0LDA+s9hbkO4EgyJlHj+3dQ9IJ9U=" ), TalerTerminalConfig( "EUR Exchange (UBS)", "http://taler-c2ec.ti.bfh.ch", - "", - "" + "Wallee-2", + "1A92pgloFR8WIgr0LDA+s9hbkO4EgyJlHj+3dQ9IJ9U=" ) ) diff --git a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt @@ -10,14 +10,11 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import ch.bfh.habej2.wallee_c2ec.client.taler.TerminalClient import ch.bfh.habej2.wallee_c2ec.client.taler.TerminalClientImplementation -import ch.bfh.habej2.wallee_c2ec.client.taler.TerminalClientMock import ch.bfh.habej2.wallee_c2ec.client.taler.config.TalerTerminalConfig import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalConfirmationRequest import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalSetup -import com.wallee.android.till.sdk.data.LineItem -import com.wallee.android.till.sdk.data.ResultCode +import com.squareup.moshi.Json import com.wallee.android.till.sdk.data.State -import com.wallee.android.till.sdk.data.Transaction import com.wallee.android.till.sdk.data.TransactionCompletionResponse import com.wallee.android.till.sdk.data.TransactionResponse import kotlinx.coroutines.flow.MutableStateFlow @@ -28,7 +25,11 @@ import java.math.BigDecimal import java.util.Optional import java.util.UUID -data class Amount(val value: Int, val frac: Int) { +data class Amount( + @Json(name = "value") val value: Int, + @Json(name = "fraction") val frac: Int, + @Json(name = "currency") val curr: String = "" +) { fun toBigDecimal(): BigDecimal = BigDecimal("$value.$frac") @@ -76,6 +77,8 @@ class WithdrawalViewModel( vararg closeables: Closeable ) : ViewModel(*closeables) { + private val retries = 3 + private var exchangeSelected = false private var terminalClient: TerminalClient? = null private val _uiState = MutableStateFlow(MutableWithdrawalOperationState()) @@ -93,11 +96,14 @@ class WithdrawalViewModel( _uiState.value = MutableWithdrawalOperationState() // reset withdrawal operation terminalClient!!.terminalsConfig { + println("terminal config request result present: ${it.isPresent}") if (!it.isPresent) { activity.finish() + } else { + _uiState.value.exchangeBankIntegrationApiUrl = + "${cfg.terminalApiBaseUrl}${TalerConstants.TALER_INTEGRATION}" + this@WithdrawalViewModel.updateCurrency(it.get().currency) } - _uiState.value.exchangeBankIntegrationApiUrl = "${cfg.terminalApiBaseUrl}${TalerConstants.TALER_INTEGRATION}" - this@WithdrawalViewModel.updateCurrency(it.get().currency) } exchangeSelected = true } @@ -161,16 +167,21 @@ class WithdrawalViewModel( onSuccess: () -> Unit, onFailure: () -> Unit ) { - + var retries = 0 + var success = false viewModelScope.launch { - terminalClient!!.retrieveWithdrawalStatus(uiState.value.encodedWopid, 30000) { - if (it.isPresent) { - onSuccess() - } else { - withdrawalOperationFailed() - onFailure() + while (retries < this@WithdrawalViewModel.retries) { + terminalClient!!.retrieveWithdrawalStatus(uiState.value.encodedWopid, 10000) { + if (it.isPresent) { + onSuccess() + success = true + retries = this@WithdrawalViewModel.retries + 1 + } } } + if (!success) {withdrawalOperationFailed() + onFailure() + } } } @@ -215,7 +226,7 @@ class WithdrawalViewModel( if (fracStr.isNotEmpty()) { frac = fracStr.toInt() } - Optional.of(Amount(value, frac)) + Optional.of(Amount(value, frac, uiState.value.currency)) } catch (ex: NumberFormatException) { println(ex.message) Optional.empty() @@ -224,7 +235,7 @@ class WithdrawalViewModel( return try { val value = inp.toInt() - Optional.of(Amount(value, 0)) + Optional.of(Amount(value, 0, uiState.value.currency)) } catch (ex: NumberFormatException) { println(ex.message) Optional.empty()