Reproducing the apple.com experience — the pixel-perfect scrolls, the products spinning in 3D — all while getting paid through Mobile Money: that's the bet behind iPhone Cameroon, an Apple store built for the Cameroonian market. Two worlds that couldn't be more opposed, reconciled inside a single monorepo.
One contract, zero duplication
The trap in a full-stack project is declaring the same types three times over: on the API side, on the form side, on the display side. I centralized all of it in a @repo/shared package: a single Zod schema that generates the inferred types, the API DTOs, and the form resolvers. The front end and the back end speak the same language, and a change to the contract breaks compilation everywhere it should — not in production.
packages/shared # schémas Zod → types + DTO + formatter XAF
apps/api # NestJS 10 + Prisma + Postgres (JWT argon2)
apps/web # Next.js 15 + React 19 + Tailwind v4
The cart is never the source of truth
A non-negotiable rule in e-commerce: the price is recomputed server-side at checkout. The cart the client sends tells you what, never how much. Stock is decremented transactionally — no overselling if two people buy the last iPhone at the same second.
Mobile Money, done right
Payment goes through an aggregator (think Fapshi / Campay) that exposes MTN MoMo and Orange Money. Locally, sandbox mode by default: without MOMO_* keys, everything is simulated, so I build out the payment flow without depending on a merchant account. The payment result comes back via a webhook POST /api/payments/webhook whose HMAC-SHA256 signature I verify — otherwise anyone could mark an order as paid.
The showroom: GSAP, Lenis, React Three Fiber
On the storefront, the goal was the Apple "feel":
- Lenis for smooth scroll,
- GSAP (
@gsap/react) for timelines and reveals synced to the scroll, - React Three Fiber + drei for the products in 3D.
All of it inside the Next 15 / React 19 App Router, with an Apple design system (CSS tokens + Tailwind v4 preset).
Building in public, on security too
I'm not claiming it's perfect. The README spells out in black and white what still needs hardening before prod: secret rotation, the short order reference (IPC-2026-XXXXXX) to reinforce against enumeration, the admin JWT to move out of localStorage into an httpOnly cookie. Naming your technical debt is already half the work.
Apple brand and visuals used for demonstration purposes — independent reseller, not affiliated with Apple Inc.
Have you ever wired up Mobile Money (MoMo/OM) on a project? Aggregator or direct operator integration — what surprised you the most? Tell me about it.