GEHWOL.MARKET — доработки интернет-магазина (152-ФЗ + задачи заказчика)
Российский ритейлер профессиональной космецевтики (мультистор, 13 регионов Юга РФ) · E-commerce / косметика (профессиональный уход за ногами, бренд GEHWOL)
Сеть из 13 региональных магазинов немецкой марки по уходу за ногами. Привёл её к закону о персональных данных, за нарушение которого штрафуют от оборота.
- PHP
- OpenCart
- ocStore 3.0.2.0
- Twig
- JavaScript
- MySQL
- SQL
- HTML
- CSS/SCSS
- OCmod
- JSON-LD/schema.org
- reCAPTCHA v3
- SSH/cPanel
В цифрах
- 13
- региональных магазинов (мультистор на одной БД/теме/коде); все охвачены правками и верификацией
- 8
- задач заказчика закрыто по реализации на живом сайте (по 8-й — ручная приёмка pending)
- 234
- уникальных FAQ Q&A внедрено (главная 8 + 30 категорий 226) в oc_gehwol_faq*
- 30 из 58
- потребительских категорий покрыто FAQ; B2B-подтрек/тонкие SKU-корзины осознанно пропущены (thin-content)
- 9
- форм с чекбоксами согласия приведены к 152-ФЗ (снята преотметка + серверная валидация)
- score=0.9, success=1
- приёмка reCAPTCHA реальным браузерным сабмитом после перевода на v3 invisible
- 4
- кастомных OCmod-пакета/модуля: gehwol_compliance, gehwol_faq, gehwol_messengers, gehwol_cookie
- 3
- юр.документа опубликованы в подвал на 14 витринах с target=_blank (Политика id=8 переписана, Согласие id=14, Оферта id=15) — подтверждено на живом сайте
- ~79 / 116 / 158 ч
- оценка трудозатрат по плану (min/expected/max) без апгрейда PHP — план, не факт
Ключевое
- В девяти формах галочки согласия стояли заранее проставленными — прямой запрет закона. Снял их, добавил проверку на сервере и журнал согласий.
- Журнал хранит не сами данные покупателя, а их необратимые отпечатки: подтвердить факт согласия можно, восстановить персональные данные из журнала — нет.
- Нашёл причину «вечной ошибки» защиты форм от роботов: в настройках стоял ключ одной версии сервиса, а на странице работал виджет другой.
- Построил раздел вопросов и ответов, редактируемый из админки, и написал для него 234 пары «вопрос — ответ», покрыв 30 потребительских категорий из 58.
- Всё внедрено отдельными модулями, без правки ядра магазина: обновление движка не сотрёт сделанное, а любой шаг можно откатить.
Задача
Сеть из 13 региональных интернет-магазинов немецкой марки по уходу за ногами работает на одной кодовой базе: один движок, одна тема, тринадцать витрин.
К лету 2026 у сети накопился пакет требований закона о персональных данных, за нарушение которых с 2025 года штрафуют в доле от оборота. Во всех формах галочки согласия стояли заранее проставленными — это прямой запрет. Отдельного согласия на обработку данных и оферты на сайте не было вовсе, а политика устарела. Вдобавок не работала защита форм от роботов, не было раздела вопросов и ответов, а уведомление о файлах cookie никак не управлялось.
Что сделано
- Начал с разведки по живому магазину и его базе, ничего не меняя, и отдельно изучил, чего именно требует закон в действующей редакции. План из восьми задач с оценкой трудозатрат и порядком отката согласовал с заказчиком до первой правки.
- Привёл к закону девять форм: снял заранее проставленные галочки, добавил проверку согласия на сервере, а не только в браузере, и завёл журнал согласий. В журнале хранятся не сами данные покупателя, а их необратимые отпечатки — подтвердить факт согласия можно, восстановить из журнала персональные данные нельзя.
- Написал и опубликовал три юридических документа: согласие на обработку данных, оферту и переписанную политику. Все три доступны из подвала на каждой витрине сети.
- Нашёл причину «вечной ошибки» защиты форм от роботов: в настройках стоял ключ одной версии сервиса, а на странице работал виджет другой. Перевёл на невидимую проверку и убедился в работе живой отправкой формы, а не только настройками.
- Построил раздел вопросов и ответов, редактируемый из админки, и написал для него 234 пары «вопрос — ответ» с медицинскими оговорками, покрыв 30 потребительских категорий из 58.
- Сделал управляемые из админки блок мессенджеров и уведомление о файлах cookie с центром настроек, где покупатель выбирает категории по отдельности.
Итог
Сеть из 13 магазинов приведена к требованиям закона о персональных данных: галочки согласия больше не проставлены заранее, согласие проверяется на сервере, а его факт фиксируется в журнале — при проверке есть чем подтвердить. Три юридических документа опубликованы и открываются на всех витринах.
Защита форм от роботов заработала: раньше отправка упиралась в ошибку, которую никто не мог объяснить. В магазине появился раздел вопросов и ответов — 234 пары, 30 потребительских категорий из 58. Оставшиеся категории пропущены сознательно: писать в них было бы нечего, а пустые страницы вредят выдаче.
Восемь задач заказчика закрыты по реализации, последняя ждёт ручной приёмки. Всё сделано отдельными модулями, без правки ядра магазина, — обновление движка не сотрёт результат.
Технические детали
Решение и подход
- Архитектура внедрения: единый OCmod-пакет
gehwol_compliance(правки шаблонов/контроллеров) + три кастомных модуля (gehwol_faq,gehwol_messengers,gehwol_cookie), каждый со своим*.ocmod.xml. Принцип — не трогать vendor-ядро OpenCart; правки переживают обновления и легко откатываются (удалить XML → Refresh). - 152-ФЗ-согласия (задача 3): снятие
checkedчерезposition="replace", серверная валидация (включая добор недостающей проверкиagree_pol_konfв контроллере predzakaz), новая таблицаoc_consent_logс индексами и приватной моделью (SHA-256-хеши IP/UA/контакта с фиксированной солью вместо сырых ПДн; запись обёрнута в try/catch — сбой лога не ломает форму; один лёгкий INSERT — бережно к db_block). - FAQ (задача 7): модуль admin+catalog, таблицы
oc_gehwol_faq/_descriptionс индексом по target, кэширование выборки (1 индексированный SELECT из кэша на страницу), рендер через 4 OCmod-инъекции (home/category controller+twig), аккордеон W3C ARIA + FAQPage JSON-LD; контент-конвейер: Markdown-черновики → локальный парсерtools/parse_faq.php→ идемпотентный CLI-импортёр. - Мессенджеры (задача 5): настройки в
oc_setting(store 0), чтение из реестраconfig→ 0 запросов к БД на рендер; inline-SVG, тумблеры мест (шапка/подвал/контакты), управление из админки. - Cookie (задача 8): порт эталона
cookie-multi(WordPress → OpenCart): 2 статических ассета (vanilla JS без jQuery + CSS), одна OCmod-вставка вheader.twig, localStorage с TTL и версионированием, публичный контрактwindow.cookieConsent+ события; «фиктивный» режим (UI + хранилище, реальную блокировку заказчик подключает по переданному README). - Капча (задача 6б): эмпирическая диагностика (зонды api2/anchor, контрольный v2-ключ) → корневая причина «Invalid key type» = ключ v3 при v2-виджете; перевод темы на v3 invisible + бэкенд-проверка score≥0.3 с логом для тюнинга.
- Нетривиальные находки темы revolution (задокументированы): подвал store 0 рендерится из таблицы
oc_theme, а не из файла/OCmod → правки в двух местах; языковые строки грузятся черезstorage/modification→ нужен Refresh + сброс OPcache; инвертированное полеnoindex; построчный поиск движка OCmod (многострочные anchor не срабатывают, смещение черезoffset).
Стек и обоснование
PHP 7.3-совместимый код (апгрейд PHP заказчик отложил) на OpenCart/ocStore 3.0.2.0 + Twig. OCmod выбран как способ внедрения, переживающий обновления ядра/темы и легко откатываемый; кастомные модули (admin+catalog MVC-L) — там, где нужны хранение и управление из админки (FAQ, мессенджеры). MySQL с обязательными индексами и кэшированием выборок — из-за истории db_block. Vanilla JS для cookie (без зависимостей, минимальная поверхность, CLS=0). reCAPTCHA v3 invisible — по решению заказчика чинить Google, а не переходить на Yandex SmartCaptcha. JSON-LD (FAQPage) — под AI-выдачу и Яндекс, несмотря на сворачивание FAQ rich results в Google.
Инженерные вызовы
- Legacy на shared-хостинге с историей db_block: все решения проектировались под минимум запросов (кэш, индексы, чтение из реестра config, лёгкие INSERT), правки БД — только с бэкапом и вне пик.
- Мультистор из 13 витрин на одной теме: правки шаблона применяются ко всем сразу, но контент/настройки различаются по store_id; добавляла сложности скрытая подмена подвала store 0 через таблицу
oc_theme(правки в двух местах). - Среда рендера revolution: языковые строки и шаблоны грузятся через
storage/modification→ правка оригинала невидима без Refresh + сброса OPcache; построчный движок OCmod не видит многострочные anchor. - CLI ≠ web-FPM: первая гипотеза бага капчи (allow_url_fopen=Off) была построена на SSH-CLI и оказалась ложной; реальный веб-FPM имеет другие возможности — достоверно проверяемо только разовым webroot-скриптом по HTTPS.
- Юридические компромиссы: «омоложение» дат отзывов (задача 4) выполнено как тест-превью по прямому указанию заказчика с письменной оговоркой о риске ФАС и инструкцией отката из бэкапа — вместо того чтобы молча выполнить или отказать.
- PHP 7.3-совместимость без современного синтаксиса при сохранении читаемости и безопасности.
Услуги в проекте
- аудит
- доработка существующего
- деплой
- 152-ФЗ/ПДн
- контент
- SEO
- поддержка