About this software
About Washly
Washly is an ASP.NET Core (.NET 10) backend with SQL Server, serving an admin web panel, a REST API, and a static landing page. Two Flutter 3.47 apps (customer, driver) consume the API. Customers browse services, place orders with time slots, pay by card or Apple Pay via Mastercard Payment Gateway Services, and track orders with proof photos. Drivers see assigned jobs, update status, and upload proof-of-collection and proof-of-delivery images. Staff manage the catalogue, orders, drivers, customers, corporate accounts, and reports.
Why Washly
What makes it better
than the alternatives
- 01
Single-tenant architecture
- 02
Ownership guards on every API endpoint
- 03
Role/page permission matrix
- 04
Hosted payment pages with Apple Pay
- 05
Comprehensive audit trail
Customer App (Flutter)
- Sign in with OTP by SMS or email (no password)
- Service catalogue: wash & fold
- clean & press
- dry cleaning
- home care
- shoes & bags with per-item prices
- Order with collection/delivery time slots
- address book with map pin
- driver instructions
- Promo codes
- coupons with wallet cashback
- wallet balance and top-up
- Card payment and Apple Pay through hosted payment page
- Live order status
- proof-of-collection and proof-of-delivery photos
- invoices (PDF)
- Push notifications (Firebase)
- support tickets
- FAQ
Driver App (Flutter)
- Jobs for today: collections and deliveries assigned to the driver
- Status updates (collected
- delivered
- attempt failed with reason)
- Proof photos with bag
- hanger and package counts
- Navigation to customer's address (Google Maps)
- Push notifications for new assignments
Admin Panel (ASP.NET Core MVC)
- Dashboard with order and customer statistics (stored procedure DashBoardStatistics)
- Orders: list
- search
- edit
- invoice (PDF)
- receipt
- assign drivers
- bulk item upload from Excel
- Service catalogue: categories
- groups
- items
- bags
- promo codes
- coupons
- Drivers: list
- create
- schedule
- performance reports
- Customers: list
- details
- transaction history
- wallet top-up
- Corporate accounts (Businesses): employees
- orders
- invoices
- Areas
- delivery charges
- time slots
- unavailable days
- Staff users with role-based page access (39 pages
read/save/update/deleteper role)- Reports: revenue
- sales
- customer
- driver
- payment (Excel export with ClosedXML)
- Push notifications to customers and drivers
- Settings: onboarding screens
- terms & conditions
- FAQ
- landing page HTML
REST API (62 endpoints)
- Public: catalogue (areas
- bags
- items
- service categories
- time slots)
- onboarding screens
- FAQ
- Sign-in: OTP request and verify (SMS/email)
- JWT token issue (30 days)
- Orders: place
- list
- details
- cancel
- rate
- proof photos
- Payments: saved cards
- Apple Pay
- wallet top-up
- hosted payment page ticket issue
- User: profile
- address book
- wallet balance
- transactions
- Driver: assigned jobs
- status update
- proof upload
- schedule
- Business employee: login
- items
- place order
- Ownership guards: every userId
- customerId
- driverId
- orderId checked against caller's identity
Payment Integration
- Mastercard Payment Gateway Services (API v71
- Apple Pay v100)
- Hosted payment pages with signed tickets (JWT
- 30 min
- one user)
- Saved cards (tokenization
- last 4 digits
- brand
- expiry)
- Apple Pay (merchant id in 3 files: Info.plist
- Runner.entitlements
- apple_pay_config.json)
- Wallet top-up and cashback from coupons
- Refunds (PaymentGateWayService.RefundsAndCards.cs)
- Payment reports with Excel export
Database (SQL Server)
- 62 tables
- 38 foreign keys
- 151 indexes (62 primary + 89 others)
- Every foreign key column has an index (verified by query in
database/README.md - Cascade deletes only for owned rows (order logs
- payments
- proof photos
- time slots
- role permissions)
- Soft deletes for business data (Status = 2)
- no hard deletes
- 10 stored procedures for reports and lists (DashBoardStatistics
- GetOrdersByFilter
- GetRevenueReport
- GetSalesReport
- GetUsers
- SearchCustomers
- etc.)
- No dynamic SQL: EF Core LINQ for single-entity work
- Dapper with named parameters for lists
- ORDER BY from fixed dictionary (SqlSort.cs)
- PBKDF2 password hashes with check constraint (CK_Users_Password_IsHash)
- One EF Core migration (InitialCreate)
- schema.sql matches it
Security & Access Control
- Admin panel: cookie sign-in (staff roles only)
- 8-hour session with sliding expiration
- Mobile API: JWT bearer tokens (30 days)
- issued after OTP verification
- OTP: 4 digits
- 5 minutes expiry
- 5 max attempts
- demo codes for testing
- Roles: Super Admin
- Admin
- Driver
- Customer
- Business Employee (AppRoles.cs)
- AdminPageAccessFilter: 39 pages with
read/save/update/deleterights per role - ApiOwnershipFilter: customers and drivers can only access their own records (userId
- orderId checked)
- OwnershipGuard: service methods verify caller's identity before data access
- Rate limiting: 10 sign-in attempts per minute per client address
- PBKDF2 password hashing (PasswordService.cs)
- app users sign in by OTP and have NULL password
Notifications & Communication
- Firebase Cloud Messaging for push notifications (customer and driver apps)
- SMS gateway integration (configurable
- disabled by default
- Sms:Enabled in appsettings)
- Email (SMTP
- configurable
- Smtp:Enabled
- templates in
Areas/Admin/Views/Email/ - Push notification screens in admin panel (CustomerPushNotification
- DriverPushNotification)
- Order status change notifications (OrderService.cs)
- Support tickets (UserReportsAndHelp)
Reports & Analytics
- Dashboard statistics: orders
- customers
- revenue (stored procedure DashBoardStatistics)
- Revenue report: date range
- area
- service category
- Excel export (GetRevenueReport)
- Sales report: date range
- customer
- driver
- Excel export (GetSalesReport)
- Customer report: orders
- spending
- last order date (GetUsers)
- Driver report: collections
- deliveries
- performance
- Payment report: transactions
- gateway
- wallet
- Excel export
- Order report: combined report with filters
OrderReport/Index.cshtml - Excel export with ClosedXML (ClosedXML 0.105.1)
Configuration & Deployment
- Docker Compose: web (ASP.NET Core)
- db (SQL Server 2019)
- init-db.sh runs schema.sql and seed.sql
- Environment variables: JWT key
- MSSQL password
- site URL
- OTP log codes (.env.example)
- appsettings.json: JWT
- OTP
- SMS
- SMTP
- payment gateway
- branding
- CORS
- Flutter build-time config: API_BASE_URL
- GOOGLE_MAPS_API_KEY
- SUPPORT_WHATSAPP
- SUPPORT_EMAIL (--dart-define)
- Firebase setup: google-services.json (Android)
- GoogleService-Info.plist (iOS) for both apps
- Release signing: key.properties (Android)
- Xcode team (iOS)
- Launcher icons: flutter_launcher_icons.yaml
- source images in
assets/
| Language | Version | Framework | Used for | Share of code |
|---|---|---|---|---|
| JavaScript | — | — | Front-end | 38.6% |
| CSS | — | — | Styling | 28.2% |
| C# | — | — | Web, API, admin | 11.6% |
| Dart | — | — | Mobile app | 10.4% |
| C# (Razor) | — | — | Web pages | 5.9% |
| SCSS | — | — | Styling | 3.2% |
| SQL | — | — | Database | 1.5% |
| HTML | — | — | Front-end | 0.5% |
| Java | — | — | API | 0.1% |
| Swift | — | — | Mobile app | 0.1% |
| Shell | — | — | Scripts | 0% |
- Primary language
- C# 10 / Dart 3.13
- Framework
- ASP.NET Core 10 / Flutter 3.47
- Database
- SQL Server 2019
- Authentication
- JWT bearer (mobile), cookie (admin), OTP sign-in
- Licence
- Single-site
- Screens
- 85
- Database tables
- 62
- Supported languages
- English only
- Browser support
- Modern browsers (Chrome, Firefox, Safari, Edge)
| Minimum | Recommended | |
|---|---|---|
| CPU | 2 vCPU | 4 vCPU |
| RAM | 4 GB RAM / 20 GB disk | 8 GB RAM / 40 GB disk |
| OS | Linux/Windows with .NET 10 SDK, SQL Server 2019+ | Linux/Windows with .NET 10 SDK, SQL Server 2019+ |
| Est. monthly hosting | $50 | $50 |
```bash cp .env.example .env # Edit .env: set MSSQL_SA_PASSWORD (8+ chars, mixed case, digit, special) and JWT_KEY (32+ chars) docker compose up -d --build # Site: http://localhost:8080 # Default admin: admin@washly.com / Admin@123 ```
```bash sudo apt update && sudo apt install -y dotnet-sdk-10.0 mssql-server sudo /opt/mssql/bin/mssql-conf setup # Choose edition, set SA password sqlcmd -S localhost -U sa -P '<password>' -C -i database/schema.sql sqlcmd -S localhost -U sa -P '<password>' -C -d Washly_db -i database/seed.sql cd "NET Project/DRYX-web" dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=localhost;Database=Washly_db;User Id=sa;Password=<password>;TrustServerCertificate=True" dotnet user-secrets set "Jwt:Key" "<random-32-char-key>" dotnet publish -c Release -o /var/www/washly sudo systemctl enable --now washly # Configure nginx reverse proxy to port 5000 ```
```bash # Install .NET 10 SDK and SQL Server 2019+ on your machine cp .env.example .env # Edit .env: set MSSQL_SA_PASSWORD and JWT_KEY sqlcmd -S localhost -U sa -P '<password>' -C -i database/schema.sql sqlcmd -S localhost -U sa -P '<password>' -C -d Washly_db -i database/seed.sql cd "NET Project/DRYX-web" dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=localhost;Database=Washly_db;User Id=sa;Password=<password>;TrustServerCertificate=True" dotnet user-secrets set "Jwt:Key" "<random-32-char-key>" dotnet run # Site: http://localhost:5208 # Admin: admin@washly.com / Admin@123 ```
Quality report
Manually reviewedHow to read the quality report
What this is. Every project on Vibe96 goes through an automated audit of its source code before a reviewer in Dubai checks it by hand. The score is out of 100; 75 is the minimum to be listed, and any single failing check blocks a listing regardless of the score.
- Security
- No real credentials in the code, every data-changing route protected, admin areas role-gated, no SQL built from user input.
- Code structure
- A developer can navigate and extend it: clear module boundaries, no giant files, little copy-paste.
- Docs & completeness
- The setup guide, example config, schema and required files the builder committed to are actually in the archive.
- Dependency health
- Packages pinned, no known critical vulnerabilities, no abandoned libraries in production paths.
- Build & deploy
- A clean machine can restore, build and start it by following the shipped instructions.
Warnings are problems that didn't block the listing; they stay visible here until a later version clears them. The audit reads the code — it does not run it — so always try the live demo before you buy. Lines of code are counted from the same audited archive.
Reviewer notes (4 minor)
Small improvements the developer has been told about. None of them stop the software from working.
Versions & updates
No updates yet. New versions appear here with a changelog.
Buyers receive updates free for 1 year.
What you get
- </>Full source codeThe complete audited source, delivered as a download from your account. No obfuscation.
- ▤DocumentationSetup guide, architecture notes, CLAUDE.md and AGENTS.md.
- ↻One year of updatesEvery new version the builder publishes, free for 12 months.
- ♧30 days of supportInstallation and defect support through Vibe96 tickets.