Back to projects
SaaS / Laundry TechClient ProjectRecent

Spin Laundry

Laundry service platform with a Flutter frontend and Node.js backend deployed on a VPS. It includes PayFast payments with ITN polling, JWT authentication, SSL, and complete production deployment.

Project Summary

My Role

Full-Stack Developer

Tech Stack

FlutterNode.jsTypeScriptPrismaMongoDBPayFastNginxPM2Hostinger VPS

App visuals

Challenge

The client needed a complete on-demand laundry platform for the South African market — a Flutter customer app and a PayFast-integrated payment system, all backed by a custom REST API. There was no existing backend: it had to be designed, built, and deployed to a production VPS from scratch. The client specifically required PayFast's ITN (Instant Transaction Notification) webhook system for server-side payment verification, and needed the entire stack live with SSL on a managed hosting environment.

Solution

I built the complete stack independently — a Flutter mobile app and a Node.js/TypeScript/Prisma/MongoDB REST API deployed on a Hostinger VPS with Nginx as a reverse proxy and PM2 for process management. Backend: Express + TypeScript REST API with Prisma ORM and MongoDB for order, user, and service management. JWT authentication with refresh token rotation. PayFast payment gateway with ITN webhook handling — the Flutter app opens a PayFast WebView, the backend receives the ITN callback and marks the order as paid. Nginx configured as a reverse proxy with SSL termination. PM2 manages the Node.js process with auto-restart on crash. A tricky production issue: the backend was returning 401 on all authenticated requests after deployment. After systematic debugging, the cause was a root-level .env file on the VPS that was silently overriding the app's own environment variables — including the JWT secret. Removing the conflicting file resolved it immediately. The Flutter app connects to the live API with Dio, handles auth token storage via flutter_secure_storage, and supports the full order flow: service selection → scheduling → payment → order tracking.

Outcome

A complete, live full-stack laundry platform — Flutter app connected to a production Node.js API, with PayFast payments, JWT auth, and a properly configured Nginx/PM2 VPS deployment with SSL. The client received a deployed, secured backend with no reliance on third-party backend-as-a-service, ready to use immediately.

What I worked on

Designed and built the full REST API from scratch: Express + TypeScript + Prisma + MongoDB.

Implemented JWT authentication with refresh tokens and secure storage on the Flutter side via flutter_secure_storage.

Integrated PayFast payment gateway: WebView-based payment flow in Flutter + ITN webhook handler in Node.js.

Configured Hostinger VPS: Nginx reverse proxy, SSL certificate, PM2 process manager with auto-restart.

Built the Flutter app with Dio HTTP client and complete order management UI (service selection, scheduling, payment, tracking).

Debugged and resolved a production JWT authentication failure traced to a conflicting root-level .env file overriding the app's environment variables on the VPS.

Handled complete deployment pipeline: domain pointing, SSL setup, environment config, and live API verification.