Что он делает
Товар, сделанный для одного человека, не укладывается в обычную страницу товара. Клиент должен прислать фотографию, вы должны изготовить вещь, а он должен увидеть её и согласиться прежде, чем вы потратите материал. Вручную это цепочка писем, и цепочка рвётся каждый раз в одном и том же месте: никто не может с уверенностью сказать, одобрил ли клиент именно ту версию, которую вы напечатали.
MevvAtelier делает эту цепочку частью заказа. Заказ несёт на себе фотографии, эскиз, одобрение и его отметку времени, а состояния, через которые он проходит, — настоящие статусы заказов WooCommerce, поэтому они видны в списке заказов, в отчётах и в фильтрах, которыми вы уже пользуетесь.
- Когда его стоит применять
- Вы продаёте то, что изготавливаете под каждый заказ из присланного клиентом, и хотите, чтобы его одобрение было записано до начала производства.
- Это не плагин опций товара
- Здесь нет матрицы вариаций и нет конструктора опций для каждого товара. Это одна цепочка с одной страницей конфигуратора для линейки, которую вы делаете под заказ.
- Фотографии не являются вложениями медиатеки
- Это приватные файлы со своим сроком хранения. Фотография клиента — не изображение товара, и обращаются с ней иначе.
Требования: WordPress 6.0 или новее, PHP 8.1 или новее и WooCommerce. Без WooCommerce плагин останавливает себя сам и сообщает об этом — у него нет собственной цепочки заказов, на которую можно опереться.
Настройки и единственное оставшееся ограничение
Всё, что магазин обычно меняет, живёт в Atölye → Ayarlar: как называется каждый пакет, сколько он стоит для одного–шести человек, цены двух дополнений, какой пакет получает набор красок бесплатно, какой выбран при открытии страницы и как долго хранятся фотографии.
Цены вы вводите в лирах, а плагин хранит их целыми в младших единицах. Сохранение — всё или ничего: если одно поле не читается, не записывается ни одно, и экран говорит, какое именно. Половина таблицы цен — это таблица, которая ломается ровно в тот момент, когда клиент оформляет заказ.
- Переименовать пакет
- Названия, идущие в комплекте, описывают напечатанные на 3D-принтере фигурки, потому что именно для такого магазина он и был построен. Впишите свои — «Маленькая подвеска», «Гравированная табличка», «Печать A4» — и именно это увидит клиент. Внутренний ключ рядом с каждым полем не меняется никогда, поэтому существующие заказы продолжают указывать на нужное.
- Продавать меньше пяти
- Оставьте название пакета пустым — он исчезнет из формы заказа, а сервер отклонит его, если кто-то всё равно отправит. Его цены остаются в таблице, так что включить его обратно позже — это одно слово, а не повторный ввод.
- Какой пакет открывается выбранным
- Решение коммерческое, а не техническое: средняя ступень якорит клиента вверх, самая дешёвая — вниз. Если выбранный вами позже отключат, форма откатится к первому ещё включённому пакету, вместо того чтобы открыться вовсе без цены.
ОСТАВШЕЕСЯ ОГРАНИЧЕНИЕ: мест под пакеты пять. Их можно переименовать, назначить им цены и отключить, но добавить шестое нельзя. Если вашей линейке нужно больше — напишите нам и укажите сколько: это следующее, что строится, и знание настоящего числа определяет его форму.
Установка
- Сначала установите и активируйте WooCommerce. Без него MevvAtelier отказывается запускаться.
- Установите MevvAtelier: загрузите zip через Плагины → Добавить новый или скопируйте каталог
mevvatelierв/wp-content/plugins/. - Активируйте его. При активации плагин регистрирует свои статусы заказов, создаёт каталог хранилища фотографий и планирует ежедневную задачу очистки.
- Создайте страницу и поместите на неё шорткод
[mevvatelier]. Эта страница и есть ваша форма заказа. - Оформите тестовый заказ через эту страницу, затем откройте Atölye в меню администратора и проведите заказ от начала до конца. Сделайте это до того, как начнёте рекламировать страницу: полный круг занимает пять минут и это единственный способ увидеть письма, которые ваш магазин действительно отправляет.
Ссылки одобрения подписываются секретом, который создаётся при первом использовании и хранится в вашей собственной базе данных. Он никогда не покидает ваш сервер и не выводится из чего-либо, что есть у нас.
Три шорткода
- [mevvatelier]
- Форма заказа. Пять шагов: пакет, сколько людей в сцене, фотографии, данные клиента и поле согласия. Пока клиент выбирает, показывается текущая сумма, и эта сумма никогда не становится той, с которой записывается заказ, — см. «Где лежат цены».
- [mevvatelier_tanitim]
- Рекламная полоса для главной страницы: заголовок, короткий текст и кнопка к форме заказа. Принимает идентификатор вложения:
[mevvatelier_tanitim gorsel="123"]. - [mevvatelier_gorsel]
- Изображение из вашей медиатеки, выводимое с адаптивными размерами, которые WordPress уже создал:
[mevvatelier_gorsel id="123" size="large"]. Он существует, чтобы рекламная страница не печатала фотографию в 2000 пикселей в слот шириной 380 пикселей на телефоне.
Страница заказа отключает кэширование страницы для себя — на языке, который одинаково понимают LiteSpeed, WP Rocket и W3 Total Cache, — и вдобавок отправляет заголовки no-store. Закэшированная форма заказа отправляется с устаревшим токеном и молча падает, а клиенту это выглядит как форма, которая ничего не делает.
Где лежат цены
Цена заказа считается на вашем сервере только из выбора клиента. Сумма, присланная браузером, попросту игнорируется: спрашивать у браузера, сколько брать, — кратчайший путь к тому, чтобы у вас купили даром. Деньги хранятся целыми в младших единицах (курушах, центах), а не десятичной дробью, поэтому длинный заказ не может разойтись на одну единицу между счётом и заказом.
Вы правите их в Atölye → Ayarlar, в лирах, с запятой для курушей. Каждому пакету нужна цена для каждого поддерживаемого числа людей — от одного до шести. Вся таблица проверяется до того, как что-либо будет записано, и если одно поле не читается, экран говорит какое и не записывает ни одного: половина таблицы цен — это таблица, которая ломается ровно в тот момент, когда клиент оформляет заказ.
Всё это лежит в одной опции, mevvatelier_pricing, если вам удобнее раскатывать её через WP-CLI, а не кликать. Плагин перечитывает опцию после записи и отказывается сообщать об успехе, если прочитанное не совпало: магазину за постоянным объектным кэшем иначе можно сказать «сохранено», пока он продолжает продавать по старой цене.
wp eval '
$t = MevvAtelier_Settings::pricing_table();
$t["labels"]["orta"] = "Orta boy kolye ucu";
$t["packages"]["orta"][1] = MevvAtelier_Pricing::parse_money( "1.290,50" );
$t["default_package"] = "orta";
var_dump( MevvAtelier_Settings::save_pricing_table( $t ) );
'
Внутренние ключи пакетов: anahtarlik, orta, buyuk, anahtarlik_orta и uclu_set; ключи дополнений — paint_kit и rush. Именно на них ссылаются код и ваши существующие заказы, поэтому они не меняются никогда — имя, которое видит клиент, это отдельное поле, и его можно переписать когда угодно.
Очередь мастерской
Atölye появляется в меню администратора у всех, кто может редактировать заказы магазина. Он выводит открытые заказы, начиная с самых старых, и отмечает красным те, что вышли за обещанный срок: обычно двадцать четыре часа, шесть — для срочного заказа. Вопрос, на который он отвечает, — не «что открыто», а «что просрочено», и только этот вопрос стоит выносить на экран.
Оператор загружает эскиз из той же строки. Загрузка кладёт файл в хранилище, записывает контрольную сумму именно того, что было показано, переводит заказ в Müşteri onayında и отправляет письмо клиенту — одно действие, а не четыре вещи, которые надо помнить.
- Model bekliyor
wc-mevv-model. Фотографии получены, модель строится. Ссылка клиента работает и сообщает ему ровно это.- Müşteri onayında
wc-mevv-onay. Эскиз отправлен. Клиент может одобрить его или попросить правку — столько раз, сколько потребуется.- Baskıda
wc-mevv-baski. Одобрено и в производстве. Форма правок исчезла с экрана, и на этом этапе сервер тоже отклоняет запрос на правку, а не только экран.
Какое состояние может следовать за каким, записано списком разрешённых переходов, а не запрещённых. Шаг, о котором никто не подумал, по умолчанию отклоняется, а не разрешается молча, — в этом и разница между конечным автоматом и пожеланием.
Что видит клиент
Одна ссылка, отправленная письмом, действующая шестьдесят дней и не требующая учётной записи. Просить человека зарегистрироваться прежде, чем он сможет посмотреть собственный эскиз, — самый верный способ потерять одобрение, поэтому ссылка несёт свои полномочия сама: она подписана, называет один заказ и никакой другой, а подделанная не открывает ничего.
Страница показывает разный экран для каждого состояния и никогда не кэшируется: закэшированная страница одобрения показала бы эскиз одного клиента следующему посетителю. Ссылка одобрения встречается в каждом письме дважды — кнопкой и обычным текстом, — потому что некоторые почтовые клиенты кнопку не рисуют.
- Заказ принят — отправляется при оформлении заказа, вместе со ссылкой.
- Эскиз готов — отправляется, когда оператор его загружает. Именно это письмо просит принять решение.
- Одобрение записано — отправляется при одобрении и прямо говорит, что производство началось.
- Отправлено — отправляется, когда оператор отмечает заказ выполненным.
Письма проходят через собственный шаблон WooCommerce вашего магазина, поэтому выглядят как остальная ваша почта, а не как приделанное сбоку.
Фотографии
Загрузки попадают в каталог внутри вашей папки uploads, имя которого нельзя угадать, и защищены сразу четырьмя способами: правилом .htaccess, файлом web.config для IIS, файлом index.php и правами доступа, которые не дают прочитать их никому, кроме сайта. Четырьмя — потому что любой из них на чьём-нибудь сервере отсутствует или игнорируется.
Файл принимается по тому, чем являются его байты, а не по тому, что заявляет имя. Исполняемый файл, переименованный в .jpg, отклоняется на пороге: проверять расширение — значит проверять бумаги, которые принёс сам нападающий. Принимаются JPEG, PNG, WebP и HEIC. Имя при сохранении случайное; исходное имя файла клиента никогда не доходит до файловой системы, потому что «ayse-dogum-gunu.jpg» — это имя ребёнка и дата.
Каждая фотография и каждый эскиз отдаются через единственный шлюз. Вашу команду пропускает право на заказы WooCommerce, клиента — подписанная ссылка, сверенная с этим заказом. Ссылка, созданная для одного заказа, не откроет файл другого. Публичного URL файлам не выдают никогда.
- Срок хранения
- Ежедневная задача удаляет загрузки и эскизы завершённых заказов по истечении срока, который задаёте вы: из коробки — шестьдесят дней, хранится в опции
mevvatelier_retention_days. Заказ, его сумма и запись об одобрении остаются; фотография — нет. - Что покидает ваш сервер
- Из этого плагина — ничего. Из цепочки заказов к нам не приходит ни фотография, ни эскиз, ни заказ, ни телеметрия, ни лицензионный запрос. Хранилище — это каталог на вашем диске, а журнал одобрений — метаданные ваших собственных заказов.
Хранить фотографию ребёнка на сервере магазина бессрочно — это ответственность, а не возможность. Если ваше обещание клиентам о сроке хранения отличается от шестидесяти дней, измените опцию так, чтобы она совпадала со сказанным: число на вашей странице и число в плагине должны быть одним и тем же числом.
Одобрение, отмена и право отказа
По турецкому регламенту дистанционной торговли товар, изготовленный по индивидуальным требованиям потребителя, после изготовления не даёт права отказа (Mesafeli Sözleşmeler Yönetmeliği, ст. 15/1-b). MevvAtelier построен вокруг этого: клиенту сообщают об этом на экране одобрения, а момент его согласия записывается в заказ вместе с одобрением.
До одобрения ничего не изготовлено, поэтому отмена стоит вам одной модели и нисколько материала: отмените заказ в WooCommerce и верните деньги, как по любому другому. После одобрения форма правок исчезает и сервер отклоняет запрос на правку, потому что в этот момент материал уже задействован.
Это описание того, что записывает плагин, а не юридическая консультация. Ваш собственный договор дистанционной продажи и форма предварительного информирования всё равно должны говорить то же самое, и для этой части существует плагин MevvLegal.
Устранение неполадок
- Форма заказа отправляется, и ничего не происходит
- Почти всегда это закэшированная копия страницы. Форма несёт одноразовый токен, а закэшированная страница раздаёт устаревший, который молча отклоняется. Очистите страницу из кэша и убедитесь, что заголовки no-store плагина доходят до браузера; некоторые CDN срезают их на границе.
- Клиент говорит, что ссылка не работает
- Три причины, и страница говорит, какая именно. После шестидесяти дней срок истёк — отправьте новую. Если ссылку переписали из письма вручную, обычно не хватает одного символа. Если она называет другой заказ, её переслали из другого письма.
- В админке фотографии показываются как битые изображения
- Хранилище отдаётся напрямую вместо того, чтобы быть закрытым: проверьте, что в каталоге хранилища по-прежнему лежат
.htaccessиindex.phpи что хостинг не сбросил права. Если файлы доступны по URL — это более срочная половина проблемы. - Загрузка отклоняется, хотя это фотография
- Файл читается как нечто иное, чем JPEG, PNG, WebP или HEIC. Скриншоты с телефона и изображения, выгруженные дизайнерскими программами, часто таковыми не являются; пересохранение в JPEG решает вопрос. Проверяется не расширение.
- Заказы не выходят из «Model bekliyor»
- Само по себе их ничто не двигает — эскиз загружает оператор. Если у кого-то из вашей команды экран очереди пуст, проверьте право на редактирование заказов магазина; экран открывается по нему, а не по статусу администратора.
- Старые фотографии всё ещё на диске
- Задача очистки работает на WP-Cron, который срабатывает только когда кто-то заходит на сайт. В тихом магазине она ждёт трафика — или направьте на неё настоящий серверный cron. Проверьте также, что эти заказы действительно завершены; открытые заказы не очищаются никогда.
- Цены в форме не те, что я задал
- Ваша сохранённая таблица не прошла проверку, и плагин вернулся к значениям по умолчанию, вместо того чтобы продавать по неверной цене. Об этом есть уведомление администратору. Каждому пакету нужны все значения числа людей от одного до шести, и каждая сумма должна быть неотрицательным целым числом в младших единицах.
Когда будете писать нам, пришлите версии WordPress, WooCommerce, PHP и плагина, номер заказа и то, какое из четырёх писем пришло, а какое нет. Фотографии клиента не присылайте.