🌿

WordPress Showcase Site with Ordering via VKontakte

for the essential-oils brand «Дыхание Поволжья», built for billboard mobile traffic

A lightweight WordPress showcase site for an essential-oils brand: catalogue with volumes and wholesale pricing, a cart stored on the buyer's device, orders via VKontakte messages and a community bot, RU/EN, a client-run admin.

Client: Дыхание Поволжья

In production
2 languages
Russian and English, a switcher in the header, language detected from the browser
1 catalogue
for the site and the VKontakte bot: prices and stock are edited in one place
14 days
retention of the daily copy of the database and uploaded photos
“Dykhanie Povolzhya” WordPress showcase by DevUnit Lab: the home page and the catalogue with prices on a phone
“Dykhanie Povolzhya” WordPress showcase by DevUnit Lab: the home page and the catalogue with prices on a phone

The task

The client, a brand of natural essential oils and hydrolates called «Дыхание Поволжья» (Breath of the Volga Region), runs billboard ads in Moscow. A passer-by follows the link from the billboard, almost always on a phone, browses the catalogue and goes to buy. Payment on the site is not needed: by agreement with the client, the whole purchase happens in a VKontakte community, and the site has to bring the buyer there with the product already chosen.

The requirements were simple:

  • instant loading on mobile, with no heavy page builders and no external fonts;
  • styling that follows the client's brand book: colours, the Bebas Neue and Geologica fonts, a vector logo from the designer's files;
  • an admin panel where a client with no WordPress experience changes products, prices, availability and almost all site texts;
  • Russian and English versions, light and dark themes.

The solution

A showcase site on WordPress with a custom theme, no third-party plugins or builders, in plain CSS and JS. A showcase site presents products and leads to an order, but does not take payment itself. Next to it runs a VKontakte community bot in Python that receives the order from the site and hands it to a manager.

What was implemented:

  • A custom «Products» post type: several volumes per product, each with its own retail and wholesale price, availability («In stock», «On order», «Out of stock»), a label on the photo, a gallery, a full description (composition, use, storage) and an English version.
  • A cart on the buyer's device: a slide-out panel, quantity, line total and grand total, and the wholesale price switching on by itself at the right quantity. A volume that is out of stock cannot be added to the cart.
  • Two routes to an order: a «Buy on VKontakte» button on a volume that links to the community product, and «Order on VK» from the cart, which passes the order contents to the bot.
  • A «Site» panel in the admin: an overview with launch readiness, «Texts and blocks» with a live preview, «Contacts and legal details» with tax-ID and registration-number checks, «SEO and counters», «Documents» with version history, and «Prices and stock» in one table.
  • Light and dark themes following the device setting with a manual switch, and RU/EN with language detected from the browser and a switcher in the header.
  • A personal-data policy and a cookie notice from templates with the legal details filled in automatically; Yandex Metrica and Google Analytics load only after consent.
  • Protection: XML-RPC closed at the entry nginx, the login form limited by attempts, the administrator login hidden from outside, comments off, a daily snapshot of the database and photos.

How it works

WordPress: a custom «Products» post type

Standard WordPress posts do not suit products with several volumes, so the theme declares its own post type. Volumes, prices, wholesale and availability are stored for each product as a separate set of fields and edited in the product card above the description. Product categories have their own pages, a card has a block of similar products, and the catalogue has pagination.

A cart in localStorage

The cart lives in the buyer's browser, in localStorage, and needs neither an account nor a server session. localStorage is storage that the browser keeps on the device between visits. The cart script calculates the total, switches wholesale on when the threshold is reached and refuses a volume that is out of stock.

Ordering through VKontakte messages

Adding a product to a VKontakte cart from a third-party site is not possible; this is a limit of the platform itself. So the «Buy on VKontakte» button opens checkout in the community with the right product, while the site cart sends the order contents to its own API, receives a one-time code and opens the community chat with a link that carries the code. The code lives for three hours. For people who have already chatted with the community, VKontakte does not pass the link parameter, so the code is put on the clipboard and the bot understands it as text. If the site does not answer within three seconds or the bot is off, the cart falls back to copying the order text.

A VKontakte community bot on aiohttp

The bot is written in Python with aiohttp and works through Long Poll, keeping dialogue state in SQLite. It reads the catalogue from the site: the site has an API that returns products, volumes, prices, wholesale thresholds and availability, cached for a minute. The bot takes an order by its code from the site exactly once, and the contents are checked against the site's database, not against what the browser sent. Wholesale, out-of-stock items and unfamiliar questions go to a manager. The administrator has version and statistics commands, a staff list with roles and a spam filter.

A custom theme from the brand book

Colours and fonts come from the brand book, the font files are stored in the theme, and there are no requests to Google Fonts. The logo is a vector in several variants, with plants from the roll-up banner and a pattern from the mark on the first screen. At the client's request a conifer-green accent for buttons and badges was added on top of the brand book. The site icons are built from the mark, including variants for phones and a manifest.json.

An admin in the client's own language

The «Site» section opens right after login and shows a launch-readiness checklist. In «Texts and blocks» any label of the home page, header, footer, catalogue, cart and cookie notice can be edited; the text changes in the preview as you type, the view switches between desktop and phone, and every field has an «Original text» option. English texts are edited in the same place with «no translation» and «check translation» marks. The Word guide for the client is built by a script: it captures screenshots of the site and the admin in a browser, draws callouts and assembles a 29-page document with 17 screenshots.

Results

  • The site has been live on its production domain, written in Cyrillic, since 21 September 2026 with indexing open; the domains with Latin letters and with a typo lead to the main one by a permanent redirect.
  • The client changes prices, availability, photos and texts on their own, with no developer needed.
  • A buyer from an ad lands on a lightweight mobile catalogue and moves to the community chat with the order ready.
  • The bot and the site work from one catalogue: there is no second product list and no price mismatch.
  • The site opens in the visitor's device theme and language, Russian or English.
  • A daily snapshot of the database and uploaded photos is kept for two weeks, and HTTPS renews automatically.

Technologies and why

  • WordPress with a custom theme — the client gets a familiar admin and editor, while the theme does not depend on third-party plugins or builders.
  • PHP 8.2 — the language of the theme: post types, the «Site» panel, the API for the bot, structured markup.
  • MariaDB 10.11 — the WordPress database: products, texts, settings.
  • Plain CSS and JS — the showcase, both themes, the cart and the gallery without frameworks, so the page is light on a phone.
  • Python and aiohttp — the VKontakte community bot: Long Poll, a button-driven dialogue, reading the catalogue from the site.
  • SQLite — the bot's dialogue state, with no separate database server.
  • Docker Compose — the same environment locally and on the server, with the bot in its own container.
  • Let's Encrypt — HTTPS with automatic renewal on the studio's web server.

Status

Site version 0.9.9 of 22 September 2026, community bot version 1.2.1. The site is open at дыханиеповолжья.рф, indexing is on, and the Yandex Metrica counter is connected with a goal on the «Order on VK» click. The catalogue currently holds two items and is waiting for photos and prices from the client; the regional part for Moscow and Chuvashia will appear once the delivery terms are known. The project has no automated tests, and acceptance follows the criteria in the documentation.

Questions about this project

Can you build an online store without online payment or delivery?
Yes. This site takes no payment on purpose: the cart assembles the order and the deal is closed by messaging in a VKontakte community. The cart passes the order contents to the community bot with a one-time code, so the buyer lands in the chat with the order already prepared. If the site does not respond or the bot is off, a fallback copies the order text instead.
Can the client change prices, stock and texts without a developer?
Yes. The «Products → Prices and stock» section shows all products in one table: prices, wholesale, availability, drag-and-drop order and a percentage change for all prices at once. Texts and photos of the blocks are edited in «Texts and blocks» with a live preview in desktop and phone views. The admin has a built-in guide with 11 sections, plus a separate 29-page guide in Word.
How does wholesale pricing work on the site?
Each product volume has its own retail price, wholesale price and wholesale threshold. The wholesale price switches on in the cart by itself once the required quantity is reached. The community bot takes the same thresholds from the website, so there is no second product list.
Why does the site need a VKontakte community bot?
The bot walks the buyer through the catalogue with buttons: product, volume, quantity, checkout. It reads prices and stock from the website through its API, passes wholesale and out-of-stock items to a manager, and answers common questions. That way an order from an ad is not lost between the site and the chat.
How is the site set up for SEO?
Pages and products have their own titles and descriptions, Schema.org markup in JSON-LD (Organization, WebSite, BreadcrumbList, Product with price and availability, ItemList), breadcrumbs, a sitemap, robots.txt, Latin URLs instead of Cyrillic ones, hreflang and a separate canonical URL for the English version. Analytics load only after cookie consent.
Where is the site hosted and what about backups?
The site runs in Docker on the studio's web server, with HTTPS and an automatically renewed Let's Encrypt certificate. A daily copy of the database and uploaded photos is kept for two weeks. XML-RPC is closed, the login form limits the number of attempts, and the administrator login is not visible from outside.

Need something similar?

Tell us about the task — we'll show how we solved it and estimate the scope.