A custom full-stack stationery storefront created as the working demo before the owner moved the final store to Shopify.
- React
- Redux Toolkit
- Node.js
- Express
- MongoDB
- Stripe
Parin Studio began as a custom full-stack website built as a working demo for a nature-inspired stationery brand. As the developer and designer, I created the storefront, visual direction, product discovery, cart, checkout, customer accounts, order history, test-payment flow, and administration workflows. After the demo stage, the owner chose Shopify as the final commerce platform, and the customer-facing Shopify store was configured and designed to carry the same brand direction into launch. This case study focuses primarily on the custom web demo and its full-stack implementation, while the completed Shopify storefront is available through the Shopify Final Site link.
Project Scope
- Responsive storefront
- Customer accounts
- Persistent cart
- Guided checkout
- Admin operations
- Test payments
A small online stationery brand needs more than a product catalogue: customers need a dependable path from discovery to payment, while administrators need one protected place to operate the store.
- The customer experience covers product discovery, search, pagination, product details, stock, reviews, a persistent cart, checkout, accounts, and order history.
- The administration area manages products, users, orders, homepage content, store settings, and payment configuration.
- Protected routes distinguish signed-in customers from administrators through authentication and role checks.
- Payments and catalogue data are demonstrations; Stripe and PayPal use test or sandbox integrations rather than live commerce credentials.
From Store Requirements to Deployment
- 1Define Customer and Administrator Journeys
- 2Model Users, Products, Reviews, Orders, and Settings
- 3Build Express Routes, Middleware, Controllers, and Models
- 4Create React Screens and Reusable Interface Components
- 5Centralise API State with Redux Toolkit and RTK Query
- 6Integrate Authentication, Email, and Test Payments
- 7Deploy the Frontend and API as Separate Vercel Projects
The project was built as two coordinated applications: a React storefront and administration interface, plus a layered Express API connected to MongoDB and external services.
Storefront to Verified Order
No
Yes
Stripe test checkout
PayPal sandbox
The checkout experience guides a customer from the catalogue to an order record, but the backend remains responsible for prices, stock checks, payment verification, and the final paid state.
The client stack was selected to support a multi-screen commerce interface with predictable navigation, shared state, and reusable API behaviour.
- React 19 was chosen for component-based storefront and administration screens, while React Router 7 keeps customer and protected routes within one client application.
- Redux Toolkit was selected over hand-written global state to organise authentication and cart state with less boilerplate.
- RTK Query centralises REST requests, loading states, caching, mutations, and tag-based invalidation instead of duplicating request logic across screens.
- React Bootstrap provides responsive, accessible interface primitives while custom styles establish the nature-inspired Parin Studio visual identity.
The server and infrastructure stack were chosen to keep the application JavaScript-first while supporting persistent data, protected workflows, and third-party commerce services.
- Node.js and Express 5 provide a compact REST API and middleware pipeline that shares the same language as the React client.
- MongoDB Atlas and Mongoose fit the document-shaped product, review, user, order, and settings data while adding schemas and relationship references.
- JWT HTTP-only cookies and bcrypt keep session tokens outside client-side JavaScript and store password hashes rather than plain-text credentials.
- Stripe, PayPal, Google OAuth, Nodemailer, and Vercel were integrated rather than rebuilding payments, identity, email delivery, and cloud deployment from scratch.
Full-Stack Application Architecture
Application Layers
External Services
The API accepts credentialed requests only from the configured frontend origin and returns an HTTP-only JWT cookie for authenticated sessions.
The frontend and API are deployed independently. React and RTK Query call an Express REST API, which applies authentication and role middleware before controllers access MongoDB or external services.
The browser is not treated as the source of truth for an order. The API reconstructs order lines from database products, recalculates totals, checks ownership, and verifies the payment provider before changing payment and stock state.
- Order creation ignores client-supplied prices and rebuilds each line from current product records.
- Quantity and stock checks reject invalid, unavailable, or insufficient inventory before an order is accepted.
- Stripe verification checks the order ID, paid status, AUD currency, and exact amount; PayPal verification follows the same server-side principle.
- MongoDB transactions combine stock deduction with the paid-state update, and a stockDeducted flag protects against repeated deductions.
- Order ownership prevents customers from reading or paying another user's order, while administration routes add an isAdmin role check.
- CORS is limited to the configured frontend origin and authenticated requests include the HTTP-only JWT cookie.
Core Commerce Data Model
↓ places
↓ writes
↓ admin creates
Order contains
Each item references a Product
Product receives
Ratings remain connected to users
The data model connects customers, products, reviews, orders, order items, and store settings while preserving the product and pricing snapshot required for historical orders.
The portfolio demo is deployed as separate Vercel frontend and API projects with MongoDB Atlas and environment-based configuration. It demonstrates the complete workflow without claiming production commerce readiness.
- The frontend receives the API address through configuration, while the API permits credentials only from its configured client origin.
- Repository-hosted images avoid relying on Vercel's non-persistent serverless filesystem.
- Payments are sandbox or test integrations, and PayPal is currently disabled in the deployed payment configuration.
- The repository does not include a documented automated test suite; future work should add controller, payment, and end-to-end checkout tests.
- Production hardening should add payment webhooks, stronger request validation, observability, image storage, accessibility audits, and recovery paths for interrupted checkout.
- Email delivery is best-effort after order updates, so a durable queue would make notifications more reliable at production scale.