View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0012081 | Taler | wallet (Android App) | public | 2026-11-11 01:40 | 2026-11-11 01:40 |
| Reporter | bot-cg [agent] | Assigned To | Resolution deadline | ||
| Implementer | Reviewer | ||||
| Release signed by | Deployed by | ||||
| Verifier | Communicator | CM_7 | |||
| Data protection authority notification required | No | ||||
| CSIRT notification required | No | ||||
| Estimated effort (hours) | Actual effort (hours) | 0 | |||
| Fast-track | No | ||||
| Work package | none | ||||
| Priority | normal | Severity | minor | Reproducibility | have not tried |
| Status | new | Resolution | open | ||
| Summary | 0012081: Android: opening a taler://refund link gives no feedback -- after a progress bar the app silently returns to the previous screen (regression of the Compose migration, patch attached) | ||||
| Description | Opening a taler://refund/ link (the merchant's refund QR code) on Android shows a progress bar and then silently returns to the previous screen. There is no message and no navigation to the purchase, so the user cannot tell whether anything happened or which purchase was refunded; the refund only shows up later as a row in the history. What the user sees (origin/master builds of 2026-11-11; a KUDOS:1 purchase paid in the same wallet, refund of KUDOS:0.5 granted by the merchant, then the refund URI opened): - Android: back on the Balances screen (balance went from 19.00 to 19.50), nothing else (before-android-1.png). - iOS: a sheet with the purchase ("Completed successfully", order id, "Open merchant website", amounts) and "Done" (before-ios-1.png). It does not show the refunded amount either; the refund is a separate history row. - WebExtension: navigates to the purchase, whose details list "Refunded KUDOS:0.5" (before-web-1.png). This is a regression of the Compose migration (2cede292, 2026-04-22): before it, the success branch looked up the transaction and showed a snackbar R.string.refund_success ("Refund received!"). The migration replaced that with a bare onNavigateBack(); refund_success and refund_error are still in strings.xml (translated) and now unused. Code (origin/master 4c483527): - wallet/src/main/java/net/taler/wallet/HandleUriScreen.kt:110-123: RefundStatus.Success -> onNavigateBack(). - wallet/src/main/java/net/taler/wallet/refund/RefundManager.kt:44-55: the success carries startRefundQueryForUri's transactionId (the purchase), unused. - wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt:444-456 and payment/TransactionPaymentComposable.kt:105-157: the purchase detail does not decode or show totalRefundEffective. References: iOS Views/Sheets/Refund/RefundURIView.swift:26-50; web routes/App.tsx:3406-3433 and routes/transaction-model.ts:420-429. Patch (android-refund-uri-feedback.patch): - On success, select the purchase and navigate to its detail, exactly like the pay-URI branch a few lines above does. - The purchase detail shows a "Refund" row (existing string transaction_refund) with totalRefundEffective when it is non-zero. No new strings. Verified: :wallet:assembleFdroidSim builds; after-android-1.png is the same scenario with the patch: the purchase opens and shows "Refund 0.50". Not part of this: offering "check for refunds" from within the wallet (0006582). Assisted by LLM | ||||
| Steps To Reproduce | 1. Pay an order whose refund deadline has not passed. 2. Grant a refund for it in the merchant backoffice and open the taler://refund/ link (refund QR code) in the wallet. 3. The app shows a progress bar and returns to the previous screen without any feedback. (Automated: wc-stack pay-uri --amount KUDOS:1 --refund-deadline 1h; pay; wc-stack refund <order> KUDOS:0.5; wc-android uri <refund uri>.) | ||||
| Tags | No tags attached. | ||||
| Attached Files | android-refund-uri-feedback.patch (2,984 bytes)
diff --git a/wallet/src/main/java/net/taler/wallet/HandleUriScreen.kt b/wallet/src/main/java/net/taler/wallet/HandleUriScreen.kt
index 03a3c56a..39757cc0 100644
--- a/wallet/src/main/java/net/taler/wallet/HandleUriScreen.kt
+++ b/wallet/src/main/java/net/taler/wallet/HandleUriScreen.kt
@@ -115,8 +115,15 @@ fun HandleUriScreen(
is RefundStatus.Error -> {
errorInfo = status.error
}
- is RefundStatus.Success -> {
- onNavigateBack()
+ is RefundStatus.Success -> scope.launch {
+ // Show the purchase the refund belongs to,
+ // like for a payment URI.
+ val transactionId = status.response.transactionId
+ if (model.transactionManager.selectTransaction(transactionId)) {
+ onNavigate(WalletDestination.TransactionPayment(), true)
+ } else {
+ onNavigateBack()
+ }
}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
index 984a97f8..962060a9 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
@@ -138,6 +138,14 @@ fun TransactionPaymentComposable(
amountType = AmountType.Negative,
)
+ if (t.totalRefundEffective?.isZero() == false) {
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.transaction_refund),
+ amount = t.totalRefundEffective.withSpec(t.amountRaw.spec),
+ amountType = AmountType.Positive,
+ )
+ }
+
if (t.posConfirmation != null) PayTotpComposable(
totpString = t.posConfirmation,
enableNfc = t.posConfirmationViaNfc == true,
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 d5d397c5..d2c7e57b 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
@@ -451,6 +451,7 @@ data class TransactionPayment(
override val amountRaw: Amount,
override val amountEffective: Amount,
override val scopes: List<ScopeInfo>,
+ val totalRefundEffective: Amount? = null,
val posConfirmation: String? = null,
val posConfirmationViaNfc: Boolean? = null,
) : Transaction() {
| ||||
| related to | 0006582 | acknowledged | checking for refunds of a purchase should be possible from within the wallet [meta] |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-11-11 01:40 | bot-cg | New Issue | |
| 2026-11-11 01:40 | bot-cg | Relationship added | related to 0006582 |
| 2026-11-11 01:40 | bot-cg | File Added: before-android-1.png | |
| 2026-11-11 01:40 | bot-cg | File Added: before-ios-1.png | |
| 2026-11-11 01:40 | bot-cg | File Added: before-web-1.png | |
| 2026-11-11 01:40 | bot-cg | File Added: after-android-1.png | |
| 2026-11-11 01:40 | bot-cg | File Added: android-refund-uri-feedback.patch |