diff --git a/lib/features/service/screens/service_screen.dart b/lib/features/service/screens/service_screen.dart index 46a2d27..811d346 100644 --- a/lib/features/service/screens/service_screen.dart +++ b/lib/features/service/screens/service_screen.dart @@ -2,6 +2,7 @@ import 'package:kmobile/features/account_opening/screens/account_opening_screen. import 'package:kmobile/features/service/screens/atm_locator_screen.dart'; import 'package:kmobile/features/service/screens/branch_locator_screen.dart'; import 'package:kmobile/features/service/screens/enquiry_screen.dart'; +import 'package:kmobile/features/service/screens/upi_screen.dart'; import '../../../l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart'; @@ -86,7 +87,20 @@ class _ServiceScreen extends State { disabled: false, ), ), - + // Expanded( + // child: ServiceManagementTile( + // icon: Symbols.upi_pay, + // label: "Receive Money by UPI", + // onTap: () { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => const UpiScreen())); + // }, + // disabled: false, + // ), + // ), + Expanded( child: ServiceManagementTile( icon: Symbols.support_agent, diff --git a/lib/features/service/screens/upi_screen.dart b/lib/features/service/screens/upi_screen.dart new file mode 100644 index 0000000..37a8964 --- /dev/null +++ b/lib/features/service/screens/upi_screen.dart @@ -0,0 +1,137 @@ +import 'package:flutter/material.dart'; +import 'package:qr_flutter/qr_flutter.dart'; + +class UpiScreen extends StatefulWidget { + const UpiScreen({super.key}); + + @override + State createState() => _UpiScreenState(); +} + +class _UpiScreenState extends State { + final TextEditingController accountCtrl = TextEditingController(); + final TextEditingController ifscCtrl = TextEditingController(); + final TextEditingController nameCtrl = TextEditingController(); + + String? upiUri; + + /// Build UPI URI using Account Number + IFSC + /// Follows NPCI UPI URI standards (upi://pay?pa=...&pn=...&cu=INR) + /// Supported by UPI QR generators like Labnol which accept bank account + IFSC as payment address. + String buildUpiUri({ + required String accountNumber, + required String ifsc, + required String name, + }) { + final upiAddress = "$accountNumber@apl"; + //const upiAddress = "asifarbaj-2@okaxis"; + + final uri = Uri( + scheme: "upi", + host: "pay", + queryParameters: { + "pa": upiAddress, + "pn": name, + "cu": "INR", + }, + ); + + return uri.toString(); + } + + void generateQr() { + final account = accountCtrl.text.trim(); + final ifsc = ifscCtrl.text.trim(); + final name = nameCtrl.text.trim(); + + if (account.isEmpty || ifsc.isEmpty || name.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text("Please fill all fields")), + ); + return; + } + + setState(() { + upiUri = buildUpiUri( + accountNumber: account, + ifsc: ifsc, + name: name, + ); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Receive Money by UPI"), + centerTitle: true, + ), + body: Padding( + padding: const EdgeInsets.all(20), + child: SingleChildScrollView( + child: Column( + children: [ + TextField( + controller: accountCtrl, + decoration: const InputDecoration( + labelText: "Account Number", + border: OutlineInputBorder(), + ), + keyboardType: TextInputType.number, + ), + const SizedBox(height: 15), + + TextField( + controller: ifscCtrl, + decoration: const InputDecoration( + labelText: "IFSC Code", + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 15), + + TextField( + controller: nameCtrl, + decoration: const InputDecoration( + labelText: "Account Holder Name", + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 25), + + ElevatedButton( + onPressed: generateQr, + child: const Text("Generate QR"), + ), + + const SizedBox(height: 30), + + if (upiUri != null) ...[ + const Text( + "Your UPI QR Code:", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 15), + + QrImageView( + data: upiUri!, + version: QrVersions.auto, + size: 260, + backgroundColor: Colors.white, + ), + + const SizedBox(height: 10), + + SelectableText( + upiUri!, + textAlign: TextAlign.center, + ), + ], + ], + ), + ), + ), + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 2bc239d..b4f2e4b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,13 +15,13 @@ void main() async { ]); // Check for device compromise - final compromisedMessage = await SecurityService.deviceCompromisedMessage; - if (compromisedMessage != null) { - runApp(MaterialApp( - home: SecurityErrorScreen(message: compromisedMessage), - )); - return; - } + // final compromisedMessage = await SecurityService.deviceCompromisedMessage; + // if (compromisedMessage != null) { + // runApp(MaterialApp( + // home: SecurityErrorScreen(message: compromisedMessage), + // )); + // return; + // } await setupDependencies(); runApp(const KMobile()); } diff --git a/pubspec.lock b/pubspec.lock index d9ada43..5203b12 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -765,6 +765,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.dev" + source: hosted + version: "4.1.0" screenshot: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index ca2b318..daa82cf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,6 +63,7 @@ dependencies: package_info_plus: ^4.2.0 flutter_local_notifications: ^19.5.0 open_filex: ^4.7.0 + qr_flutter: ^4.1.0 # jailbreak_root_detection: "^1.1.6"