gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-android] branch master updated (7cd48e3 -> 656ab6b)


From: gnunet
Subject: [taler-taler-android] branch master updated (7cd48e3 -> 656ab6b)
Date: Thu, 13 Apr 2023 16:34:07 +0200

This is an automated email from the git hooks/post-receive script.

torsten-grote pushed a change to branch master
in repository taler-android.

    from 7cd48e3  [pos] Don't crash when adding custom product with huge 
invalid amount
     new 4d37a68  [wallet] Migrated withdrawal and refresh detail to Compose
     new 5a9174f  [wallet] Migrated payment and refund detail to Compose
     new c2b8d13  [wallet] Remove exchangeBaseUrl from Refresh transactions
     new 1c6fda4  [wallet] Clean up compose migration of withdrawal and refresh 
transactions
     new 656ab6b  [wallet] Clean up compose migration of payment and refund 
transactions

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../TransactionPaymentComposable.kt}               | 100 +++++++++---
 .../TransactionRefundComposable.kt}                |  73 +++++----
 .../wallet/transactions/ActionButtonComposable.kt  | 127 +++++++++++++++
 .../transactions/TransactionDetailFragment.kt      |  63 --------
 .../transactions/TransactionLinkComposable.kt      |  86 ++++++++++
 .../transactions/TransactionPaymentFragment.kt     |  53 +++----
 .../transactions/TransactionRefreshFragment.kt     | 106 +++++++++----
 .../transactions/TransactionRefundFragment.kt      |  58 +++----
 .../transactions/TransactionWithdrawalFragment.kt  | 130 ++++++---------
 .../net/taler/wallet/transactions/Transactions.kt  |   1 -
 .../withdraw/TransactionWithdrawalComposable.kt    | 147 +++++++++++++++++
 .../res/layout/fragment_transaction_payment.xml    | 149 -----------------
 .../res/layout/fragment_transaction_withdrawal.xml | 176 ---------------------
 wallet/src/main/res/navigation/nav_graph.xml       |  21 +--
 14 files changed, 647 insertions(+), 643 deletions(-)
 copy 
wallet/src/main/java/net/taler/wallet/{deposit/TransactionDepositComposable.kt 
=> payment/TransactionPaymentComposable.kt} (51%)
 copy 
wallet/src/main/java/net/taler/wallet/{deposit/TransactionDepositComposable.kt 
=> refund/TransactionRefundComposable.kt} (58%)
 create mode 100644 
wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt
 create mode 100644 
wallet/src/main/java/net/taler/wallet/transactions/TransactionLinkComposable.kt
 create mode 100644 
wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
 delete mode 100644 wallet/src/main/res/layout/fragment_transaction_payment.xml
 delete mode 100644 
wallet/src/main/res/layout/fragment_transaction_withdrawal.xml

diff --git 
a/wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt 
b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
similarity index 51%
copy from 
wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt
copy to 
wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
index 3d59b35..c760bb4 100644
--- 
a/wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
@@ -1,6 +1,6 @@
 /*
  * This file is part of GNU Taler
- * (C) 2022 Taler Systems S.A.
+ * (C) 2023 Taler Systems S.A.
  *
  * GNU Taler is free software; you can redistribute it and/or modify it under 
the
  * terms of the GNU General Public License as published by the Free Software
@@ -14,7 +14,7 @@
  * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-package net.taler.wallet.deposit
+package net.taler.wallet.payment
 
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -22,36 +22,46 @@ import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import net.taler.common.Amount
+import net.taler.common.ContractMerchant
 import net.taler.common.Timestamp
 import net.taler.common.toAbsoluteTime
 import net.taler.wallet.R
-import net.taler.wallet.backend.TalerErrorCode.EXCHANGE_GENERIC_KYC_REQUIRED
+import net.taler.wallet.backend.TalerErrorCode
 import net.taler.wallet.backend.TalerErrorInfo
+import net.taler.wallet.compose.TalerSurface
 import net.taler.wallet.transactions.AmountType
 import net.taler.wallet.transactions.DeleteTransactionComposable
 import net.taler.wallet.transactions.ErrorTransactionButton
-import net.taler.wallet.transactions.ExtendedStatus.Pending
+import net.taler.wallet.transactions.ExtendedStatus
+import net.taler.wallet.transactions.PaymentStatus
 import net.taler.wallet.transactions.TransactionAmountComposable
-import net.taler.wallet.transactions.TransactionDeposit
+import net.taler.wallet.transactions.TransactionInfo
+import net.taler.wallet.transactions.TransactionInfoComposable
+import net.taler.wallet.transactions.TransactionLinkComposable
+import net.taler.wallet.transactions.TransactionPayment
 
 @Composable
-fun TransactionDepositComposable(t: TransactionDeposit, devMode: Boolean?, 
onDelete: () -> Unit) {
+fun TransactionPaymentComposable(
+    t: TransactionPayment,
+    devMode: Boolean,
+    onFulfill: (url: String) -> Unit,
+    onDelete: () -> Unit,
+) {
     val scrollState = rememberScrollState()
     Column(
         modifier = Modifier
             .fillMaxWidth()
             .verticalScroll(scrollState),
-        horizontalAlignment = Alignment.CenterHorizontally,
+        horizontalAlignment = CenterHorizontally,
     ) {
         val context = LocalContext.current
         Text(
@@ -69,35 +79,75 @@ fun TransactionDepositComposable(t: TransactionDeposit, 
devMode: Boolean?, onDel
             amount = t.amountRaw,
             amountType = AmountType.Neutral,
         )
-        val fee = t.amountEffective - t.amountRaw
-        if (!fee.isZero()) {
-            TransactionAmountComposable(
-                label = stringResource(id = R.string.withdraw_fees),
-                amount = fee,
-                amountType = AmountType.Negative,
-            )
+        TransactionAmountComposable(
+            label = stringResource(id = R.string.withdraw_fees),
+            amount = t.amountEffective - t.amountRaw,
+            amountType = AmountType.Negative,
+        )
+        PurchaseDetails(info = t.info) {
+            onFulfill(t.info.fulfillmentUrl ?: "")
         }
         DeleteTransactionComposable(onDelete)
-        if (devMode == true && t.error != null) {
+        if (devMode && t.error != null) {
             ErrorTransactionButton(error = t.error)
         }
     }
 }
 
+@Composable
+fun PurchaseDetails(
+    info: TransactionInfo,
+    onClick: () -> Unit,
+) {
+    Column(
+        horizontalAlignment = CenterHorizontally,
+    ) {
+        // Summary and fulfillment message
+        val text = if (info.fulfillmentMessage == null) {
+            info.summary
+        } else {
+            "${info.summary}\n\n${info.fulfillmentMessage}"
+        }
+        if (info.fulfillmentUrl != null) {
+            TransactionLinkComposable(
+                label = stringResource(id = R.string.transaction_order),
+                info = text,
+            ) { onClick() }
+        } else {
+            TransactionInfoComposable(
+                label = stringResource(id = R.string.transaction_order),
+                info = text,
+            )
+        }
+        // Order ID
+        Text(
+            stringResource(id = R.string.transaction_order_id, info.orderId),
+            style = MaterialTheme.typography.bodyMedium,
+        )
+    }
+}
+
 @Preview
 @Composable
-fun TransactionDepositComposablePreview() {
-    val t = TransactionDeposit(
+fun TransactionPaymentComposablePreview() {
+    val t = TransactionPayment(
         transactionId = "transactionId",
         timestamp = Timestamp.fromMillis(System.currentTimeMillis() - 360 * 60 
* 1000),
-        extendedStatus = Pending,
-        depositGroupId = "fooBar",
+        extendedStatus = ExtendedStatus.Pending,
+        info = TransactionInfo(
+            orderId = "123",
+            merchant = ContractMerchant(name = "Taler"),
+            summary = "Some Product that was bought and can have quite a long 
label",
+            fulfillmentMessage = "This is some fulfillment message",
+            fulfillmentUrl = "https://bank.demo.taler.net/";,
+            products = listOf(),
+        ),
+        status = PaymentStatus.Paid,
         amountRaw = Amount.fromDouble("TESTKUDOS", 42.1337),
         amountEffective = Amount.fromDouble("TESTKUDOS", 42.23),
-        targetPaytoUri = "https://exchange.example.org/peer/pull/credit";,
-        error = TalerErrorInfo(code = EXCHANGE_GENERIC_KYC_REQUIRED),
+        error = TalerErrorInfo(code = 
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED),
     )
-    Surface {
-        TransactionDepositComposable(t, true) {}
+    TalerSurface {
+        TransactionPaymentComposable(t = t, devMode = true, onFulfill = {}) {}
     }
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt 
b/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
similarity index 58%
copy from 
wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt
copy to 
wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
index 3d59b35..bb077f1 100644
--- 
a/wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
@@ -1,6 +1,6 @@
 /*
  * This file is part of GNU Taler
- * (C) 2022 Taler Systems S.A.
+ * (C) 2023 Taler Systems S.A.
  *
  * GNU Taler is free software; you can redistribute it and/or modify it under 
the
  * terms of the GNU General Public License as published by the Free Software
@@ -14,7 +14,7 @@
  * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-package net.taler.wallet.deposit
+package net.taler.wallet.refund
 
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -22,36 +22,44 @@ import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import net.taler.common.Amount
+import net.taler.common.ContractMerchant
 import net.taler.common.Timestamp
 import net.taler.common.toAbsoluteTime
 import net.taler.wallet.R
-import net.taler.wallet.backend.TalerErrorCode.EXCHANGE_GENERIC_KYC_REQUIRED
+import net.taler.wallet.backend.TalerErrorCode
 import net.taler.wallet.backend.TalerErrorInfo
+import net.taler.wallet.compose.TalerSurface
+import net.taler.wallet.payment.PurchaseDetails
 import net.taler.wallet.transactions.AmountType
 import net.taler.wallet.transactions.DeleteTransactionComposable
 import net.taler.wallet.transactions.ErrorTransactionButton
-import net.taler.wallet.transactions.ExtendedStatus.Pending
+import net.taler.wallet.transactions.ExtendedStatus
 import net.taler.wallet.transactions.TransactionAmountComposable
-import net.taler.wallet.transactions.TransactionDeposit
+import net.taler.wallet.transactions.TransactionInfo
+import net.taler.wallet.transactions.TransactionRefund
 
 @Composable
-fun TransactionDepositComposable(t: TransactionDeposit, devMode: Boolean?, 
onDelete: () -> Unit) {
+fun TransactionRefundComposable(
+    t: TransactionRefund,
+    devMode: Boolean,
+    onFulfill: (url: String) -> Unit,
+    onDelete: () -> Unit,
+) {
     val scrollState = rememberScrollState()
     Column(
         modifier = Modifier
             .fillMaxWidth()
             .verticalScroll(scrollState),
-        horizontalAlignment = Alignment.CenterHorizontally,
+        horizontalAlignment = CenterHorizontally,
     ) {
         val context = LocalContext.current
         Text(
@@ -60,25 +68,25 @@ fun TransactionDepositComposable(t: TransactionDeposit, 
devMode: Boolean?, onDel
             style = MaterialTheme.typography.bodyLarge,
         )
         TransactionAmountComposable(
-            label = stringResource(id = R.string.transaction_paid),
+            label = stringResource(id = R.string.transaction_refund),
             amount = t.amountEffective,
-            amountType = AmountType.Negative,
+            amountType = AmountType.Positive,
         )
         TransactionAmountComposable(
             label = stringResource(id = R.string.transaction_order_total),
             amount = t.amountRaw,
             amountType = AmountType.Neutral,
         )
-        val fee = t.amountEffective - t.amountRaw
-        if (!fee.isZero()) {
-            TransactionAmountComposable(
-                label = stringResource(id = R.string.withdraw_fees),
-                amount = fee,
-                amountType = AmountType.Negative,
-            )
+        TransactionAmountComposable(
+            label = stringResource(id = R.string.withdraw_fees),
+            amount = t.amountRaw - t.amountEffective,
+            amountType = AmountType.Negative,
+        )
+        PurchaseDetails(info = t.info) {
+            onFulfill(t.info.fulfillmentUrl ?: "")
         }
         DeleteTransactionComposable(onDelete)
-        if (devMode == true && t.error != null) {
+        if (devMode && t.error != null) {
             ErrorTransactionButton(error = t.error)
         }
     }
@@ -86,18 +94,25 @@ fun TransactionDepositComposable(t: TransactionDeposit, 
devMode: Boolean?, onDel
 
 @Preview
 @Composable
-fun TransactionDepositComposablePreview() {
-    val t = TransactionDeposit(
+fun TransactionRefundComposablePreview() {
+    val t = TransactionRefund(
         transactionId = "transactionId",
         timestamp = Timestamp.fromMillis(System.currentTimeMillis() - 360 * 60 
* 1000),
-        extendedStatus = Pending,
-        depositGroupId = "fooBar",
-        amountRaw = Amount.fromDouble("TESTKUDOS", 42.1337),
-        amountEffective = Amount.fromDouble("TESTKUDOS", 42.23),
-        targetPaytoUri = "https://exchange.example.org/peer/pull/credit";,
-        error = TalerErrorInfo(code = EXCHANGE_GENERIC_KYC_REQUIRED),
+        extendedStatus = ExtendedStatus.Pending,
+        info = TransactionInfo(
+            orderId = "123",
+            merchant = ContractMerchant(name = "Taler"),
+            summary = "Some Product that was bought and can have quite a long 
label",
+            fulfillmentMessage = "This is some fulfillment message",
+            fulfillmentUrl = "https://bank.demo.taler.net/";,
+            products = listOf(),
+        ),
+        refundedTransactionId = "transactionId",
+        amountRaw = Amount.fromDouble("TESTKUDOS", 42.23),
+        amountEffective = Amount.fromDouble("TESTKUDOS", 42.1337),
+        error = TalerErrorInfo(code = 
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED),
     )
-    Surface {
-        TransactionDepositComposable(t, true) {}
+    TalerSurface {
+        TransactionRefundComposable(t = t, devMode = true, onFulfill = {}) {}
     }
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt 
b/wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt
new file mode 100644
index 0000000..d4c12aa
--- /dev/null
+++ 
b/wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt
@@ -0,0 +1,127 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2023 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under 
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+ * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.transactions
+
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.AccountBalance
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import net.taler.wallet.R
+import net.taler.wallet.backend.TalerErrorCode
+import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer
+import net.taler.wallet.transactions.WithdrawalDetails.TalerBankIntegrationApi
+
+interface ActionListener {
+    enum class Type {
+        COMPLETE_KYC,
+        CONFIRM_WITH_BANK,
+        CONFIRM_MANUAL
+    }
+
+    fun onActionButtonClicked(tx: Transaction, type: Type)
+}
+
+@Composable
+fun ActionButton(
+    modifier: Modifier = Modifier,
+    tx: TransactionWithdrawal,
+    listener: ActionListener,
+) {
+    if (tx.error != null) {
+        // There is an error!
+        when (tx.error.code) {
+            TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED -> {
+                KycButton(modifier, tx, listener)
+            }
+            else -> {}
+        }
+    } else if (!tx.confirmed) {
+        // There is a transaction!
+        if (tx.withdrawalDetails is TalerBankIntegrationApi &&
+            tx.withdrawalDetails.bankConfirmationUrl != null
+        ) {
+            // The transaction can be completed with a link!
+            ConfirmBankButton(modifier, tx, listener)
+        } else if (tx.withdrawalDetails is ManualTransfer) {
+            // The transaction must be completed manually!
+            ConfirmManualButton(modifier, tx, listener)
+        }
+    }
+}
+
+@Composable
+private fun KycButton(
+    modifier: Modifier = Modifier,
+    tx: TransactionWithdrawal,
+    listener: ActionListener,
+) {
+    Button(
+        onClick = { listener.onActionButtonClicked(tx, 
ActionListener.Type.COMPLETE_KYC) },
+        modifier = modifier,
+    ) {
+        Text(stringResource(R.string.transaction_action_kyc))
+    }
+}
+
+@Composable
+private fun ConfirmBankButton(
+    modifier: Modifier = Modifier,
+    tx: TransactionWithdrawal,
+    listener: ActionListener,
+) {
+    Button(
+        onClick = { listener.onActionButtonClicked(tx, 
ActionListener.Type.CONFIRM_WITH_BANK) },
+        modifier = modifier,
+    ) {
+        val label = stringResource(R.string.withdraw_button_confirm_bank)
+        Icon(
+            Icons.Default.AccountBalance,
+            label,
+            modifier = Modifier.size(ButtonDefaults.IconSize)
+        )
+        Spacer(Modifier.size(ButtonDefaults.IconSpacing))
+        Text(label)
+    }
+}
+
+@Composable
+private fun ConfirmManualButton(
+    modifier: Modifier = Modifier,
+    tx: TransactionWithdrawal,
+    listener: ActionListener,
+) {
+    Button(
+        onClick = { listener.onActionButtonClicked(tx, 
ActionListener.Type.CONFIRM_MANUAL) },
+        modifier = modifier,
+    ) {
+        val label = 
stringResource(R.string.withdraw_manual_ready_details_intro)
+        Icon(
+            Icons.Default.AccountBalance,
+            label,
+            modifier = Modifier.size(ButtonDefaults.IconSize)
+        )
+        Spacer(Modifier.size(ButtonDefaults.IconSpacing))
+        Text(label)
+    }
+}
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
index d37728f..678bed2 100644
--- 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
@@ -17,25 +17,16 @@
 package net.taler.wallet.transactions
 
 import android.os.Bundle
-import android.text.SpannableString
-import android.text.style.UnderlineSpan
 import android.view.Menu
 import android.view.MenuInflater
 import android.view.MenuItem
-import android.widget.TextView
 import androidx.annotation.StringRes
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import androidx.navigation.fragment.findNavController
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import kotlinx.serialization.encodeToString
-import kotlinx.serialization.json.Json
-import net.taler.common.Amount
 import net.taler.wallet.MainViewModel
 import net.taler.wallet.R
-import net.taler.wallet.compose.copyToClipBoard
-import net.taler.wallet.getAttrColor
-import net.taler.wallet.launchInAppBrowser
 
 abstract class TransactionDetailFragment : Fragment() {
 
@@ -72,34 +63,6 @@ abstract class TransactionDetailFragment : Fragment() {
         }
     }
 
-    protected fun bindOrderAndFee(
-        orderSummaryView: TextView,
-        orderAmountView: TextView,
-        orderIdView: TextView,
-        feeView: TextView,
-        info: TransactionInfo,
-        raw: Amount,
-        fee: Amount,
-    ) {
-        orderAmountView.text = raw.toString()
-        feeView.text = getString(R.string.amount_negative, fee.toString())
-        orderSummaryView.text = if (info.fulfillmentMessage == null) {
-            info.summary
-        } else {
-            "${info.summary}\n\n${info.fulfillmentMessage}"
-        }
-        if (info.fulfillmentUrl?.startsWith("http", ignoreCase = true) == 
true) {
-            val content = SpannableString(info.summary)
-            content.setSpan(UnderlineSpan(), 0, info.summary.length, 0)
-            orderSummaryView.text = content
-            
orderSummaryView.setTextColor(requireContext().getAttrColor(android.R.attr.textColorLink))
-            orderSummaryView.setOnClickListener {
-                launchInAppBrowser(requireContext(), info.fulfillmentUrl)
-            }
-        }
-        orderIdView.text = getString(R.string.transaction_order_id, 
info.orderId)
-    }
-
     @StringRes
     protected open val deleteDialogTitle = R.string.transactions_delete
 
@@ -128,30 +91,4 @@ abstract class TransactionDetailFragment : Fragment() {
         findNavController().popBackStack()
     }
 
-    protected fun onShowErrorButtonClicked(t: Transaction) {
-        val err = t.error
-        require(err != null) { "Transaction had no error." }
-
-        @Suppress("OPT_IN_USAGE")
-        val json = Json {
-            prettyPrint = true
-            prettyPrintIndent = "  "
-        }
-        val message = json.encodeToString(err)
-        MaterialAlertDialogBuilder(requireContext(), 
R.style.MaterialAlertDialog_Material3)
-            .setTitle(getString(R.string.nav_error))
-            .setMessage(message)
-            .setNeutralButton(R.string.close) { dialog, _ ->
-                dialog.cancel()
-            }
-            .setPositiveButton(R.string.copy) { _, _ ->
-                copyToClipBoard(
-                    requireContext(),
-                    getString(R.string.nav_error),
-                    message,
-                )
-            }
-            .show()
-    }
-
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionLinkComposable.kt
 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionLinkComposable.kt
new file mode 100644
index 0000000..e8fca0f
--- /dev/null
+++ 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionLinkComposable.kt
@@ -0,0 +1,86 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2023 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under 
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+ * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.transactions
+
+import android.R
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.ClickableText
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import net.taler.wallet.compose.TalerSurface
+import net.taler.wallet.getAttrColor
+
+@Composable
+// FIXME this assumes that it is used in a column and applies its own padding, 
not really re-usable
+fun TransactionLinkComposable(label: String, info: String, onClick: () -> 
Unit) {
+    Text(
+        modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp),
+        text = label,
+        style = MaterialTheme.typography.bodyMedium,
+    )
+    val context = LocalContext.current
+    val linkColor = Color(context.getAttrColor(R.attr.textColorLink))
+    val annotatedString = buildAnnotatedString {
+        pushStringAnnotation(tag = "url", annotation = info)
+        withStyle(style = SpanStyle(color = linkColor)) {
+            append(info)
+        }
+        pop()
+    }
+    ClickableText(
+        modifier = Modifier.padding(top = 8.dp, start = 16.dp, end = 16.dp, 
bottom = 16.dp),
+        text = annotatedString,
+        style = TextStyle(fontSize = 24.sp, textAlign = TextAlign.Center),
+    ) { offset ->
+        annotatedString.getStringAnnotations(
+            tag = "url",
+            start = offset,
+            end = offset,
+        ).firstOrNull()?.let {
+            onClick()
+        }
+    }
+}
+
+@Preview
+@Composable
+fun TransactionLinkComposablePreview() {
+    TalerSurface {
+        Column(
+            horizontalAlignment = CenterHorizontally,
+        ) {
+            TransactionLinkComposable(
+                label = "This is a label",
+                info = "This is some fulfillment message"
+            ) {}
+        }
+    }
+}
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
index 068a41e..e9eb5b8 100644
--- 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
@@ -19,50 +19,33 @@ package net.taler.wallet.transactions
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
-import android.view.View.VISIBLE
 import android.view.ViewGroup
-import net.taler.common.toAbsoluteTime
-import net.taler.wallet.databinding.FragmentTransactionPaymentBinding
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.platform.ComposeView
+import net.taler.wallet.compose.TalerSurface
+import net.taler.wallet.launchInAppBrowser
+import net.taler.wallet.payment.TransactionPaymentComposable
 
 class TransactionPaymentFragment : TransactionDetailFragment() {
 
-    private lateinit var ui: FragmentTransactionPaymentBinding
-
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
         savedInstanceState: Bundle?,
-    ): View {
-        ui = FragmentTransactionPaymentBinding.inflate(inflater, container, 
false)
-        return ui.root
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        transactionManager.selectedTransaction.observe(viewLifecycleOwner) { t 
->
-            if (t !is TransactionPayment) return@observe
-            ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
-
-            ui.amountPaidWithFeesView.text = t.amountEffective.toString()
-            val fee = t.amountEffective - t.amountRaw
-            bindOrderAndFee(
-                ui.orderSummaryView,
-                ui.orderAmountView,
-                ui.orderIdView,
-                ui.feeView,
-                t.info,
-                t.amountRaw,
-                fee
-            )
-            ui.deleteButton.setOnClickListener {
-                onDeleteButtonClicked(t)
-            }
-            if (devMode.value == true && t.error != null) {
-                ui.showErrorButton.visibility = VISIBLE
-                ui.showErrorButton.setOnClickListener {
-                    onShowErrorButtonClicked(t)
-                }
+    ): View = ComposeView(requireContext()).apply {
+        setContent {
+            TalerSurface {
+                val t = 
transactionManager.selectedTransaction.observeAsState().value
+                val devMode = devMode.observeAsState().value ?: false
+                if (t is TransactionPayment) TransactionPaymentComposable(t, 
devMode,
+                    onFulfill = { url ->
+                        launchInAppBrowser(requireContext(), url)
+                    },
+                    onDelete = {
+                        onDeleteButtonClicked(t)
+                    }
+                )
             }
         }
     }
-
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
index 36d3bc7..391eefa 100644
--- 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
@@ -19,50 +19,94 @@ package net.taler.wallet.transactions
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
-import android.view.View.GONE
-import android.view.View.VISIBLE
 import android.view.ViewGroup
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import net.taler.common.Amount
+import net.taler.common.Timestamp
 import net.taler.common.toAbsoluteTime
 import net.taler.wallet.R
-import net.taler.wallet.cleanExchange
-import net.taler.wallet.databinding.FragmentTransactionWithdrawalBinding
+import net.taler.wallet.backend.TalerErrorCode
+import net.taler.wallet.backend.TalerErrorInfo
+import net.taler.wallet.compose.TalerSurface
 
 class TransactionRefreshFragment : TransactionDetailFragment() {
 
-    private lateinit var ui: FragmentTransactionWithdrawalBinding
-
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
         savedInstanceState: Bundle?,
-    ): View {
-        ui = FragmentTransactionWithdrawalBinding.inflate(inflater, container, 
false)
-        return ui.root
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        transactionManager.selectedTransaction.observe(viewLifecycleOwner) { t 
->
-            if (t !is TransactionRefresh) return@observe
-            ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
-
-            ui.effectiveAmountLabel.visibility = GONE
-            ui.effectiveAmountView.visibility = GONE
-            ui.confirmWithdrawalButton.visibility = GONE
-            ui.chosenAmountLabel.visibility = GONE
-            ui.chosenAmountView.visibility = GONE
-            val fee = t.amountEffective
-            ui.feeView.text = getString(R.string.amount_negative, 
fee.toString())
-            ui.exchangeView.text = cleanExchange(t.exchangeBaseUrl)
-            ui.deleteButton.setOnClickListener {
-                onDeleteButtonClicked(t)
-            }
-            if (devMode.value == true && t.error != null) {
-                ui.showErrorButton.visibility = VISIBLE
-                ui.showErrorButton.setOnClickListener {
-                    onShowErrorButtonClicked(t)
+    ): View = ComposeView(requireContext()).apply {
+        setContent {
+            TalerSurface {
+                val t = 
transactionManager.selectedTransaction.observeAsState().value
+                val devMode = devMode.observeAsState().value ?: false
+                if (t is TransactionRefresh) TransactionRefreshComposable(t, 
devMode) {
+                    onDeleteButtonClicked(t)
                 }
             }
         }
     }
+}
 
+@Composable
+private fun TransactionRefreshComposable(
+    t: TransactionRefresh,
+    devMode: Boolean,
+    onDelete: () -> Unit,
+) {
+    val scrollState = rememberScrollState()
+    Column(
+        modifier = Modifier
+            .fillMaxWidth()
+            .verticalScroll(scrollState),
+        horizontalAlignment = CenterHorizontally,
+    ) {
+        val context = LocalContext.current
+        Text(
+            modifier = Modifier.padding(16.dp),
+            text = t.timestamp.ms.toAbsoluteTime(context).toString(),
+            style = MaterialTheme.typography.bodyLarge,
+        )
+        TransactionAmountComposable(
+            label = stringResource(id = R.string.withdraw_fees),
+            amount = t.amountEffective,
+            amountType = AmountType.Negative,
+        )
+        DeleteTransactionComposable(onDelete)
+        if (devMode && t.error != null) {
+            ErrorTransactionButton(error = t.error)
+        }
+    }
+}
+
+@Preview
+@Composable
+private fun TransactionRefreshComposablePreview() {
+    val t = TransactionRefresh(
+        transactionId = "transactionId",
+        timestamp = Timestamp.fromMillis(System.currentTimeMillis() - 360 * 60 
* 1000),
+        extendedStatus = ExtendedStatus.Pending,
+        amountRaw = Amount.fromDouble("TESTKUDOS", 42.23),
+        amountEffective = Amount.fromDouble("TESTKUDOS", 42.1337),
+        error = TalerErrorInfo(code = 
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED),
+    )
+    Surface {
+        TransactionRefreshComposable(t, true) {}
+    }
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
index 9c30609..61c0364 100644
--- 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
@@ -19,55 +19,33 @@ package net.taler.wallet.transactions
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
-import android.view.View.VISIBLE
 import android.view.ViewGroup
-import androidx.core.content.ContextCompat.getColor
-import net.taler.common.toAbsoluteTime
-import net.taler.wallet.R
-import net.taler.wallet.databinding.FragmentTransactionPaymentBinding
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.platform.ComposeView
+import net.taler.wallet.compose.TalerSurface
+import net.taler.wallet.launchInAppBrowser
+import net.taler.wallet.refund.TransactionRefundComposable
 
 class TransactionRefundFragment : TransactionDetailFragment() {
 
-    private lateinit var ui: FragmentTransactionPaymentBinding
-
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
         savedInstanceState: Bundle?,
-    ): View {
-        ui = FragmentTransactionPaymentBinding.inflate(inflater, container, 
false)
-        return ui.root
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        transactionManager.selectedTransaction.observe(viewLifecycleOwner) { t 
->
-            if (t !is TransactionRefund) return@observe
-            ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
-
-            ui.amountPaidWithFeesLabel.text = 
getString(R.string.transaction_refund)
-            ui.amountPaidWithFeesView.setTextColor(getColor(requireContext(), 
R.color.green))
-            ui.amountPaidWithFeesView.text =
-                getString(R.string.amount_positive, 
t.amountEffective.toString())
-            val fee = t.amountRaw - t.amountEffective
-            bindOrderAndFee(
-                ui.orderSummaryView,
-                ui.orderAmountView,
-                ui.orderIdView,
-                ui.feeView,
-                t.info,
-                t.amountRaw,
-                fee
-            )
-            ui.deleteButton.setOnClickListener {
-                onDeleteButtonClicked(t)
-            }
-            if (devMode.value == true && t.error != null) {
-                ui.showErrorButton.visibility = VISIBLE
-                ui.showErrorButton.setOnClickListener {
-                    onShowErrorButtonClicked(t)
-                }
+    ): View = ComposeView(requireContext()).apply {
+        setContent {
+            TalerSurface {
+                val t = 
transactionManager.selectedTransaction.observeAsState().value
+                val devMode = devMode.observeAsState().value ?: false
+                if (t is TransactionRefund) TransactionRefundComposable(t, 
devMode,
+                    onFulfill = { url ->
+                        launchInAppBrowser(requireContext(), url)
+                    },
+                    onDelete = {
+                        onDeleteButtonClicked(t)
+                    }
+                )
             }
         }
     }
-
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
index ad70d2f..7a85522 100644
--- 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
@@ -19,70 +19,26 @@ package net.taler.wallet.transactions
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
-import android.view.View.GONE
-import android.view.View.VISIBLE
 import android.view.ViewGroup
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.platform.ComposeView
 import androidx.fragment.app.activityViewModels
 import androidx.navigation.fragment.findNavController
-import net.taler.common.toAbsoluteTime
 import net.taler.wallet.MainViewModel
 import net.taler.wallet.R
-import net.taler.wallet.cleanExchange
-import net.taler.wallet.databinding.FragmentTransactionWithdrawalBinding
-import net.taler.wallet.handleKyc
+import net.taler.wallet.compose.TalerSurface
 import net.taler.wallet.launchInAppBrowser
-import net.taler.wallet.transactions.ExtendedStatus.Pending
 import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer
 import net.taler.wallet.transactions.WithdrawalDetails.TalerBankIntegrationApi
+import net.taler.wallet.withdraw.TransactionWithdrawalComposable
 import net.taler.wallet.withdraw.createManualTransferRequired
 
-class TransactionWithdrawalFragment : TransactionDetailFragment() {
+class TransactionWithdrawalFragment : TransactionDetailFragment(), 
ActionListener {
 
     private val model: MainViewModel by activityViewModels()
     private val withdrawManager by lazy { model.withdrawManager }
-    private lateinit var ui: FragmentTransactionWithdrawalBinding
 
-    override fun onCreateView(
-        inflater: LayoutInflater,
-        container: ViewGroup?,
-        savedInstanceState: Bundle?,
-    ): View {
-        ui = FragmentTransactionWithdrawalBinding.inflate(inflater, container, 
false)
-        return ui.root
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        transactionManager.selectedTransaction.observe(viewLifecycleOwner) { t 
->
-            if (t !is TransactionWithdrawal) return@observe
-            ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
-
-            ui.effectiveAmountLabel.text = getString(R.string.withdraw_total)
-            ui.effectiveAmountView.text = t.amountEffective.toString()
-            setupConfirmWithdrawalButton(t)
-            setupActionButton(t)
-            ui.chosenAmountLabel.text = getString(R.string.amount_chosen)
-            ui.chosenAmountView.text =
-                getString(R.string.amount_positive, t.amountRaw.toString())
-            val fee = t.amountRaw - t.amountEffective
-            ui.feeView.text = getString(R.string.amount_negative, 
fee.toString())
-            ui.exchangeView.text = cleanExchange(t.exchangeBaseUrl)
-            if (t.extendedStatus == Pending) {
-                ui.deleteButton.setIconResource(R.drawable.ic_cancel)
-                ui.deleteButton.setText(R.string.cancel)
-            }
-            ui.deleteButton.setOnClickListener {
-                onDeleteButtonClicked(t)
-            }
-            if (devMode.value == true && t.error != null) {
-                ui.showErrorButton.visibility = VISIBLE
-                ui.showErrorButton.setOnClickListener {
-                    onShowErrorButtonClicked(t)
-                }
-            }
-        }
-    }
-
-    private val isPending get() = 
transactionManager.selectedTransaction.value?.extendedStatus == Pending
+    private val isPending get() = 
transactionManager.selectedTransaction.value?.extendedStatus == 
ExtendedStatus.Pending
 
     override val deleteDialogTitle: Int
         get() = if (isPending) R.string.cancel else super.deleteDialogTitle
@@ -92,42 +48,56 @@ class TransactionWithdrawalFragment : 
TransactionDetailFragment() {
     override val deleteDialogButton: Int
         get() = if (isPending) R.string.ok else super.deleteDialogButton
 
-    private fun setupConfirmWithdrawalButton(t: TransactionWithdrawal) {
-        if (t.extendedStatus == Pending && !t.confirmed) {
-            if (t.withdrawalDetails is TalerBankIntegrationApi &&
-                t.withdrawalDetails.bankConfirmationUrl != null
-            ) {
-                ui.confirmWithdrawalButton.setOnClickListener {
-                    launchInAppBrowser(requireContext(), 
t.withdrawalDetails.bankConfirmationUrl)
-                }
-            } else if (t.withdrawalDetails is ManualTransfer) {
-                
ui.confirmWithdrawalButton.setText(R.string.withdraw_manual_ready_details_intro)
-                ui.confirmWithdrawalButton.setOnClickListener {
-                    val status = createManualTransferRequired(
-                        amount = t.amountRaw,
-                        exchangeBaseUrl = t.exchangeBaseUrl,
-                        // TODO what if there's more than one or no URI?
-                        uriStr = t.withdrawalDetails.exchangePaytoUris[0],
-                        transactionId = t.transactionId,
-                    )
-                    withdrawManager.viewManualWithdrawal(status)
-                    findNavController().navigate(
-                        
R.id.action_nav_transactions_detail_withdrawal_to_nav_exchange_manual_withdrawal_success
-                    )
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?,
+    ): View = ComposeView(requireContext()).apply {
+        setContent {
+            TalerSurface {
+                val t = 
transactionManager.selectedTransaction.observeAsState().value
+                val devMode = devMode.observeAsState().value ?: false
+                if (t is TransactionWithdrawal) 
TransactionWithdrawalComposable(
+                    t = t,
+                    devMode = devMode,
+                    actionListener = this@TransactionWithdrawalFragment,
+                ) {
+                    onDeleteButtonClicked(t)
                 }
-            } else ui.confirmWithdrawalButton.visibility = GONE
-        } else ui.confirmWithdrawalButton.visibility = GONE
+            }
+        }
     }
 
-    private fun setupActionButton(t: TransactionWithdrawal) {
-        ui.actionButton.visibility = t.handleKyc({ GONE }) { error ->
-            ui.actionButton.setText(R.string.transaction_action_kyc)
-            error.getStringExtra("kycUrl")?.let { kycUrl ->
-                ui.actionButton.setOnClickListener {
+    override fun onActionButtonClicked(tx: Transaction, type: 
ActionListener.Type) {
+        when (type) {
+            ActionListener.Type.COMPLETE_KYC -> {
+                tx.error?.getStringExtra("kycUrl")?.let { kycUrl ->
                     launchInAppBrowser(requireContext(), kycUrl)
                 }
             }
-            VISIBLE
+            ActionListener.Type.CONFIRM_WITH_BANK -> {
+                if (tx !is TransactionWithdrawal) return
+                if (tx.withdrawalDetails !is TalerBankIntegrationApi) return
+                tx.withdrawalDetails.bankConfirmationUrl?.let { url ->
+                    launchInAppBrowser(requireContext(), url)
+                }
+            }
+            ActionListener.Type.CONFIRM_MANUAL -> {
+                if (tx !is TransactionWithdrawal) return
+                if (tx.withdrawalDetails !is ManualTransfer) return
+                // TODO what if there's more than one or no URI?
+                if (tx.withdrawalDetails.exchangePaytoUris.isEmpty()) return
+                val status = createManualTransferRequired(
+                    amount = tx.amountRaw,
+                    exchangeBaseUrl = tx.exchangeBaseUrl,
+                    uriStr = tx.withdrawalDetails.exchangePaytoUris[0],
+                    transactionId = tx.transactionId,
+                )
+                withdrawManager.viewManualWithdrawal(status)
+                findNavController().navigate(
+                    
R.id.action_nav_transactions_detail_withdrawal_to_nav_exchange_manual_withdrawal_success,
+                )
+            }
         }
     }
 }
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt 
b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
index 68d0bc4..a306685 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
@@ -264,7 +264,6 @@ class TransactionRefresh(
     override val transactionId: String,
     override val timestamp: Timestamp,
     override val extendedStatus: ExtendedStatus,
-    val exchangeBaseUrl: String,
     override val error: TalerErrorInfo? = null,
     override val amountRaw: Amount,
     override val amountEffective: Amount,
diff --git 
a/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
 
b/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
new file mode 100644
index 0000000..f1a22d3
--- /dev/null
+++ 
b/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
@@ -0,0 +1,147 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2023 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under 
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+ * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.withdraw
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Alignment.Companion.CenterVertically
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import net.taler.common.Amount
+import net.taler.common.Timestamp
+import net.taler.common.toAbsoluteTime
+import net.taler.wallet.R
+import net.taler.wallet.backend.TalerErrorCode
+import net.taler.wallet.backend.TalerErrorInfo
+import net.taler.wallet.cleanExchange
+import net.taler.wallet.transactions.ActionButton
+import net.taler.wallet.transactions.ActionListener
+import net.taler.wallet.transactions.AmountType
+import net.taler.wallet.transactions.DeleteTransactionComposable
+import net.taler.wallet.transactions.ErrorTransactionButton
+import net.taler.wallet.transactions.ExtendedStatus
+import net.taler.wallet.transactions.Transaction
+import net.taler.wallet.transactions.TransactionAmountComposable
+import net.taler.wallet.transactions.TransactionInfoComposable
+import net.taler.wallet.transactions.TransactionWithdrawal
+import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer
+
+@Composable
+fun TransactionWithdrawalComposable(
+    t: TransactionWithdrawal,
+    devMode: Boolean,
+    actionListener: ActionListener,
+    onDelete: () -> Unit,
+) {
+    val scrollState = rememberScrollState()
+    Column(
+        modifier = Modifier
+            .fillMaxWidth()
+            .verticalScroll(scrollState),
+        horizontalAlignment = Alignment.CenterHorizontally,
+    ) {
+        val context = LocalContext.current
+        Text(
+            modifier = Modifier.padding(16.dp),
+            text = t.timestamp.ms.toAbsoluteTime(context).toString(),
+            style = MaterialTheme.typography.bodyLarge,
+        )
+        TransactionAmountComposable(
+            label = stringResource(id = R.string.withdraw_total),
+            amount = t.amountEffective,
+            amountType = AmountType.Positive,
+        )
+        ActionButton(tx = t, listener = actionListener)
+        TransactionAmountComposable(
+            label = stringResource(id = R.string.amount_chosen),
+            amount = t.amountRaw,
+            amountType = AmountType.Neutral,
+        )
+        TransactionAmountComposable(
+            label = stringResource(id = R.string.withdraw_fees),
+            amount = t.amountRaw - t.amountEffective,
+            amountType = AmountType.Negative,
+        )
+        TransactionInfoComposable(
+            label = stringResource(id = R.string.withdraw_exchange),
+            info = cleanExchange(t.exchangeBaseUrl),
+        )
+        if (t.extendedStatus == ExtendedStatus.Pending) {
+            Button(
+                modifier = Modifier.padding(16.dp),
+                colors = ButtonDefaults.buttonColors(containerColor = 
MaterialTheme.colorScheme.error),
+                onClick = onDelete,
+            ) {
+                Row(verticalAlignment = CenterVertically) {
+                    Icon(
+                        painter = painterResource(id = R.drawable.ic_cancel),
+                        contentDescription = null,
+                        tint = MaterialTheme.colorScheme.onError,
+                    )
+                    Text(
+                        modifier = Modifier.padding(start = 8.dp),
+                        text = stringResource(R.string.cancel),
+                        color = MaterialTheme.colorScheme.onError,
+                    )
+                }
+            }
+        } else {
+            DeleteTransactionComposable(onDelete)
+        }
+        if (devMode && t.error != null) {
+            ErrorTransactionButton(error = t.error)
+        }
+    }
+}
+
+@Preview
+@Composable
+fun TransactionWithdrawalComposablePreview() {
+    val t = TransactionWithdrawal(
+        transactionId = "transactionId",
+        timestamp = Timestamp.fromMillis(System.currentTimeMillis() - 360 * 60 
* 1000),
+        extendedStatus = ExtendedStatus.Pending,
+        exchangeBaseUrl = "https://exchange.demo.taler.net/";,
+        withdrawalDetails = ManualTransfer(exchangePaytoUris = emptyList()),
+        amountRaw = Amount.fromDouble("TESTKUDOS", 42.23),
+        amountEffective = Amount.fromDouble("TESTKUDOS", 42.1337),
+        error = TalerErrorInfo(code = 
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED),
+    )
+    val listener = object : ActionListener {
+        override fun onActionButtonClicked(tx: Transaction, type: 
ActionListener.Type) {
+        }
+    }
+    Surface {
+        TransactionWithdrawalComposable(t, true, listener) {}
+    }
+}
diff --git a/wallet/src/main/res/layout/fragment_transaction_payment.xml 
b/wallet/src/main/res/layout/fragment_transaction_payment.xml
deleted file mode 100644
index 5b674bd..0000000
--- a/wallet/src/main/res/layout/fragment_transaction_payment.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ This file is part of GNU Taler
-  ~ (C) 2020 Taler Systems S.A.
-  ~
-  ~ GNU Taler is free software; you can redistribute it and/or modify it under 
the
-  ~ terms of the GNU General Public License as published by the Free Software
-  ~ Foundation; either version 3, or (at your option) any later version.
-  ~
-  ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT 
ANY
-  ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
-  ~ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-  ~
-  ~ You should have received a copy of the GNU General Public License along 
with
-  ~ GNU Taler; see the file COPYING.  If not, see 
<http://www.gnu.org/licenses/>
-  -->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android";
-    xmlns:app="http://schemas.android.com/apk/res-auto";
-    xmlns:tools="http://schemas.android.com/tools";
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:fillViewport="true"
-    tools:context=".transactions.TransactionDetailFragment">
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-        <TextView
-            android:id="@+id/timeView"
-            style="@style/TransactionLabel.Time"
-            app:layout_constraintBottom_toTopOf="@+id/amountPaidWithFeesLabel"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            tools:text="23 March 2020 23:42pm" />
-
-        <TextView
-            android:id="@+id/amountPaidWithFeesLabel"
-            style="@style/TransactionLabel"
-            android:text="@string/transaction_paid"
-            app:layout_constraintBottom_toTopOf="@+id/amountPaidWithFeesView"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/timeView" />
-
-        <TextView
-            android:id="@+id/amountPaidWithFeesView"
-            style="@style/TransactionContent"
-            android:textColor="?colorError"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/amountPaidWithFeesLabel"
-            tools:text="-23.42 TESTKUDOS" />
-
-        <TextView
-            android:id="@+id/orderAmountLabel"
-            style="@style/TransactionLabel"
-            android:text="@string/transaction_order_total"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/amountPaidWithFeesView" 
/>
-
-        <TextView
-            android:id="@+id/orderAmountView"
-            style="@style/TransactionContent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/orderAmountLabel"
-            tools:text="23 TESTKUDOS" />
-
-        <TextView
-            android:id="@+id/feeLabel"
-            style="@style/TransactionLabel"
-            android:text="@string/withdraw_fees"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/orderAmountView" />
-
-        <TextView
-            android:id="@+id/feeView"
-            style="@style/TransactionContent"
-            android:textColor="?colorError"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/feeLabel"
-            tools:text="-0.42 TESTKUDOS" />
-
-        <TextView
-            android:id="@+id/orderSummaryLabel"
-            style="@style/TransactionLabel"
-            android:text="@string/transaction_order"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/feeView" />
-
-        <TextView
-            android:id="@+id/orderSummaryView"
-            style="@style/TransactionContent"
-            android:textColor="?android:textColorPrimary"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/orderSummaryLabel"
-            tools:text="Some Product that was bought and can have quite a long 
label" />
-
-        <TextView
-            android:id="@+id/orderIdView"
-            style="@style/TransactionLabel"
-            android:layout_marginBottom="16dp"
-            android:text="@string/transaction_order_id"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/orderSummaryView" />
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/deleteButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginVertical="10dp"
-            android:text="@string/transactions_delete"
-            android:textColor="?colorOnError"
-            app:backgroundTint="?colorError"
-            app:icon="@drawable/ic_delete"
-            app:iconTint="?colorOnError"
-            app:layout_constraintBottom_toTopOf="@id/showErrorButton"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/orderIdView" />
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/showErrorButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginVertical="10dp"
-            android:visibility="gone"
-            android:text="@string/nav_error"
-            app:backgroundTint="?colorError"
-            app:icon="@drawable/ic_error"
-            android:textColor="?colorOnError"
-            app:iconTint="?colorOnError"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/deleteButton"
-            tools:visibility="visible" />
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</ScrollView>
diff --git a/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml 
b/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml
deleted file mode 100644
index 87530a4..0000000
--- a/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml
+++ /dev/null
@@ -1,176 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ This file is part of GNU Taler
-  ~ (C) 2020 Taler Systems S.A.
-  ~
-  ~ GNU Taler is free software; you can redistribute it and/or modify it under 
the
-  ~ terms of the GNU General Public License as published by the Free Software
-  ~ Foundation; either version 3, or (at your option) any later version.
-  ~
-  ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT 
ANY
-  ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
-  ~ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-  ~
-  ~ You should have received a copy of the GNU General Public License along 
with
-  ~ GNU Taler; see the file COPYING.  If not, see 
<http://www.gnu.org/licenses/>
-  -->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android";
-    xmlns:app="http://schemas.android.com/apk/res-auto";
-    xmlns:tools="http://schemas.android.com/tools";
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:fillViewport="true"
-    tools:context=".transactions.TransactionDetailFragment">
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-        <TextView
-            android:id="@+id/timeView"
-            style="@style/TransactionLabel.Time"
-            app:layout_constraintBottom_toTopOf="@+id/effectiveAmountLabel"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            tools:text="23 March 2020 23:42pm" />
-
-        <TextView
-            android:id="@+id/effectiveAmountLabel"
-            style="@style/TransactionLabel"
-            app:layout_constraintBottom_toTopOf="@+id/effectiveAmountView"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/timeView"
-            tools:text="@string/withdraw_total" />
-
-        <TextView
-            android:id="@+id/effectiveAmountView"
-            style="@style/TransactionContent"
-            android:textColor="@color/green"
-            app:layout_constraintBottom_toTopOf="@+id/confirmWithdrawalButton"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/effectiveAmountLabel"
-            tools:text="23.42 TESTKUDOS" />
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/confirmWithdrawalButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:icon="@drawable/ic_account_balance"
-            android:text="@string/withdraw_button_confirm_bank"
-            android:textColor="?colorOnPrimary"
-            app:iconTint="?colorOnPrimary"
-            app:drawableTint="?attr/colorOnPrimarySurface"
-            app:layout_constraintBottom_toTopOf="@+id/actionButton"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/effectiveAmountView"
-            tools:ignore="RtlHardcoded" />
-
-        <Button
-            android:id="@+id/actionButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginVertical="10dp"
-            android:textColor="?colorOnTertiary"
-            android:backgroundTint="?colorTertiary"
-            android:visibility="gone"
-            app:layout_constraintBottom_toTopOf="@id/chosenAmountLabel"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/confirmWithdrawalButton"
-            tools:text="@string/transaction_action_kyc"
-            tools:visibility="visible" />
-
-        <TextView
-            android:id="@+id/chosenAmountLabel"
-            style="@style/TransactionLabel"
-            app:layout_constraintBottom_toTopOf="@+id/chosenAmountView"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/actionButton"
-            tools:text="@string/amount_chosen" />
-
-        <TextView
-            android:id="@+id/chosenAmountView"
-            style="@style/TransactionContent"
-            app:layout_constraintBottom_toTopOf="@+id/feeLabel"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/chosenAmountLabel"
-            tools:text="24 TESTKUDOS" />
-
-        <TextView
-            android:id="@+id/feeLabel"
-            style="@style/TransactionLabel"
-            android:text="@string/withdraw_fees"
-            app:layout_constraintBottom_toTopOf="@+id/feeView"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/chosenAmountView" />
-
-        <TextView
-            android:id="@+id/feeView"
-            style="@style/TransactionContent"
-            android:textColor="?colorError"
-            app:layout_constraintBottom_toTopOf="@+id/exchangeLabel"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/feeLabel"
-            tools:text="-0.38 TESTKUDOS" />
-
-        <TextView
-            android:id="@+id/exchangeLabel"
-            style="@style/TransactionLabel"
-            android:text="@string/withdraw_exchange"
-            app:layout_constraintBottom_toTopOf="@+id/exchangeView"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/feeView" />
-
-        <TextView
-            android:id="@+id/exchangeView"
-            style="@style/TransactionContent"
-            app:layout_constraintBottom_toTopOf="@+id/deleteButton"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/exchangeLabel"
-            tools:text="exchange.demo.taler.net" />
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/deleteButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginVertical="10dp"
-            android:text="@string/transactions_delete"
-            app:backgroundTint="?colorError"
-            app:icon="@drawable/ic_delete"
-            android:textColor="?colorOnError"
-            app:iconTint="?colorOnError"
-            app:layout_constraintBottom_toTopOf="@id/showErrorButton"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/exchangeView" />
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/showErrorButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginVertical="10dp"
-            android:visibility="gone"
-            android:text="@string/nav_error"
-            app:backgroundTint="?colorError"
-            app:icon="@drawable/ic_error"
-            android:textColor="?colorOnError"
-            app:iconTint="?colorOnError"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/deleteButton"
-            tools:visibility="visible" />
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</ScrollView>
diff --git a/wallet/src/main/res/navigation/nav_graph.xml 
b/wallet/src/main/res/navigation/nav_graph.xml
index 6508539..966afac 100644
--- a/wallet/src/main/res/navigation/nav_graph.xml
+++ b/wallet/src/main/res/navigation/nav_graph.xml
@@ -227,8 +227,7 @@
     <fragment
         android:id="@+id/nav_transactions_detail_withdrawal"
         
android:name="net.taler.wallet.transactions.TransactionWithdrawalFragment"
-        android:label="@string/transactions_detail_title"
-        tools:layout="@layout/fragment_transaction_withdrawal">
+        android:label="@string/transactions_detail_title">
         <action
             
android:id="@+id/action_nav_transactions_detail_withdrawal_to_nav_exchange_manual_withdrawal_success"
             app:destination="@id/nav_exchange_manual_withdrawal_success" />
@@ -237,38 +236,32 @@
     <fragment
         android:id="@+id/nav_transactions_detail_payment"
         android:name="net.taler.wallet.transactions.TransactionPaymentFragment"
-        android:label="@string/transactions_detail_title"
-        tools:layout="@layout/fragment_transaction_payment" />
+        android:label="@string/transactions_detail_title" />
 
     <fragment
         android:id="@+id/nav_transactions_detail_refund"
         android:name="net.taler.wallet.transactions.TransactionRefundFragment"
-        android:label="@string/transactions_detail_title"
-        tools:layout="@layout/fragment_transaction_payment" />
+        android:label="@string/transactions_detail_title" />
 
     <fragment
         android:id="@+id/nav_transactions_detail_refresh"
         android:name="net.taler.wallet.transactions.TransactionRefreshFragment"
-        android:label="@string/transactions_detail_title"
-        tools:layout="@layout/fragment_transaction_withdrawal" />
+        android:label="@string/transactions_detail_title" />
 
     <fragment
         android:id="@+id/nav_transactions_detail_deposit"
         android:name="net.taler.wallet.transactions.TransactionDepositFragment"
-        android:label="@string/transactions_detail_title"
-        tools:layout="@layout/fragment_transaction_withdrawal" />
+        android:label="@string/transactions_detail_title" />
 
     <fragment
         android:id="@+id/nav_transactions_detail_tip"
         android:name="net.taler.wallet.transactions.TransactionTipFragment"
-        android:label="@string/transactions_detail_title"
-        tools:layout="@layout/fragment_transaction_withdrawal" />
+        android:label="@string/transactions_detail_title" />
 
     <fragment
         android:id="@+id/nav_transactions_detail_peer"
         android:name="net.taler.wallet.transactions.TransactionPeerFragment"
-        android:label="@string/transactions_detail_title"
-        tools:layout="@layout/fragment_transaction_payment" />
+        android:label="@string/transactions_detail_title" />
 
     <fragment
         android:id="@+id/alreadyAccepted"

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]