Документация MevvAtelier

Ничто не уходит в производство, пока клиент не скажет «да».

MevvAtelier помещает цепочку производства под заказ внутрь WooCommerce: конфигуратор, считающий цену на вашем сервере, хранилище, из которого загруженные фотографии никогда не выходят, подписанную ссылку, которую клиент открывает без учётной записи для одобрения эскиза, четыре состояния заказа, движущиеся только вперёд, и очередь мастерской, показывающую, что просрочено. Это руководство охватывает установку, создаваемые вами страницы, где лежат цены, очередь, что видит клиент и что проверять, когда что-то не работает.

Что он делает

Товар, сделанный для одного человека, не укладывается в обычную страницу товара. Клиент должен прислать фотографию, вы должны изготовить вещь, а он должен увидеть её и согласиться прежде, чем вы потратите материал. Вручную это цепочка писем, и цепочка рвётся каждый раз в одном и том же месте: никто не может с уверенностью сказать, одобрил ли клиент именно ту версию, которую вы напечатали.

MevvAtelier делает эту цепочку частью заказа. Заказ несёт на себе фотографии, эскиз, одобрение и его отметку времени, а состояния, через которые он проходит, — настоящие статусы заказов WooCommerce, поэтому они видны в списке заказов, в отчётах и в фильтрах, которыми вы уже пользуетесь.

Когда его стоит применять
Вы продаёте то, что изготавливаете под каждый заказ из присланного клиентом, и хотите, чтобы его одобрение было записано до начала производства.
Это не плагин опций товара
Здесь нет матрицы вариаций и нет конструктора опций для каждого товара. Это одна цепочка с одной страницей конфигуратора для линейки, которую вы делаете под заказ.
Фотографии не являются вложениями медиатеки
Это приватные файлы со своим сроком хранения. Фотография клиента — не изображение товара, и обращаются с ней иначе.

Требования: WordPress 6.0 или новее, PHP 8.1 или новее и WooCommerce. Без WooCommerce плагин останавливает себя сам и сообщает об этом — у него нет собственной цепочки заказов, на которую можно опереться.

Настройки и единственное оставшееся ограничение

Всё, что магазин обычно меняет, живёт в Atölye → Ayarlar: как называется каждый пакет, сколько он стоит для одного–шести человек, цены двух дополнений, какой пакет получает набор красок бесплатно, какой выбран при открытии страницы и как долго хранятся фотографии.

Цены вы вводите в лирах, а плагин хранит их целыми в младших единицах. Сохранение — всё или ничего: если одно поле не читается, не записывается ни одно, и экран говорит, какое именно. Половина таблицы цен — это таблица, которая ломается ровно в тот момент, когда клиент оформляет заказ.

Переименовать пакет
Названия, идущие в комплекте, описывают напечатанные на 3D-принтере фигурки, потому что именно для такого магазина он и был построен. Впишите свои — «Маленькая подвеска», «Гравированная табличка», «Печать A4» — и именно это увидит клиент. Внутренний ключ рядом с каждым полем не меняется никогда, поэтому существующие заказы продолжают указывать на нужное.
Продавать меньше пяти
Оставьте название пакета пустым — он исчезнет из формы заказа, а сервер отклонит его, если кто-то всё равно отправит. Его цены остаются в таблице, так что включить его обратно позже — это одно слово, а не повторный ввод.
Какой пакет открывается выбранным
Решение коммерческое, а не техническое: средняя ступень якорит клиента вверх, самая дешёвая — вниз. Если выбранный вами позже отключат, форма откатится к первому ещё включённому пакету, вместо того чтобы открыться вовсе без цены.

ОСТАВШЕЕСЯ ОГРАНИЧЕНИЕ: мест под пакеты пять. Их можно переименовать, назначить им цены и отключить, но добавить шестое нельзя. Если вашей линейке нужно больше — напишите нам и укажите сколько: это следующее, что строится, и знание настоящего числа определяет его форму.

Установка

  1. Сначала установите и активируйте WooCommerce. Без него MevvAtelier отказывается запускаться.
  2. Установите MevvAtelier: загрузите zip через Плагины → Добавить новый или скопируйте каталог mevvatelier в /wp-content/plugins/.
  3. Активируйте его. При активации плагин регистрирует свои статусы заказов, создаёт каталог хранилища фотографий и планирует ежедневную задачу очистки.
  4. Создайте страницу и поместите на неё шорткод [mevvatelier]. Эта страница и есть ваша форма заказа.
  5. Оформите тестовый заказ через эту страницу, затем откройте 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 и плагина, номер заказа и то, какое из четырёх писем пришло, а какое нет. Фотографии клиента не присылайте.