fints 0.1.2
fints: ^0.1.2 copied to clipboard
FinTS 3.0 and 4.1 client for German banks. Retrieves accounts, balances and transactions with PIN/TAN, two-step TAN, decoupled approval and PSD2 strong customer authentication.
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'bank_directory.dart';
import 'login_page.dart';
import 'tan_ui.dart';
void main() => runApp(const FinTsExampleApp());
class FinTsExampleApp extends StatelessWidget {
const FinTsExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
scaffoldMessengerKey: messengerKey,
title: 'FinTS Beispiel',
locale: const Locale('de'),
supportedLocales: const [Locale('de')],
localizationsDelegates: GlobalMaterialLocalizations.delegates,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
darkTheme: ThemeData(colorSchemeSeed: Colors.indigo, brightness: Brightness.dark),
home: const BankListPage(),
);
}
}
class BankListPage extends StatefulWidget {
const BankListPage({super.key});
@override
State<BankListPage> createState() => _BankListPageState();
}
class _BankListPageState extends State<BankListPage> {
final _banks = loadBankDirectory();
String _query = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bank auswählen'),
actions: [
IconButton(
icon: const Icon(Icons.info_outline),
tooltip: 'Lizenzen',
onPressed: () => showLicensePage(context: context, applicationName: 'FinTS Beispiel'),
),
],
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(12),
child: TextField(
decoration: const InputDecoration(
prefixIcon: Icon(Icons.search),
hintText: 'Name, Ort, BLZ oder BIC',
border: OutlineInputBorder(),
),
onChanged: (value) => setState(() => _query = value.trim()),
),
),
Expanded(
child: FutureBuilder<List<Bank>>(
future: _banks,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Text(
'Die Bankliste konnte nicht geladen werden. Legen Sie die FinTS-Institutsliste als '
'assets/fints_institute.csv ab.\n\n${snapshot.error}',
textAlign: TextAlign.center,
),
),
);
}
final banks = snapshot.data;
if (banks == null) return const Center(child: CircularProgressIndicator());
final filtered = _query.isEmpty ? banks : banks.where((b) => b.matches(_query)).toList();
return ListView.builder(
itemCount: filtered.length,
itemBuilder: (context, i) {
final bank = filtered[i];
return ListTile(
title: Text(bank.name),
subtitle: Text([bank.bankCode, bank.bic, bank.city].where((s) => s.isNotEmpty).join(' · ')),
onTap: () =>
Navigator.push(context, MaterialPageRoute<void>(builder: (_) => LoginPage(bank: bank))),
);
},
);
},
),
),
],
),
);
}
}