FinFlow is a fintech playground that showcases clean architecture, reliable payments, and a clear developer experience.
- App: https://finflow-swart.vercel.app
- Stripe test data: https://docs.stripe.com/testing
- Backend: .NET 9 Web API, Clean Architecture, MediatR, FluentValidation
- Frontend: Next.js 14, Tailwind CSS, shadcn/ui
- Database: PostgreSQL with EF Core
- Payments: Stripe (Checkout + Webhooks)
- Infra: Docker, Docker Compose
- User registration, login, JWT auth, refresh tokens
- Wallet creation & multi-wallet per user
- Deposit, withdrawal, transfer flows
- Stripe Checkout + webhook-driven balance updates
- Transaction history and basic analytics
- Fully dockerized local stack
FinFlow.API→ ASP.NET Core Web API (controllers, endpoints)FinFlow.Application→ Business logic (CQRS, services, handlers)FinFlow.Domain→ Core domain entities & rulesFinFlow.Infrastructure→ EF Core, DbContext, Stripe integrationfinflow-ui→ Next.js 14 frontend dashboard
This is the fastest way to run the full stack locally.
docker compose up --buildServices
- API: http://localhost:5001 (container listens on port 80)
- UI: http://localhost:3000
- pgAdmin: http://localhost:5050
Default credentials & config
- Postgres:
finflowuser/finflowpass(DB:finflowdb, port5432) - pgAdmin:
admin@finflow.com/adminpass - Stripe keys in
docker-compose.ymlare placeholders (sk_test_change_me,whsec_change_me,pk_test_change_me). Replace them to test real webhook/checkout flows.
ℹ️ If you only run the UI in Docker, you do not need
npm installon your host.
Use the same connection values expected by the API:
Host=localhost
Port=5432
Database=finflowdb
Username=finflowuser
Password=finflowpass
If you want Postgres via Docker only:
docker run --name finflow-postgres \
-e POSTGRES_USER=finflowuser \
-e POSTGRES_PASSWORD=finflowpass \
-e POSTGRES_DB=finflowdb \
-p 5432:5432 \
-d postgres:15From repo root:
dotnet restore
dotnet ef database update --project FinFlow.Infrastructure --startup-project FinFlow.API
dotnet run --project FinFlow.APIFrom finflow-ui:
cd finflow-ui
npm install
NEXT_PUBLIC_API_BASE_URL=http://localhost:5001 npm run devMinimum configuration used by the API:
ConnectionStrings__DefaultConnection
Jwt__Key
Jwt__Issuer
Jwt__Audience
FRONTEND_URLS
Stripe__SecretKey
Stripe__WebhookSecret
Stripe__SuccessUrl
Stripe__CancelUrl
Seq__UrlNotes
FRONTEND_URLSis a comma-separated list of allowed origins (CORS).Seq__Urlis optional in development, required in production.Stripe__SuccessUrlandStripe__CancelUrlshould point to UI routes that handle checkout outcomes.
Forward Stripe webhooks to your API:
stripe listen --forward-to http://localhost:5001/api/payments/webhookRun migrations outside API startup (CI/CD or a one-off job).
CI/CD step
dotnet ef database update --project FinFlow.Infrastructure --startup-project FinFlow.APIOne-off Docker job
docker run --rm \
-e ConnectionStrings__DefaultConnection="$CONNECTION_STRING" \
-e Jwt__Key="$JWT_KEY" \
-e Stripe__SecretKey="$STRIPE_SECRET_KEY" \
-e Stripe__WebhookSecret="$STRIPE_WEBHOOK_SECRE
69EC
T" \
-e Seq__Url="$SEQ_URL" \
finflow-api:latest \
dotnet ef database update --project FinFlow.Infrastructure --startup-project FinFlow.API- Swagger UI: http://localhost:5001/swagger
- pgAdmin (Docker): http://localhost:5050