Loading

NaijaClick

Category :
E-Commerce / Marketplace / Fullstack
Domain :
naijaclick.com.ng
Start Date :
2025
Market :
Nigeria / African Diaspora (NRI)

Executive Summary

NaijaClick is a full-stack multi-vendor e-commerce marketplace purpose-built for Nigerian consumers, small business sellers, and the Nigerian diaspora (NRI) seeking authentic healthcare, lifestyle, and cultural products shipped from home. The platform combines a Next.js web application and React Native mobile app backed by 29 Mongoose data models and 90+ API routes, featuring a granular role-based permission system, Paystack payment processing, Cloudflare R2 image storage with lifecycle management, and an affiliate referral program. The architecture was designed from the ground up to handle multi-seller inventory isolation, SEO-optimised dynamic pages, and zero-downtime content delivery — scaling from a solo-seller storefront to a full marketplace.

Project Overview

NaijaClick is a full-stack, multi-vendor e-commerce marketplace built for Nigerian consumers and small business sellers. The platform also targets the NRI (Nigerian diaspora) audience seeking authentic healthcare, lifestyle, and cultural products they trust from home. It surfaces two experiences: a web application (Next.js) for shoppers, sellers, and administrators, and a mobile application (React Native) as a companion shopping and seller management app. Revenue is driven by seller commissions on each transaction, with secondary income from an affiliate referral program where users earn wallet credits for driving new sign-ups and first orders.

Architecture & Data Layer

The Next.js app is organised into five route groups — public homepage, buyer application, auth flows, seller dashboard, and admin panel — each with its own layout and access scope. The data layer is built on 29 Mongoose models covering users, sellers, products, categories, orders, cart, payments, wallets, withdrawals, referrals, earnings, coupons, reviews, support tickets, notifications, and more. The API surface spans 90+ routes split across public, authenticated buyer, seller, and admin namespaces. Every admin and seller route is protected with a granular permission system using 40+ permission constants checked via a hasPermission() utility.

Challenge: SEO with Client Components in Next.js App Router

Interactive pages used "use client" for state management, which prevents generateMetadata exports in the App Router. The solution was a server wrapper pattern: all client-side logic is extracted into a *Content.jsx component, while the parent page.jsx remains a server component that exports generateMetadata — fetching real data from MongoDB (category name, product count, search query). Components using useSearchParams() are wrapped in Suspense boundaries. The result is full dynamic metadata including title, description, OG image, canonical URL, and JSON-LD structured data on every page, while retaining all client-side interactivity.

Challenge: Paystack Payment Integration

Paystack is the dominant payment processor in Nigeria but operates in NGN (kobo). All stored amounts are kept in kobo using integer arithmetic to eliminate floating-point rounding errors. The display layer converts kobo to NGN with locale formatting. Paystack inline-js handles the checkout popup; the backend independently verifies the transaction reference before confirming any order. The payout flow follows a wallet → withdrawal request → admin approval → bank transfer pipeline, with each step fully audited in the data layer.

Challenge: Multi-Seller Inventory Isolation

In a multi-vendor marketplace, products, orders, and earnings must be strictly isolated per seller while admins retain full cross-seller visibility. Every productSchema document carries a seller ObjectId reference. All seller API routes filter by seller: session.user.sellerId. Admin routes carry no such filter and are controlled entirely via the permission system. Order line items reference both buyer and seller, enabling per-seller earnings calculations at settlement time.

Challenge: Cloudflare R2 Image Lifecycle

Without lifecycle management, deleted records leave orphaned files in storage indefinitely, accumulating cost. Every uploaded image creates an imageSchema record in MongoDB tracking the R2 key, owner, and confirmed status. confirmImages(url) marks an image as in-use when a record is saved. deleteImages(url) deletes both the R2 object and the MongoDB record on deletion. Unconfirmed images — from abandoned upload sessions — can be garbage-collected by a scheduled job. This pattern ensures zero orphaned assets from day one.

Challenge: Role-Based Auth Across Three Portals

The platform has three distinct portals — buyer, seller, and admin — each with different data access requirements. NextAuth session stores role, permissions[], and sellerId on the user object. The hasPermission(user, PERMISSION_CONSTANT) utility is called at the top of every protected API handler; no route relies on role strings directly. Middleware redirects unauthenticated users to the correct login page based on the attempted route. Seller onboarding is a separate application flow using submissionSchema — sellers are not active until admin approval.

Technology

Stack Used

Key Features — Buyer Experience

Product discovery with keyword debounce, category filters, price range, and sort controls. Multi-level nested category hierarchy with breadcrumb navigation. Product pages with image gallery, seller info, related products, and FastCheckout — a one-tap inline checkout without leaving the product page. Persistent server-side cart, order history with status tracking, verified purchase reviews, wishlist/favourites, coupon codes at checkout, and a saved address book.

Key Features — Seller & Admin Experience

Sellers get a dashboard with revenue overview, order counts, and top-performing products. Product management supports multiple images, variants, and stock levels. A wallet system tracks real-time earnings with transaction history, withdrawal requests, and payout bank details. Admins have full user and seller management, product moderation, order oversight, a hero slide CMS, category/collection management, coupon management, support ticket responses, platform announcements, and a permissions-gated analytics dashboard.

Affiliate & Referral System

Each user receives a unique referral link. When a referred user registers and places their first order, the referrer earns wallet credits. Earnings are tracked per referral event via EarningSchema and referralSchema. Attribution persists through the full signup funnel. Edge cases — duplicate referrals, self-referrals, coupon stacking with referral credits — required explicit business rules defined before implementation, not discovered during QA.

Lessons Learned

Design the permission system on day one — the granular PERMISSIONS constant map looks like over-engineering for a small codebase, but every new feature only costs two lines. The server wrapper pattern for SEO must be the starting structure, not a later refactor. Storage lifecycle management (confirmImages/deleteImages) must be built in from the first upload, not bolted on. Fallback data ensures zero-downtime UX even during cold-start DB issues. Multi-seller marketplace complexity compounds — every new feature must answer "does this apply per-seller or platform-wide?" at schema design time, not during QA.