Lorhia

Lorhia

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

Backend PHP 8.3, hand-rolled MVC and router — no framework, no Composer
Database MySQL / MariaDB — 48 tables, dated SQL migrations
Front-end Vanilla JS and modular CSS — no build step
Payments Stripe (direct API over cURL)
Fulfilment Shipmondo official SDK — sales orders and carrier labels
Localisation Weglot Swedish/English with compliance blocks excluded
AI Pluggable providers: OpenAI, Gemini, Groq, Grok, Hugging Face
Hosting Loopia shared hosting, SMTP over STARTTLS

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

  1. Concern

    The main skin concern selects exactly one of four product categories — the one deterministic step.

  2. Skin type

    Sets texture preference within that category.

  3. Routine

    Chooses a starter set or complementary products for someone who already has a routine.

  4. Sensitivity

    Excludes strong actives such as retinol and AHA/BHA when sensitivity is frequent or occasional.

  5. 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

Ritual Box Subscriptions

Subscription plans and customer subscriptions with curated boxes, promoted through subscriber popups.

Bundles

Curated multi-product bundles managed from the admin.

Smart Checkout Add-ons

An AddOnEngine evaluates the client's trigger rules against the live cart; the suggested products per rule are swappable from the admin.

Stripe Checkout

Card payments with a production guard: the development fallback can never run when APP_ENV is production.

Shipmondo Fulfilment

Push orders to Shipmondo Order Management or book a carrier label from the order screen; raw API responses stored for later tracking extraction.

Newsletter & Campaigns

Subscriber management, welcome and launch emails, paced batch sending and GDPR-compliant unsubscribe.

Admin & Operations

AI Product Authoring

Generates product content from a name, notes and an image, choosing from existing category slugs; provider and model set per store.

Catalogue & Inventory

Products, variants, images, ingredients, INCI and compliance data, stock and CSV-ready dummy data.

Orders

Status workflow, packing slips, Shipmondo actions and order history.

Content & Media

Homepage and legal page blocks, journal, a media library and image-dimension guidance.

Shipmondo Settings

Credentials, test mode, carrier products loaded live from the account, sender address and a Test Connection button.

Roles & Audit

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

48

Database tables

Products, compliance, subscriptions, orders, media

174

Routes

Storefront and private-path admin

26k

Lines of code

20k PHP across 174 files + 6k CSS & JS

5

AI providers

OpenAI, Gemini, Groq, Grok, Hugging Face

2

Languages

Swedish and English

Frameworks

Hand-rolled MVC on shared hosting

Want something like this?

Let's talk about your project requirements.

Start a Project