Магазин упаковки: задачи вокруг старого OpenCart, не ломая его
Оптово-розничный магазин упаковки в Петербурге с учётом в 1С. За год вокруг боевого OpenCart 2.3 появились экран показателей отдела продаж, видеораздел с фоновой конвертацией, портал аттестации сотрудников, отчёт по трафику и демо новой витрины на Mercurio. Магазин при этом не останавливался.
Что было
Клиент - оптово-розничный магазин упаковки в Петербурге: клейкие ленты и скотч с логотипом, дой-пак и вакуумные пакеты, перчатки, плёнка, коробки на заказ. Сайт lpack-spb.ru работает на ocStore 2.3 с PHP 7.2 и ionCube, поиск на Sphinx, обмен с 1С. Покупатели к нему привычны, учёт и продажи ведутся в 1С.
Задачи у такого бизнеса приходят маленькими порциями: показать продажникам цифры, выложить ролики, обучить новых сотрудников, понять, откуда трафик. Переписать всё с нуля значит на полгода остаться без изменений. Я выбрал другой путь: каждая задача - отдельный небольшой инструмент рядом с сайтом, а сам сайт дорабатываю аккуратно и по частям.
Экран показателей отдела продаж
Начали в сентябре 2025 с монитора в отделе продаж. В 1С у клиента есть виджеты с показателями, но смотреть их внутри учётной системы неудобно. Сделал небольшое приложение на Laravel 12: сервер логинится в 1С, забирает JSON виджетов, при отказе перелогинивается и отдаёт фронту данные вместе с серверным временем. На экране отгрузки и счета за год против плана, воронка, конверсия за день, месяц и год, средний чек, звонки, WhatsApp, письма, движение денег, таблица по менеджерам. Графики на Chart.js, табы переключаются по кругу сами, есть полноэкранный режим. Это не CRM и не замена 1С: экран, который показывает, как идёт день.
Видеораздел на OpenCart 2.3
Весной 2026 перешли к самому сайту. В марте - коммерческое предложение, страницы услуг и модуль контентных блоков для категорий в админке. В мае - секции в редакторе статей блога: своя вкладка, переключатель между визуальным редактором и кодом, карусель товаров.
В августе клиент захотел ролики: обзоры товаров с телефона, видеоотзывы, вертикальная лента в стиле Reels. В OpenCart 2.3 такого нет, сделал своё: схема БД, админка загрузки, хаб /videos, страница ролика с ЧПУ и разметкой VideoObject, карусель на главной, плитка в галерее товара, ролики в выдаче категории, карточке товара, поиске и на лендингах услуг.
Телефон отдаёт MOV, браузеры хотят MP4. Конвертацию сделал фоновой: очередь в базе, воркер на ffmpeg, крон как подстраховка, статус в админке. Лимит загрузки поднял со 100 до 500 МБ, mp4 отдаёт nginx мимо PHP. По пути поймал и починил двойной flock в кроне. Тестовый ролик на проде сконвертировался меньше чем за секунду: ffmpeg только перепаковал контейнер.
Параллельно сменился бренд: «Л-ПАК» и «ОПТОПАК» стали «ОПТОПАК СЕВЕРО-ЗАПАД». Переименование по всей базе сделал скриптом: учёт HTML-экранирования OpenCart, бэкап перед запуском, защита длины полей, отчёт о заменах. В августе сменили и реквизиты на новое юрлицо - тоже миграцией с бэкапом и проверкой.
Портал обучения и аттестации
Летом встал вопрос обучения: водители, менеджеры, кладовщики, у каждого свой набор знаний. За десять дней на стыке июля и августа сделал внутренний портал на Laravel 13: сотруднику по должности открываются разделы и статьи, после статьи тест. Правильные ответы не попадают в HTML до отправки, проверка на сервере. Вопросы с несколькими правильными ответами, разбор попытки по образцу заказчика, статусы прохождения, персональные допуски от руководителя. Статьи редактируются в TipTap с таблицами и картинками, HTML чистится санитайзером на сервере. Миграцию перед выкладкой репетировал на копии боевой базы: конвертер перевёл старые статьи, вопросы и попытки целы.
Отчёт по трафику
Клиент спрашивал, откуда приходят люди и в какие разделы. Скрипт на Python собирает данные GA4 и Яндекс.Метрики, группирует адреса по типам - статьи, категории клейких лент, перчаток и так далее - и складывает помесячный Excel по расписанию. Вопрос закрыт без ещё одного дашборда.
Новая витрина на Mercurio
Сайт на PHP 7.2 и ionCube однажды упрётся в потолок. С сентября 2026 переношу магазин на Mercurio - свою платформу, на которой уже работает магазин офисной мебели. Laravel 13, PostgreSQL, Inertia и React с SSR, TypeScript. За неполный месяц: импорт каталога из базы OpenCart (7 856 позиций, 108 категорий), редиректы со старых адресов, посадочные фильтров, корзина с кратностью отгрузки, заказ по списку артикулов или файлом, реквизиты по ИНН, кабинет покупателя, отзывы с модерацией, прайс раздела в xlsx, ролики, PWA, e2e на Playwright.
Сейчас это демо на opto-pack.ru. Покупатели работают со старым сайтом, финальный прогон переноса и отключение от OpenCart впереди. Показательная мелочь: в шапке старого сайта стояло «2 400+» товаров при 7 856 в каталоге. В новой витрине число считается из базы.
Что вышло
За год у небольшого бизнеса появились пять инструментов, и ни один не потребовал останавливать магазин. Экран показателей, портал аттестации и отчёт по трафику живут рядом с сайтом и от его движка не зависят. Видеораздел, блоки категорий и ребрендинг - внутри OpenCart, модулями и миграциями, с бэкапом перед каждой выкладкой и отчётом клиенту после. Бизнес-метрик по продажам после этих работ у меня нет, и выдумывать их не буду.
Вывод
Легаси-сайт, который приносит деньги, сам по себе не повод для переписывания. Повод появляется, когда у клиента копятся задачи, которые на старой платформе дороже, чем рядом с ней. Пока копятся, закрываю их по одной: маленькими инструментами и аккуратными доработками. Когда новая витрина будет готова, переезд станет ещё одной такой задачей, а не прыжком.