MERA — Clothing Online Store with MoySklad Integration

  • Online store
  • Next.js
  • Payload CMS
  • Integrations
  • Architecture
  • Fullstack
  • Admin panel
  • Fashion

What Was Built

  • Clothing catalog: about 1,000 products and 5,000 SKUs — size and color variants. Filters, search that handles typos, synonyms, and wrong keyboard layout, and complete outfit purchases.
  • Purchase from catalog to delivery: cart, promo codes, YooKassa, CDEK delivery with pickup point selection on a map, customer account, and guest checkout.
  • Store management: syncing the catalog, variants, and stock with MoySklad; managing products, promotions, outfits, the journal, and the home page through admin panels.
  • PWA and push: install MERA as an app, order notifications, and a separate subscription to news and promotions — including for guests.
  • Launch and maintenance: SEO, mobile optimization, load testing scenarios, and one-command deployment.

Idea and Challenge

MERA is a clothing online store with a catalog of about 1,000 products and 5,000 SKUs — size and color variants. The goal was to combine convenient browsing of items and ready-made outfits, online payments, delivery, and catalog and stock synchronization with MoySklad. I delivered the whole project: from design concept and planning to launch.

How the Store Works

Search responds as you type and understands typos: a misspelled “alpca coat” finds alpaca coats, and “cashmir” finds a cashmere jumper. It searches by color and material, knows synonyms (blazer ↔ jacket), and shows not only products but also journal articles in the results.

If a query is typed in the wrong keyboard layout — for example, “gfkmnj” — search figures out what was meant and shows “Results for ‘пальто’ (coat)”. The typed text itself is not replaced.

Technically: Meilisearch with tuned field weights, stop words, and a synonym dictionary. Products and articles are searched in a single query, prices and availability are pulled from Medusa at display time, and the index is updated via webhooks. If the search engine is unavailable, the storefront automatically falls back to Medusa search. Layout correction runs on the server with no external APIs: it maps physical QWERTY ↔ JCUKEN keys, and only when the original query returned nothing — suggestions and full results always match.

Catalog with Filters

Filters by price, material, fit, size, and color, with a product count for each value. Selected parameters appear as chips, and a filtered selection can be shared as a link.

Technically: the Medusa Store API doesn't support facets or price filtering, so the storefront keeps a compact catalog snapshot with an inverted index. The architecture is designed for catalogs of up to 50,000 SKUs, and filtered pages have a dedicated SEO policy.

Product Page and Variants

Color swatches that switch photos, unavailable sizes crossed out, sizes with the last item in stock marked, and a size chart that opens in a modal.

Technically: size and color are product options in Medusa, and stock comes from Medusa inventory in real time.

Outfits: The Whole Look in One Click

Ready-made sets of several items with a “Complete look” price. The shopper picks a size for each item and adds the entire outfit to the cart in one action — which boosts the average order value.

Technically: outfits are assembled by a content manager in Payload; the CMS verifies that each product exists in Medusa, and the cart adds items in a batch and reports if any item is out of stock.

Cart, Promo Codes, and Free Shipping

A “… left until free shipping” bar nudges shoppers toward the 15,000 ₽ threshold, and promo codes are applied right in the cart.

Technically: the threshold and promo codes are promotions in Medusa's promotion module, with no core modifications: the marketer changes the terms in the admin panel.

Checkout and CDEK Delivery

The city is chosen from the CDEK directory, with the region shown next to the name — so three different towns called Troitsk can't be confused. Pickup point and courier delivery costs are calculated right after the city is selected and added to the total.

The form guides rather than punishes: errors appear after leaving a field, and next to the disabled “Place order” button it says what's missing. If the city changes, courier delivery is recalculated and the selected pickup point is marked as outdated — an order can't be placed with another city's rate.

Technically: suggestions are protected against stale responses, and a CDEK directory failure is shown as an error with a “Retry” button rather than “city not found”. Delivery-to-city consistency is checked both in the UI and on the server before payment. A guest cart is safely transferred to the account after sign-in.

On Mobile

Filters, the product page, search, and checkout are adapted for mobile shopping: the total and the order button are pinned to the bottom of the screen. The menu includes the catalog, account, favorites, and help: size guide, care, and delivery. The layout has been tested with text enlarged to 200%.

MERA as an App — PWA

The store can be installed on a phone or added to the Dock and opened in its own window. A dedicated MERA icon appears on the device screen, so shoppers can return to their purchases straight from it.

Technically: a manifest with the name, start URL /, and standalone mode, Apple metadata, and a theme color were added. A favicon, 192 and 512 px icons, an Apple Touch Icon, and a maskable icon were prepared. Installation instructions for phones and the Dock are described in the README.

Order Push Notifications

In their account, shoppers can enable notifications for the current browser. They report order creation and cancellation, fulfillment creation, shipment, and delivery. Tapping a notification opens the relevant order in the account.

Permission is requested only after a button is clicked. Push messages contain no personal data, order contents, or totals. News and promotions are enabled with a separate toggle.

And More

  • Customer account: addresses and order history; guest checkout without registration.
  • A Payload-powered journal with live preview; articles appear in search.
  • SEO: sitemaps for products, categories, and articles, product structured data, and indexing rules for filters.
  • k6 load testing scenarios and one-command deployment.

Admin: How the Store Is Managed

Two clear interfaces instead of one overloaded one: commerce in Medusa, content in Payload. The manager handles products, promotions, and copy on their own, without a developer.

Products, Variants, and Stock

A product record with “Color” and “Size” options, tags for catalog filters, and collections. Each variant has its own SKU and warehouse stock — the storefront automatically shows which sizes are unavailable and where only the last item remains.

Promotions and Promo Codes

Free shipping above a threshold is an automatic Medusa promotion: terms and dates are changed in the admin panel, with no code changes.

Outfits, Journal, and Home Page

An outfit is assembled from catalog products, and the CMS verifies that each product exists. Journal articles come with live preview, version history, and an SEO tab. Home page copy is edited line by line.

Push Campaigns

A section for marketing push campaigns was added to Medusa Admin: the manager creates a draft, checks the preview, confirms sending, and sees the history. Campaigns reach only customers and guests who have separately opted in to MERA news and promotions.

Guests can subscribe right on the storefront and manage their subscription via a persistent element in the footer. Once dismissed, the subscription prompt is hidden for 30 days.

Technically: sending runs through the Medusa backend with VAPID, a background queue, and protection against duplicate deliveries. Ownership of a guest subscription is confirmed via an HttpOnly cookie; owner checks and safe unsubscription are implemented. Passing the Web Push configuration to the backend is part of the deployment process.

Architecture and Stack

A monorepo (pnpm + Turborepo, TypeScript) with two applications. Medusa 2 handles products, prices, stock, orders, and promotions. Next.js 16 with Payload CMS 3 handles the storefront and content. The boundary rule: commerce data belongs to Medusa, content belongs to Payload, linked only by product handle. For faceted filters not available in the Store API, the storefront keeps a compact in-memory catalog snapshot with an inverted index; the cache is invalidated by webhooks when products change. Production: Docker, nginx with TLS and rate limiting, two PostgreSQL databases, Redis, Meilisearch, and one-command scripted deployment.

Integrations

  • YooKassa: a custom Medusa payment provider with no third-party SDKs. I don't take the webhook status at face value: the provider re-fetches the payment via the YooKassa API and determines the result from it.
  • CDEK: a custom fulfillment provider. Rates calculated per route, delivery to a pickup point, parcel locker, or by courier, with point selection on Yandex Maps.
  • MoySklad: syncing the catalog, variants, and stock into Medusa. Idempotent upsert: re-running creates no duplicates, and if the data contains an error the import stops entirely so that no partial data reaches the storefront.

Performance

Google PageSpeed Insights, desktop: performance, accessibility, best practices, and SEO — 100/100/100/100.

Mobile version: 92/100/100/100.

My Role

I built the entire project myself: design concept, architecture, storefront, back end, integrations, and deployment. I made and implemented the key technical decisions myself — splitting commerce data and content between Medusa and Payload, custom payment and delivery providers, the faceted filter index, and the inventory sync scheme. I use AI tools to speed up routine work: boilerplate code, testing hypotheses, tests. Design, architecture, and quality control remain my responsibility.

Result

A full-cycle store: catalog, cart, YooKassa payments, CDEK delivery calculation with pickup point selection on a map, customer account, and content and commerce admin panels. MERA installs as a PWA; push notifications help customers track orders, and separate campaigns keep them informed about news and promotions.