LiveSince 2026

Web · Admin

Architecture, backend, storefront and admin

Solovit Store

A self-hosted, bilingual online store for an Egyptian supplements brand: cash on delivery, a customer wallet, loyalty points, and an admin the owner's staff run the business from.

  • Commits since July 2026

  • Test files: unit, API and end-to-end

  • Languages, Arabic first

Solovit Store home page in Arabic

01/Problem

The brand needed its own store, not a rented one: Arabic-first content, cash on delivery, shipping priced per governorate, and staff who also take orders on WhatsApp.

It also had to grow with the business: offers, a wallet, loyalty points and campaigns were added while the store was already taking orders, without breaking the money.

02/Constraints

  • 01Arabic and English for the interface and the product content, entered once in the admin.
  • 02Money must stay exact: wallet, points and discounts can never drift from what the customer saw.
  • 03Real ad attribution, with tracking only after the visitor consents.
  • 04Self-hosted on one server with nightly backups.

03/Architecture

Customers

  • Storefront · Next.js 15
  • next-intl ar/en
  • Meta Pixel + CAPI

Staff

  • Admin · Medusa v2
  • orders & analysis
  • wallet · loyalty · lucky game

Commerce core

  • Medusa modules
  • custom ledgers
  • scheduled jobs
  • email

Data

  • PostgreSQL 16
  • Redis 7
  • Cloudflare R2 + CDN
Medusa v2 provides orders, carts and products; everything specific to this business (wallet, loyalty, the lucky game, governorate shipping, WhatsApp orders) is a custom module with its own admin pages.

04/Decisions

  1. Never take an order at a total the customer didn't see

    Placing the order re-prices shipping and re-applies promotions. If the total moves at that moment, the order stops, the page refreshes and asks the customer to review the new total, instead of silently charging a different amount.

  2. Wallet and points as ledgers, not balances

    Every credit and spend is a ledger row. Points are earned only when an order is delivered and paid, and reversed on refusal or cancellation. Writes are idempotent and serialized per order, so a double click never credits twice.

    Trade-off: More code than a single balance column, and every new feature has to say how it reverses.

  3. Attribution from the server, after consent

    Browsers block pixels. Purchases are also sent server-side through Meta's Conversions API with the click identifiers, so the owner sees which campaign sold, and an admin page shows whether tracking is actually working.

  4. AI fills the product page, a person checks it

    The new-product editor gives staff a ready Arabic prompt for any chat model. They paste the JSON back and every text field fills in both languages. Prices, sizes and images stay manual; the parser tolerates wrapped JSON and fills only the keys present (11 tests).

05/Screens

Product page: sizes, bonus packs, cash on delivery
Product page: sizes, bonus packs, cash on delivery
The lucky game: sign up, spin, win store credit or a discount
The lucky game: sign up, spin, win store credit or a discount

06/Stack

Medusa v2Next.js 15React 19TypeScriptPostgreSQL 16Redis 7next-intlCloudflare R2Meta CAPIVitestPlaywrightDockerCaddy

Next systemSolovit CMS
Mohammed Yousef Ali | Systems Architect for real businesses