Automatically scan your Android SMS inbox, parse every bank debit/credit, UPI transfer, and wallet payment into clean structured data — with income vs expense tracking, 19 spend categories, and a zero-setup web tester.
50+ banks (SBI, HDFC, ICICI, Axis, Kotak…) 100+ UPI handles (@paytm, @ybl, @okaxis…) 14 wallets (PhonePe, Google Pay, Amazon Pay…) Flutter (Android + iOS + Web)
| Feature | Android | iOS | Web |
|---|---|---|---|
| Parse All SMS from inbox | ✅ | ❌ (OS restriction) | ❌ |
| Paste & test individual SMS | ✅ | ✅ | ✅ |
| Store parsed transactions (SQLite) | ✅ | ✅ | ❌ |
| Filter by bank / category / type | ✅ | ✅ | — |
- 50+ banks — SBI, HDFC, ICICI, Axis, Kotak, PNB, BOB, and more
- 100+ UPI handles — @paytm, @ybl, @okaxis, @oksbi, @okicici, @apl, etc.
- 14 wallet providers — Paytm, PhonePe, Google Pay, Amazon Pay, MobiKwik, etc.
- 19 spending categories — food, groceries, fuel, travel, shopping, EMI, salary, and more
- Smart deduplication — SHA-256 hash of raw SMS prevents double-counting
CountryParserinterface →IndiaParser→ParserRegistry- Adding a new country = add one class + register in
ParserRegistry
Flutter ≥ 3.0.0
Dart ≥ 3.0.0
flutter pub getflutter run -d <android-device-id>Grant SMS permission when prompted. Tap Parse All SMS on the Home tab.
flutter run -d <ios-device-id>iOS does not allow reading the SMS inbox. Use the Tester tab to paste and parse individual messages.
flutter run -d chrome
# or build for deployment:
flutter build web --release
# then serve the build/web/ folderlib/
├── main.dart # Entry point; wires Android SMS on Android only
├── app.dart # Root widget; web shows tester, mobile shows full app
├── core/
│ ├── app_state.dart # ChangeNotifier: parse all, load, totals
│ ├── database/
│ │ ├── db_helper.dart # SQLite init + schema
│ │ └── transaction_dao.dart # CRUD, bulk insert, aggregations
│ ├── parser/
│ │ ├── base_parser.dart # CountryParser interface
│ │ ├── parser_registry.dart # Tries parsers in order; first match wins
│ │ └── india/
│ │ ├── india_parser.dart # Full India SMS parsing logic
│ │ ├── models/
│ │ │ ├── enums.dart
│ │ │ └── parsed_transaction.dart
│ │ └── constants/
│ │ ├── banks.dart # 50+ bank keyword map + sender ID map
│ │ ├── upi_handles.dart # 100+ UPI handles
│ │ ├── wallets.dart # 14 wallet providers
│ │ └── categories.dart # Merchant keyword → category rules
│ └── sms/
│ ├── sms_service.dart # Platform-agnostic interface
│ ├── android_sms_impl.dart # Android: flutter_sms_inbox + permissions
│ └── noop_sms_impl.dart # Web/iOS stub
├── features/
│ ├── home/
│ │ └── home_screen.dart # Dashboard + Parse All button
│ ├── transactions/
│ │ ├── transactions_screen.dart # Full list with search + filters
│ │ ├── transaction_detail_sheet.dart
│ │ └── widgets/
│ │ └── transaction_tile.dart
│ └── tester/
│ └── tester_screen.dart # Paste SMS tester (all platforms)
└── shared/
├── theme.dart # Orange/grey Material3 theme
└── widgets/
└── amount_text.dart # ₹ amount with credit/debit colour
- Create
lib/core/parser/<country>/mirroring theindia/structure. - Implement
CountryParser:class UsParser implements CountryParser { @override String get countryCode => 'US'; @override bool canParse(String sms, String? sender) { ... } @override ParsedTransaction? parse(String rawSms, {String? sender}) { ... } }
- Register in
lib/core/parser/parser_registry.dart:final List<CountryParser> _parsers = [IndiaParser(), UsParser()];
That's it. No other files need changing.