The Challenge
Premium skincare, regulated data, a small team
The client needed a store that feels as refined as a Scandinavian beauty brand while carrying regulated cosmetics data correctly: full INCI ingredient lists, EU warnings and Responsible Person details that must never be reordered, machine-translated or invented.
They also wanted guided selling — a skin quiz, curated Ritual Boxes and bundles — real carrier fulfilment, bilingual Swedish/English, and an admin a non-technical owner could run alone on standard shared hosting.
The Solution
A custom commerce platform, built around how the client actually sells
• Storefront with categories, search, product pages with variants, reviews, accounts and a journal.
• Skin Profile Quiz that turns six answers into a personalised routine from live inventory.
• Ritual Box subscriptions and curated bundles, with checkout add-on suggestions driven by the client's own rules.
• Stripe card payments, Shipmondo order management and labels, Weglot Swedish/English translation.
• EU compliance blocks — INCI, warnings and Responsible Person — stored separately and protected from machine translation.
• AI product authoring in the admin: staff enter a name, basic info and a photo, and the system drafts the product content against the store's own taxonomy.
• Pre-launch mode, newsletter with welcome and launch campaigns, GDPR-compliant legal pages and one-click unsubscribe.
Tech Stack
System Architecture
Small, explicit layers a new team can pick up in a day
Front controller
index.php bootstraps configuration, the autoloader and the router; 174 routes cover the storefront and an admin mounted on a configurable private path.
Middleware
Admin authentication, role-based access, CSRF, rate limiting and a Coming Soon gate that hides the shop while keeping the admin, newsletter and unsubscribe reachable.
Core
Database, Router, Request/Response, Session, Auth, CSRF, Validator, View, Cache, Mailer (hand-written SMTP client), ImageProcessor, Media and Crypto (AES-256-CBC for secrets at rest).
Domain
Models for products, bundles, add-on rules, subscription plans and customer subscriptions, quiz submissions, ritual guides, orders, reviews and journal articles. Services: AddOnEngine, RitualBoxService, ShipmondoService and an AI service layer with a provider interface and factory.
Data
Products with images, variants, ingredients, a full INCI table and a compliance table; orders with item lines, shipping snapshots and history; a generic media library; key/value site settings and JSON homepage blocks so content is editable without code.
Skin Profile Quiz
Six questions, one deterministic routine
-
Concern
The main skin concern selects exactly one of four product categories — the one deterministic step.
-
Skin type
Sets texture preference within that category.
-
Routine
Chooses a starter set or complementary products for someone who already has a routine.
-
Sensitivity
Excludes strong actives such as retinol and AHA/BHA when sensitivity is frequent or occasional.
-
Age & goal
Age range is a tie-break weighting only; the goal shapes the tone of the ritual guide. Results draw only from published, in-stock products.
Commerce Features
Subscription plans and customer subscriptions with curated boxes, promoted through subscriber popups.
Curated multi-product bundles managed from the admin.
An AddOnEngine evaluates the client's trigger rules against the live cart; the suggested products per rule are swappable from the admin.
Card payments with a production guard: the development fallback can never run when APP_ENV is production.
Push orders to Shipmondo Order Management or book a carrier label from the order screen; raw API responses stored for later tracking extraction.
Subscriber management, welcome and launch emails, paced batch sending and GDPR-compliant unsubscribe.
Admin & Operations
Generates product content from a name, notes and an image, choosing from existing category slugs; provider and model set per store.
Products, variants, images, ingredients, INCI and compliance data, stock and CSV-ready dummy data.
Status workflow, packing slips, Shipmondo actions and order history.
Homepage and legal page blocks, journal, a media library and image-dimension guidance.
Credentials, test mode, carrier products loaded live from the account, sender address and a Test Connection button.
Admin users with roles and permissions; settings changes audited without ever logging secret values.
Compliance, Security & Reliability
Regulated data treated as regulated
• INCI lists, warnings and EU Responsible Person details are stored as supplied by the client's compliance consultant and marked no-translate, so Weglot never machine-translates regulated safety text; Swedish wording is entered by hand.
• API secrets (Shipmondo, AI providers) are encrypted at rest with AES-256-CBC and a random IV, never rendered back to the browser, and only replaced when a new value is typed.
• CSRF on every form, rate-limited endpoints, role-based admin access and an audit log.
• Checkout guarded so a missing Stripe key can never complete an order in production.
• Email built for real inboxes: table layouts with inline styles and real text, sent over STARTTLS on the only port the host allows, with failures logged rather than allowed to break checkout.
Documentation & Handover
Delivered ready for another team to run
The project shipped with a technical handover for the incoming team (architecture, configuration, database, integrations, hosting constraints and known gaps), a plain-English owner's guide to every admin screen, a Shipmondo integration guide, an image-dimension guide and a credentials-transfer checklist that lists every account and key without containing a single secret.
Known gaps are documented rather than hidden — Stripe refunds and webhooks, carrier tracking sync and Weglot subdirectory SEO — each with the recommended next step.
By the Numbers
Database tables
Products, compliance, subscriptions, orders, media
Routes
Storefront and private-path admin
Lines of code
20k PHP across 174 files + 6k CSS & JS
AI providers
OpenAI, Gemini, Groq, Grok, Hugging Face
Languages
Swedish and English
Frameworks
Hand-rolled MVC on shared hosting
Product Gallery
Storefront, quiz, Ritual Box and admin