Back to projects
WebMobileCase study

Kojo Marketplace

Designed and shipped a full-stack classifieds marketplace for Seller and Buyers, with seller verification and Payment subscription.

Screens/Pages

Mobile app

Mobile app

Web landing page

Web landing page

Overview

Kojo is a Nigerian classifieds marketplace connecting buyers and sellers across states and LGAs, live at kojo.ng. I built the entire platform, a FastAPI backend, a Next.js web app, an Expo mobile app, and an admin panel — covering the complete commerce loop: location-based browsing, listing creation with image uploads, seller KYC verification, reviews, and paid subscriptions through Paystack. The project also involved migrating an earlier Laravel + Inertia implementation onto a fully async Python architecture without breaking the mobile client.

Role

Owned the platform end-to-end as the sole engineer: API design, database schema, web frontend, mobile app, admin tooling, payments integration, and production deployment.

What I built

  • A marketplace where African can buy and sell within their own state or anywhere in the country.
  • A simple way for sellers to create listings with photos and manage everything they're selling from one dashboard — on web and mobile.
  • Buyer protection signals like reviews and ratings so people can buy with confidence.
  • Seller verification so buyers can trust who they're dealing with before money changes hands.
  • A way for sellers to grow their reach through paid subscriptions instead of one-off listing fees.
  • An admin side of the platform to review sellers, moderate listings, and keep the marketplace clean.
  • An admin panel for listing moderation, user management, KYC review with approval/rejection workflow, subscription plan management, and category/attribute CRUD.
  • A complete monetization loop: plan selection → Paystack hosted checkout → signed webhook → subscription activation with expiry → server-enforced free-tier upload limits.
  • A KYC pipeline where sellers submit business documents (CAC, NIN) through a review status workflow before gaining verified status.
  • An image processing pipeline that validates and normalizes uploads (EXIF transposition) and watermarks product photos to protect listings from theft.

Technical approach

I designed a strict API contract first — every endpoint returns one consistent envelope ({ok, data, message, meta} / structured errors with codes and field-level details) — then built all three clients against it, so web and mobile handle success, validation, and auth failures identically.

  • Built using FastAPI (Python) — an async backend API serving both the web and mobile apps.
  • MySQL as the primary database, with Redis used for caching frequently accessed data like listings and category lookups.
  • Mobile mirrors the same contract through a typed API layer with an unauthorized-handler wired into Redux, keeping session behavior identical across platforms.
  • Deployed on AWS cloud infrastructure using EC2 for the application server and RDS for the MySQL database, deployed through a CI/CD pipeline.

Challenges

Payments that actually complete

Subscription checkout leaves the app for Paystack and returns later, so payment state had to survive redirects: webhook signature verification, reference-level idempotency, and transaction re-verification prevent double charges and missed activations.

Enforcing business rules server-side

Rules like 'three free listings per month' or 'active subscription required' had to be enforced at the API layer with clear error responses, since two independent clients consume the same endpoints.

Seller trust and verification

Connecting strangers means reputation risk, so sellers go through document-based KYC with a reviewable Pending → Under Review → Approved/Rejected workflow rather than a simple toggle.

Rewriting a live stack without breaking clients

Migrating from Laravel + Inertia to FastAPI meant preserving behavioral compatibility while improving the contract; the mobile app was migrated onto the new API with a documented field-mapping layer during the transition.

Outcomes

  • Shipped a working three-client marketplace (web, mobile, admin) backed by a single API, live in production at kojo.ng.
  • The full commerce loop works end-to-end: browse by location and category, list products with images, get KYC-verified, pay for subscriptions, and review sellers.
  • One API contract powers all clients with identical success/error semantics, cutting integration friction between web and mobile.
  • Payment reliability holds up under real-world flows — retries, abandoned checkouts, and webhook replays are handled idempotently.