Cross-platform Flutter app. Production API is Django REST; Supabase is optional. Local UI demos use
USE_MOCK_API=trueand need neither backend.
| Platform | Flutter SDK | Dart | API Backend | Realtime | Status |
|---|---|---|---|---|---|
| Android (Linux/macOS/Windows) · iOS (macOS) | stable (CI) | 3.x (>=3.0.0 <4.0.0) |
Django REST, or in-app mock | Optional Supabase | Production prep |
- Project Overview
- Documentation
- Project Structure
- Dependencies
- Configuration & Environment Variables
- Build & Deployment
- Troubleshooting & FAQs
- Changelog
- Contributing
- Code of Conduct
HapoPay is a parent-student money management and smart spending platform. The Flutter app gives parents tools to manage allowances, adjust spending limits, and monitor transactions in real time. Students get a safe payment flow with dynamic QR codes, biometric auth, and a gamified rewards hub (tiers, streaks, claimable achievements).
Backend model: Django owns business logic and the payment gateway. Supabase is optional (Supabase.initialize is skipped when SUPABASE_URL is empty). With USE_MOCK_API=true, Dio serves an in-memory catalog so you can demo without any server.
App stack: Riverpod 3 (state + codegen), GoRouter (navigation), Dio (HTTP + auth/retry/mock interceptors), Material 3 light/dark theming via lib/core/theme/.
Clone: git clone git@github.com:HapoTV/HapoPay_Flutter.git — this is the Flutter app root (there is no mobile/ subfolder). Setup: docs/SETUP.md.
| Doc | Description |
|---|---|
| Setup & Installation | Clone this repo, Flutter, mock vs live API, Android emulator, demo logins |
| Environment Variables | .env.dev / .env.prod, USE_MOCK_API, emulator loopback, keystore |
| Architecture | Clean layers, Riverpod, GoRouter |
| Features & Screens | Auth, parent dashboard, student QR & rewards routes |
| Rewards System | Catalog, tiers, claim UX, API contract, mock flow |
| Project Roadmap | Milestones and build status |
| Production Checklist | Store-submission blockers and completed work |
| Production Runbook | Ordered phases for signing, env, assets, legal, QA |
| Production operations | Latency, traffic, errors, maintenance, workflows, scale, client performance |
lib/
├── main.dart / app.dart
├── core/ # config, network, router, theme, storage, realtime
├── features/
│ ├── auth/ # login, register, JWT session, biometrics
│ ├── parent/ # dashboard, ledger, spending limits
│ ├── student/ # dashboard, rewards catalog / claim
│ └── qrcode/ # pay QR + my QR screens
└── shared/ # shared widgets (buttons, cards, theme toggle)
test/ # unit / widget tests by feature
docs/ # setup, architecture, features, rewards, prod runbook
Primary packages from pubspec.yaml:
| Package | Purpose |
|---|---|
flutter_riverpod / riverpod_annotation |
State management + codegen |
go_router |
Declarative navigation & role redirects |
dio |
HTTP client, auth / mock / retry interceptors |
supabase_flutter |
Realtime subscriptions & client init |
flutter_secure_storage |
Hardware-backed token storage |
shared_preferences |
Lightweight local settings cache |
qr_flutter / mobile_scanner |
QR generation and camera scanning |
local_auth |
Face ID / fingerprint |
google_fonts / intl |
Typography and localization |
Copy the sample and fill in values (files are gitignored — never commit secrets):
cp .env.example .env.dev
cp .env.example .env.prod# .env.example (compile-time KEY=VALUE; no quotes)
SUPABASE_URL=
SUPABASE_ANON_KEY=
API_BASE_URL=http://10.0.2.2:8000/api
USE_MOCK_API=false
SENTRY_DSN=| Variable | Notes |
|---|---|
SUPABASE_URL |
Optional. Empty skips Supabase init |
API_BASE_URL |
http://10.0.2.2:8000/api on the Android emulator when talking to host Django |
USE_MOCK_API |
true for local UI demos without Django; must be false for release |
SENTRY_DSN |
Optional. Empty skips Sentry init |
Every flutter run / flutter build must pass --dart-define-from-file. Full reference: docs/SETUP_ENV.md.
# UI demo (set USE_MOCK_API=true in .env.dev)
flutter run --dart-define-from-file=.env.dev
# Codegen — only after changing @riverpod annotations (*.g.dart is already committed)
dart run build_runner build --delete-conflicting-outputsapplicationId / namespace: com.hapopay.hapoPay. Release builds load android/key.properties when present (otherwise debug keys + Gradle warning).
./tool/generate_android_keystore.sh
flutter build appbundle --release --dart-define-from-file=.env.prod
flutter build apk --release --dart-define-from-file=.env.prodVersion bump: dart run tool/bump_version.dart build|patch|minor|major. Tag v* triggers .github/workflows/release.yml.
Requires Apple Developer enrollment, App ID, distribution cert, provisioning profile, and DEVELOPMENT_TEAM in Xcode. Bundle ID is already com.hapopay.hapoPay.
flutter build ipa --release --dart-define-from-file=.env.prodStore-readiness checklist and phased runbook: PRODUCTION_READINESS.md · docs/PROD_NEXT_STEPS.md. Legal / listing drafts: docs/legal/ · docs/store/.
| Error / Symptom | Likely Cause | Solution |
|---|---|---|
Connection refused on Android emulator |
localhost is the emulator, not the host |
Set API_BASE_URL to http://10.0.2.2:8000/api |
| Realtime subscription fails | Replication not enabled | Enable tables under Supabase Database → Replication |
| Invalid JWT | Django / Supabase signing mismatch | Align SimpleJWT secret with Supabase JWT secret if sharing tokens |
| Keystore / signing failure | Missing or wrong key.properties |
Run ./tool/generate_android_keystore.sh; keep backups offline |
| Camera viewport blank | Main AndroidManifest has no CAMERA yet |
iOS already has NSCameraUsageDescription; Android still needs the permission |
| Unexpected mock responses in release | USE_MOCK_API=true |
Set USE_MOCK_API=false in .env.prod |
- Auth: Django JWT login/register path, secure storage, biometric service, role-based GoRouter redirects
- Parent: dashboard, family ledger, spending limits, card lock; Supabase realtime feed wiring
- Student: dashboard, QR pay / my QR screens, rewards hub (tiers, streak panel, optimistic claim)
- Rewards catalog shared across mock, demo, and UI — see docs/rewards_system.md
- Networking: Dio interceptors (auth, retry, errors); mock API gated by
USE_MOCK_API - Theme: Material 3 light/dark tokens in
lib/core/theme/ - Android / iOS identity:
com.hapopay.hapoPay; release signing viakey.properties - Sentry (optional DSN), release CI (AAB + unsigned iOS), version bump tool
- CI: analyze, tests, debug builds; release workflow on
v*tags
- Interactive parent budget charts
- Push notifications (FCM / APNs)
- Store assets; host Privacy / Terms URLs; paste Play Data safety
- Broader unit / widget / integration coverage
See CONTRIBUTING.md for workflow, linting, tests, PRs, and commit conventions.
This project follows a Code of Conduct. Report unacceptable behavior to the maintainers.
HapoPay Mobile · v1.0.0