diff --git a/lib/g1/g1_helper.dart b/lib/g1/g1_helper.dart
index 0d5be13127c7063b1bdfca97c86badda1b34e401..6534ccf083fb431042da735874aa816ac31ef252 100644
--- a/lib/g1/g1_helper.dart
+++ b/lib/g1/g1_helper.dart
@@ -170,7 +170,8 @@ String getQrUri(
   return uri;
 }
 
-PaymentState? parseScannedUri(String qr) {
+PaymentState? parseScannedUri(String qrOrig) {
+  final String qr = Uri.decodeFull(qrOrig);
   final RegExp regexKeyCommentAmount = RegExp(
       r'(duniter\:key|june\:\/)/(\w+(:\w{3})?)\?(comment=([^&]+))&amount=([\d.,]+)');
   final RegExp regexKeyAmountComment = RegExp(
@@ -198,7 +199,7 @@ PaymentState? parseScannedUri(String qr) {
     return PaymentState(
         contact: Contact(pubKey: publicKey),
         amount: amount,
-        comment: comment ?? '');
+        comment: cleanComment(comment));
   }
 
   if (matchKeyAmountComment != null) {
@@ -210,14 +211,14 @@ PaymentState? parseScannedUri(String qr) {
     return PaymentState(
         contact: Contact(pubKey: publicKey),
         amount: amount,
-        comment: comment ?? '');
+        comment: cleanComment(comment));
   }
 
   if (matchKeyComment != null) {
     final String publicKey = matchKeyComment.group(2)!;
     final String? comment = matchKeyComment.group(4);
     return PaymentState(
-        contact: Contact(pubKey: publicKey), comment: comment ?? '');
+        contact: Contact(pubKey: publicKey), comment: cleanComment(comment));
   }
 
   final RegExpMatch? matchKeyAmount = regexKeyAmount.firstMatch(qr);
diff --git a/lib/ui/ui_helpers.dart b/lib/ui/ui_helpers.dart
index 07ef7c230c4e443121d4ee2655349a68e28b9164..ae563ba318682a8ca6b63eec9b7269d5832b9f88 100644
--- a/lib/ui/ui_helpers.dart
+++ b/lib/ui/ui_helpers.dart
@@ -86,9 +86,9 @@ String humanizeFromToPubKey(String publicAddress, String address) {
 }
 
 String humanizeContact(String publicAddress, Contact contact,
-    [bool addKey = false]) {
+    [bool addKey = false, String Function(String s) trf = tr]) {
   if (contact.pubKey == publicAddress) {
-    return tr('your_wallet');
+    return trf('your_wallet');
   } else {
     final String pubKey = humanizePubKey(contact.pubKey);
     final bool titleNotTheSameAsPubKey = contact.title != pubKey;
@@ -232,6 +232,15 @@ Future<Uint8List?> resizeAvatar(Uint8List avatarBase64) async {
 
 final RegExp basicEnglishCharsRegExp =
     RegExp(r'^[ A-Za-z0-9\s.;:!?()\-_;!@&<>%]*$');
+final RegExp basicEnglishCharsRegExpNegative =
+    RegExp(r'[^ A-Za-z0-9\s.;:!?()\-_;!@&<>%]');
+
+String cleanComment(String? comment) {
+  return comment == null
+      ? ''
+      : comment.replaceAllMapped(
+          basicEnglishCharsRegExpNegative, (Match match) => ' ');
+}
 
 void fetchTransactions(BuildContext context) {
   final AppCubit appCubit = context.read<AppCubit>();
@@ -425,7 +434,10 @@ bool isSymbolPlacementBefore(String pattern) {
 String currentLocale(BuildContext context) => context.locale.languageCode;
 
 String? validateDecimal(
-    {required String sep, required String locale, required String? amount}) {
+    {required String sep,
+    required String locale,
+    required String? amount,
+    required String Function(String s) tr}) {
   final NumberFormat format = NumberFormat.decimalPattern(locale);
   if (amount == null || amount.isEmpty || amount.startsWith(sep)) {
     return null;
@@ -436,6 +448,10 @@ String? validateDecimal(
       return tr('enter_a_positive_number');
     }
     final String formattedAmount = format.format(n);
+    if (amount.contains(sep) && amount.endsWith('0')) {
+      // remove trailing zeros in 0.10 == 0.1
+      amount = amount.replaceAll(RegExp(r'0*$'), '');
+    }
     if (formattedAmount != amount) {
       return tr('enter_a_valid_number');
     }
diff --git a/test/g1_test.dart b/test/g1_test.dart
index b9f25395c97949603a5552089899a6b57975ce33..9a911f3c0b2da582dc72ff20acdc33f04b3d180c 100644
--- a/test/g1_test.dart
+++ b/test/g1_test.dart
@@ -54,91 +54,118 @@ void main() {
         equals(true));
   });
 
-  test('validate qr uris', () {
-    const String baseKey = 'FRYyk57Pi456EJRu9vqVfSHLgmUfx4Qc3goS62a7dUSm';
-    final String publicKeyWithChecksum = getFullPubKey(baseKey);
-
-    final List<String> keys = <String>[baseKey, publicKeyWithChecksum];
-
-    for (final String publicKey in keys) {
-      final String uriA = getQrUri(pubKey: publicKey, amount: '10');
-      final PaymentState? payA = parseScannedUri(uriA);
-      expect(payA!.amount, equals(10), reason: 'amount should be 10 in $uriA');
-      expect(payA.contact!.pubKey, equals(publicKey));
-
-      final String uriB = getQrUri(pubKey: publicKey);
-      final PaymentState? payB = parseScannedUri(uriB);
-      expect(payB!.amount, equals(null));
-      expect(payB.contact!.pubKey, equals(publicKey));
-
-      final PaymentState? payC = parseScannedUri(publicKey);
-      expect(payC!.amount, equals(null));
-      expect(payC.contact!.pubKey, equals(publicKey));
-
-      final String uriD = getQrUri(pubKey: publicKey, amount: '10.10');
-      final PaymentState? payD = parseScannedUri(uriD);
-      expect(payD!.amount, equals(10.10));
-      expect(payD.contact!.pubKey, equals(publicKey));
-
-      final String uriE =
-          getQrUri(pubKey: publicKey, amount: '10,10', locale: 'es');
-      final PaymentState? payE = parseScannedUri(uriE);
-      expect(payE!.amount, equals(10.10));
-      expect(payE.contact!.pubKey, equals(publicKey));
-
-      final String uriF = 'june://$publicKey?amount=100';
-      final PaymentState? payF = parseScannedUri(uriF);
-      expect(payF!.amount, equals(100));
-      expect(payF.contact!.pubKey, equals(publicKey));
-
-      final String uriJ =
-          'june://$publicKey?comment=GCHANGE:AYDI9JPOVIL9ZVG-PNCU&amount=100';
-      final PaymentState? payJ = parseScannedUri(uriJ);
-      expect(payJ!.comment, equals('GCHANGE:AYDI9JPOVIL9ZVG-PNCU'));
-      expect(payJ.amount, equals(100));
-      expect(payJ.contact!.pubKey, equals(publicKey));
-
-      const String uriK =
-          'june://DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech?amount=10&comment=This Is my comment';
-      final PaymentState? payK = parseScannedUri(uriK);
-      expect(payK!.comment, equals('This Is my comment'));
-      expect(payK.amount, equals(10));
-      expect(payK.contact!.pubKey,
-          equals('DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech'));
-
-      const String uriL =
-          'june://DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech?comment=This Is my comment&amount=10';
-      final PaymentState? payL = parseScannedUri(uriL);
-      expect(payL!.comment, equals('This Is my comment'));
-      expect(payL.amount, equals(10));
-      expect(payL.contact!.pubKey,
-          equals('DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech'));
-
-      const String uriM =
-          'june://DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech?comment=Mi comentario&amount=10,0';
-      final PaymentState? payM = parseScannedUri(uriM);
-      expect(payM!.comment, equals('Mi comentario'));
-      expect(payM.amount, equals(10));
-      expect(payM.contact!.pubKey,
-          equals('DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech'));
-
-      const String uriN =
-          'june://DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech?comment=This Is my comment';
-      final PaymentState? payN = parseScannedUri(uriN);
-      expect(payN!.amount == null, equals(true));
-      expect(payN.comment, equals('This Is my comment'));
-      expect(payN.contact!.pubKey,
-          equals('DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech'));
-
-      const String uriO =
-          'june://DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech:XXX?comment=This Is my comment';
-      final PaymentState? payO = parseScannedUri(uriO);
-      expect(payO!.amount == null, equals(true));
-      expect(payO.comment, equals('This Is my comment'));
-      expect(payO.contact!.pubKey,
-          equals('DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech:XXX'));
-    }
-  });
+  const String baseKey = 'FRYyk57Pi456EJRu9vqVfSHLgmUfx4Qc3goS62a7dUSm';
+  final String publicKeyWithChecksum = getFullPubKey(baseKey);
+  final List<String> keys = <String>[baseKey, publicKeyWithChecksum];
+
+  for (final String publicKey in keys) {
+    group('Tests for publicKey: $publicKey', () {
+      test('validate qr uri with amount', () {
+        final String uriA = getQrUri(pubKey: publicKey, amount: '10');
+        final PaymentState? payA = parseScannedUri(uriA);
+        expect(payA!.amount, equals(10),
+            reason: 'amount should be 10 in $uriA');
+        expect(payA.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate qr uri without amount', () {
+        final String uriB = getQrUri(pubKey: publicKey);
+        final PaymentState? payB = parseScannedUri(uriB);
+        expect(payB!.amount, equals(null));
+        expect(payB.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate qr scanned', () {
+        final PaymentState? payC = parseScannedUri(publicKey);
+        expect(payC!.amount, equals(null));
+        expect(payC.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate qr uri with decimal amount', () {
+        final String uriD = getQrUri(pubKey: publicKey, amount: '10.10');
+        final PaymentState? payD = parseScannedUri(uriD);
+        expect(payD!.amount, equals(10.10));
+        expect(payD.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate qr uri with localized decimal amount', () {
+        final String uriE =
+            getQrUri(pubKey: publicKey, amount: '10,10', locale: 'es');
+        final PaymentState? payE = parseScannedUri(uriE);
+        expect(payE!.amount, equals(10.10));
+        expect(payE.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate custom june uri with amount', () {
+        final String uriF = 'june://$publicKey?amount=100';
+        final PaymentState? payF = parseScannedUri(uriF);
+        expect(payF!.amount, equals(100));
+        expect(payF.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate june uri with comment and amount', () {
+        final String uriJ =
+            'june://$publicKey?comment=GCHANGE:AYDI9JPOVIL9ZVG-PNCU&amount=100';
+        final PaymentState? payJ = parseScannedUri(uriJ);
+        expect(payJ!.comment, equals('GCHANGE:AYDI9JPOVIL9ZVG-PNCU'));
+        expect(payJ.amount, equals(100));
+        expect(payJ.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate june uri with amount and comment', () {
+        final String uriK =
+            'june://$publicKey?amount=10&comment=This Is my comment';
+        final PaymentState? payK = parseScannedUri(uriK);
+        expect(payK!.comment, equals('This Is my comment'));
+        expect(payK.amount, equals(10));
+        expect(payK.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate june uri with reordered comment and amount', () {
+        final String uriL =
+            'june://$publicKey?comment=This Is my comment&amount=10';
+        final PaymentState? payL = parseScannedUri(uriL);
+        expect(payL!.comment, equals('This Is my comment'));
+        expect(payL.amount, equals(10));
+        expect(payL.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate june uri with localized amount and comment', () {
+        final String uriM =
+            'june://$publicKey?comment=Mi comentario&amount=10,0';
+        final PaymentState? payM = parseScannedUri(uriM);
+        expect(payM!.comment, equals('Mi comentario'));
+        expect(payM.amount, equals(10));
+        expect(payM.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate june uri with comment only', () {
+        final String uriN = 'june://$publicKey?comment=This Is my comment';
+        final PaymentState? payN = parseScannedUri(uriN);
+        expect(payN!.amount == null, equals(true));
+        expect(payN.comment, equals('This Is my comment'));
+        expect(payN.contact!.pubKey, equals(publicKey));
+      });
+
+      test('validate june uri with encoded uri', () {
+        final String uriN =
+            Uri.encodeFull('june://$publicKey?comment=This Is my comment');
+        final PaymentState? payN = parseScannedUri(uriN);
+        expect(payN!.amount == null, equals(true));
+        expect(payN.comment, equals('This Is my comment'));
+        expect(payN.contact!.pubKey, equals(publicKey));
+      });
+
+      test('Replace incorrect comment characters', () {
+        final String uriN = Uri.encodeFull(
+            'june://$publicKey?comment=This Is my comment,!%áéíóú');
+        final PaymentState? payN = parseScannedUri(uriN);
+        expect(payN!.amount == null, equals(true));
+        expect(payN.comment, equals('This Is my comment !%     '));
+        expect(payN.contact!.pubKey, equals(publicKey));
+      });
+    });
+  }
 
   test('encrypt/decrypt of keys', () {
     const String pass = '1234';