View Issue Details

IDProjectCategoryView StatusLast Update
0012123Talerwallet (iOS App)public2026-11-12 00:24
Reporterbot-cg [agent] Assigned ToResolution deadline
ImplementerReviewer 
Release signed byDeployed by 
VerifierCommunicatorCM_7  
Data protection authority notification requiredNo  
CSIRT notification requiredNo  
Estimated effort (hours)Actual effort (hours)0 
Fast-trackNo
Work packagenone
PrioritynormalSeverityminorReproducibilityhave not tried
Status newResolutionopen 
Summary0012123: Merchant texts with translations are shown in the user's 2nd/3rd language instead of the merchant's default: English UI shows German choice descriptions (patch attached)
DescriptionSeen on the "Confirm Payment" sheet of a v1 contract with three choices, on an
iPhone whose language list (Settings -> General -> Language & Region) is
English, German, French, Italian. The app is displayed in English.

The order's choices were created as

    description: "plain" description_i18n: { de: "einfach", fr: "simple" }
    description: "with a discount pass" description_i18n: { de: "mit Rabattpass", fr: "avec pass de réduction" }
    description: "deluxe, two passes" (no description_i18n)

What the sheet shows (screenshot attached): the first two options are titled
"einfach" and "mit Rabattpass", the third "deluxe, two passes", between the
English headings "Payment Options", "Get with your purchase:" and "Spend now:".
An English screen with two German option names.

Cause: TalerWallet1/Model/Model+Payment.swift:14, I18nDict.localized, walks
Locale.preferredLanguageCodes and returns the first entry it finds. A merchant
does not list its default language in *_i18n -- the untagged field is that
text -- so for a user whose first language is the merchant's default there is
never a hit for it, and the loop goes on to the second or third language of the
phone. The same helper serves the order summary (summary_i18n), product
descriptions and token family descriptions, so those are affected the same way;
I have only observed it on choice descriptions.

Anybody with a second language configured on the phone gets this at any shop
that offers a translation into that second language.

Suggested fix (not compiled): stop at the language the app itself is displayed
in. If there is no entry for it, fall back to the untagged text instead of a
lower-ranked language. A user whose first language the app is not translated
into still gets the best lower-ranked match, as before.

diff --git a/TalerWallet1/Model/Model+Payment.swift b/TalerWallet1/Model/Model+Payment.swift
index f9720921..b2b071d3 100644
--- a/TalerWallet1/Model/Model+Payment.swift
+++ b/TalerWallet1/Model/Model+Payment.swift
@@ -14,10 +14,19 @@ typealias I18nDict = [String: String] // two-char language code, e.g.
 extension I18nDict {
     var localized: String? {
         if !self.isEmpty {
+ // the language the app itself is displayed in
+ let uiCode = Bundle.main.preferredLocalizations.first.flatMap {
+ Locale(identifier: $0).languageCode
+ }
             for code in Locale.preferredLanguageCodes {
                 if let i18n = self[code] {
                     return i18n
                 }
+ if code == uiCode {
+ // No entry for the language of the UI: the untagged text is the
+ // merchant's default. Do not go on to a lower-ranked language.
+ break
+ }
             }
         }
         return nil

Found by the UI fuzzing harness (scenario tokens-earn-and-delete, 2026-11-12);
wallet build from taler-ios master as of early November 2026, iOS 27 simulator.
TagsNo tags attached.
Attached Files

Required notifications

Address or linkRemarkAdded byNotifiedActions

Activities

Issue History

Date ModifiedUsernameFieldChange
2026-11-12 00:24bot-cgNew Issue
2026-11-12 00:24bot-cgFile Added: confirm-payment-german-options.png