# Продажи

Раздел про то, как школа берёт деньги: что продаётся, на каких условиях,
что происходит после оплаты и какие письма при этом уходят.

## Продукт ≠ тариф

Две сущности, которые проще всего перепутать, и путаница дорого стоит.

**Продукт** — то, что получает ученик: доступ к курсу, файл, участие
в группе, услуга.

**Тариф** — условия продажи: набор продуктов, цена, срок доступа, правила.

Один продукт продаётся **несколькими тарифами** — это и есть тарифная сетка.
«Только курс» за 14 000, «курс + разбор» за 29 000, «всё вместе на год»
за 49 000: продукт внутри может быть один и тот же.

Раздел **Продукты** показывает продукты карточками, а тарифы — внутри них.
У продукта видно, продаётся ли он, сколько у него учеников и сколько оплачено
за 30 дней — по дате оплаты. У тарифа — цена, число продаж, состояние
(«активен», «до 8 августа», «закончился…», «выключен») и **на скольких
опубликованных страницах стоит его кнопка оплаты**: выключенный тариф
выключает кнопку «Купить» на всех этих страницах разом.

Продукт, который купить нельзя, обведён жёлтым и говорит почему — например,
«единственный тариф выключен»; кнопка «Включить тариф» стоит прямо в строке.
Над списком — отбор **Продаются · Без активных тарифов · Архив** и поиск
по названию продукта, курса и тарифа. Тариф заводится кнопкой **«+ Тариф»**
внутри продукта. Взгляд со стороны тарифов — переключатель **«Продукты · Тарифы»**
в строке раздела: там
комплект из нескольких продуктов виден один раз, а состояние тарифа —
то же, что в карточке продукта.

На телефоне цифры стоят под названием, действия — в меню «⋯», а тарифы
раскрываются кнопкой «3 тарифа ▾».

**Продукты в тариф добавляются поиском.** В поле «Что даёт этот тариф»
наберите часть названия — появятся до двадцати подходящих с видом продукта;
над списком — отбор по виду («Доступ к курсу», «Файл»…). Выбранное стоит
плашками, лишнее снимается крестиком. Так же — «Переход с другого тарифа»,
«Кому» в рассылке и условия сегментов: при тысяче продуктов выбор остаётся
выбором, а не простынёй галочек.

**Состав тарифа с оплатами правится.** Добавили в проданный тариф бонусный курс —
форма спросит, выдать ли его тем, кто уже купил, или только новым покупателям, и без
ответа не сохранит. «Выдать купившим» открывает добавленное всем, у кого доступ
по тарифу ещё идёт, на тот же срок; повтор правки второй раз не выдаёт. Убранное
у купивших **не отзывается** — за него заплачено; новые покупатели его не получат.
Правка состава проданного тарифа пишется в журнал: что добавили, что убрали,
кому выдали.

> **Продукт, входящий в живой тариф, убрать нельзя** — школа назовёт тариф,
> который останется продавать пустоту. Кнопка «Купить», после которой
> не приходит ничего, — худшее, что может случиться на продажах.

## Заказ ≠ покупка

**Заказ** — намерение и деньги: что человек собрался купить и на сколько.
**Покупка** — факт выданного доступа.

Их разделение — не педантизм. Заказ может быть оплачен, а доступ отозван;
доступ может быть выдан руками, без всякого заказа. Смешай их — и возврат
денег начнёт удалять доступ, а ручная выдача перестанет отличаться
от продажи.

## Приём оплаты

Кассы две: **ЮKassa** и **демо-касса**. Выбираются в «Настройки →
Интеграции → Приём платежей».

### ЮKassa

Нужны два значения из личного кабинета ЮKassa: **идентификатор магазина**
и **секретный ключ** («Настройки → Магазин», кнопка «Выпустить ключ»).

Ключ показывается там **один раз** — сохраните сразу. Из школы он обратно
не отдаётся, только маска: доступ к панели не должен означать доступ
к деньгам.

Школа проверяет ключ **настоящим запросом** к кассе сразу после сохранения.
Вписанный ключ от другого магазина обнаружится в ту же минуту, а не первой
продажей.

Возврат денег работает через ту же кассу — см. ниже.

### Демо-касса

Проводит заказ целиком, но **денег не берёт**. Она для проверки: пройти
путь покупателя от кнопки до открытого доступа, ничего не заплатив.

> **Оставлять её на живом сайте нельзя** — школа соберёт заказы, за которые
> никто не заплатил. Продукт предупреждает об этом на трёх экранах:
> в настройках, в списке заказов и на самой странице оплаты.

### Как устроен приём оплаты

Своя платёжная страница — чтобы настроить, что происходит после оплаты,
и не отдавать этот момент чужому сервису.

**Состояние платежа берётся у провайдера повторным запросом, а не из тела
уведомления.** Уведомление говорит «посмотри на этот платёж», а не «поверь
мне на слово»: подделать уведомление проще, чем ответ на прямой запрос.

**Повтор уведомления не выдаёт доступ дважды.** Провайдеры повторяют
уведомления — это норма, а не сбой, и продукт к этому готов с обеих сторон:
на приёме — уникальность по паре «провайдер + внешний номер», при создании
платежа — ключ идемпотентности.

**Оплата после отказа принимается.** Первая попытка не прошла — касса честно
ответила «отказ», и платёж помечен отказом. Человек ввёл карту ещё раз на той же
странице и заплатил: раз касса теперь говорит «оплачено», это оплачено, и доступ
открывается. Обратно, из оплаченного в отказ, платёж не уходит никогда.

**У каждого платежа — своя касса.** Школа может сменить кассу — скажем, демо
на ЮKassa, — и старые платежи от этого не ломаются: уведомление по платежу
проверяется правилами той кассы, где его провели (у каждой кассы свой адрес
уведомлений), возврат уходит туда же, а автоплатёж подписки списывает через
кассу, сохранившую карту, — токен карты действует только у неё. Незавершённый
платёж старой кассы покупателю не подсовывается: вернувшись к заказу, он платит
через текущую.

**Журнал уведомлений кассы.** Каждое уведомление — принятое, повтор, «касса ещё
не подтвердила», отказ, «платёж неизвестен», отклонённое по подписи — записывается
вместе с тем, что прислала касса. Подписи и ключи из заголовков в журнал
не попадают. По заказу исход виден строкой в ленте «Что происходило»: «Касса
прислала уведомление — оплата подтверждена». Так поддержка отвечает на вопрос
«приходило ли уведомление и что с ним стало», не заглядывая в журналы сервера.

**Уведомление кассы может не дойти** — сбой сети, перезапуск сервера в ту самую
секунду. Поэтому раз в 15 минут продукт сам переспрашивает кассу о платежах,
которые ждут подтверждения дольше 10 минут (за последние трое суток), и обрабатывает
их тем же путём, что и уведомление. Человек, заплативший без уведомления, получает
доступ в пределах четверти часа, а не после письма в поддержку.

## Что происходит после оплаты

Одной операцией, целиком или никак:

1. заказ помечается оплаченным;
2. создаются покупки — по одной на каждый продукт тарифа;
3. открывается доступ к курсам;
4. уходят письма.

Заказ, помеченный оплаченным без выданного доступа, — худшее из состояний:
человек заплатил и не учится, а поддержка узнаёт об этом от него.

## Промокоды

Фиксированная сумма или процент, срок действия, ограничение по тарифам,
общий предел применений и предел на человека, «только для первой покупки».

**Просроченный код не ломает покупку.** Человек пришёл покупать, а не
подбирать код: заказ создаётся по полной цене, а про код сказано отдельно.
Потерять заказ из-за истёкшей акции — худший из исходов.

**Отмена заказа возвращает применение кода в предел.** Иначе человек,
передумавший однажды, теряет право на акцию навсегда и читает это как
поломку школы.

### На что действует: выбор тарифов

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

Это не украшение списка: на трёх тарифах плоский ряд галочек читается,
на тридцати — нет, и галочка ставится наугад. Тариф, собранный из нескольких
продуктов, стоит в группе первого: второе место означало бы, что галочка
в одной группе не видна в другой.

Выбранные тарифы не исчезают из списка при поиске — иначе теряешь из вида то,
что уже отметил, и снимаешь выбор вслепую.

### Кому достаётся, срок и «Дополнительно»

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

**Сколько это стоит школе** считается тут же, до создания кода, отдельной карточкой
рядом с полями: скидка на заказ по самому дорогому из выбранных тарифов («39 000 →
33 150 ₽») и максимум скидок, если код применят столько раз, сколько разрешено.
Без предела применений сказано отдельно: код будет работать, пока его не отключат
руками.

**Личные коды** выдаёт шаг сценария «Выдать личный промокод»: код вида `L-7KQ2PX` работает только у того,
кому выдан, — чужой покупатель слышит «код выдан другому человеку»; одно применение, срок — числом дней.
В список «Промокоды» личные коды не попадают — сценарий выдаёт их сотнями; видно их в журнале человека
и в поле, куда шаг положил код.

## Частичная оплата

Человек платит часть и сразу получает часть курса; доплатит в срок — доступ станет
полным. Включается в форме тарифа, раздел **«Частичная оплата»**, — три вопроса подряд:

- **сумма части** — меньше цены тарифа; рядом видно, сколько это процентов от цены;
- **срок доступа по части** — числом, в днях или часах. Доплатил в срок — доступ
  продлевается до тарифного, и срок тарифа идёт с оплаты части; доплатил позже —
  с доплаты;
- **что открывается после части** — «Ничего», «Весь курс» или «Выбрать вручную»:
  дерево курса с галочками, хоть по одному уроку из каждого модуля. Галочка модуля
  с чертой — отмечена часть его уроков. Модуль, отмеченный целиком, откроет и уроки,
  добавленные в него позже.

На странице покупки появляется выбор **«Целиком» или «Частью»** — с суммой части,
остатком, сроком и тем, что откроется сразу. Выбравший «частью» платит часть и в
кабинете над программой курса видит плашку «Оплачена часть · 9 900 ₽ из 34 900 ₽»:
что открыто, до какого дня доплатить и кнопку **«Доплатить»** — остаток того же заказа,
а не новый заказ. Закрытые уроки подписаны «Откроется после доплаты». Та же плашка —
в заказе ученика.

За три дня до срока доплаты приходит письмо «Подходит срок платежа» со ссылкой
на заказ; при сроке короче трёх дней письма нет — срок покупатель видел, когда выбирал
«частью». **Не доплатил в срок** — открытое по части закрывается, внесённое остаётся
оплатой части. Доплатить можно и после срока: курс откроется целиком.

**Условия замерзают в заказе.** Поправили часть тарифа — у тех, кто уже платил частью,
открыто обещанное при покупке. Новую цену или состав тарифа правка сверяет с частью:
часть не меньше цены — это уже полная оплата, и сохранение откажет словами.

Часть можно отметить и вручную: «Отметить оплату вручную» в заказе, выбранном «частью»,
с суммой не меньше части откроет то же, что оплата через кассу. Шапка карточки такого
заказа говорит «Открыта часть · доплатить до 3 октября» или «Часть не доплачена».

Частичная оплата открывает только **курсы**: файл, участие в группе и услуга выдаются
после доплаты — половину файла не выдашь. Партнёру комиссия начисляется, когда заказ
оплачен целиком, — со всей суммы.

Агенту школы: «включи частичную оплату тарифа „Базовый“: 9 900 ₽, 14 дней, открыть
вводный модуль» — он зовёт `set_offer_partial_payment`, и изменение условий ждёт
вашего «да»: покупатели видят их сразу.

### Чек при частичной оплате

Чек выбивается ровно на сумму платежа. Часть, открывающая уроки, — признак «частичный
расчёт и кредит», доплата после неё — «оплата кредита». Часть, которая ничего
не открывает («Ничего»), — «частичная предоплата», а доплата после неё — «полный
расчёт» на остаток: чек зачёта предоплаты продукт пока не выбивает. Если бухгалтерия
его требует, выбирайте «Весь курс» или уроки — тогда зачёт не нужен.

## Рассрочка

Школа даёт рассрочку сама, без банка: деньги приходят частями по графику, и каждый
платёж открывает свою часть курса. Включается в форме тарифа, раздел **«Внутренняя
рассрочка»**:

- **число платежей и шаг между ними** — числами; шаг — в днях или часах. **Сумма
  платежа считается сама**: поровну с округлением вверх до рубля, копейки от деления —
  последнему платежу (34 900 ₽ на три — 11 634, 11 634 и 11 632);
- **«Без первого платежа»** — первый платёж через шаг, а то, что он открывает,
  открывается сразу, в долг до его срока;
- **график и доступ по платежам** — таблица с датами и «что открывает»; ниже вкладки
  «1-й», «2-й», «3-й» и то же дерево курса, что у частичной оплаты. Урок, отданный
  одному платежу, помечен его номером и заново не выбирается: у урока одна дата
  открытия. **Всё нераспределённое открывает последний платёж**;
- **если платёж просрочен** — «Закрыть весь курс до оплаты» (с запасом суток после
  срока), «Оставить открытым то, что уже оплачено» или «Ничего не закрывать, только
  напоминать» — тогда уроки платежа открываются в его дату, оплачен он или нет;
- **напоминания** — за 3 дня до даты, в день платежа, на следующий день после
  просрочки; каждое можно снять. Тексты — «Настройки → Письма продукта»: «Подходит
  срок платежа по рассрочке», «Сегодня платёж по рассрочке», «Платёж по рассрочке
  просрочен». Письмо о просрочке говорит, что с доступом, — по выбору школы.

На странице покупки появляется **«В рассрочку — 3 платежа: 11 634 ₽ сейчас, дальше
по 11 634 ₽ раз в 30 дней»**. Сроки остальных платежей считаются от оплаты первого:
заказ мог неделю ждать оплаты. В кабинете над программой курса — плашка «Рассрочка ·
оплачено 1 из 3» со следующим платежом и кнопкой «Оплатить … раньше срока», в заказе —
«График платежей» с галочками. Тот же график — в карточке заказа у школы, а шапка
говорит «Рассрочка · оплачено 1 из 3 · следующий платёж 19 октября».

Платёж можно отметить вручную — «Отметить оплату вручную»: строки графика оплачиваются
по накопленной сумме. Последний платёж делает доступ полным тем же доступом — без второй
покупки; доплатил в срок — срок тарифа идёт с первого платежа.

**Внесённая часть заказа сама доступа не даёт** — открывает частичная оплата
по условиям тарифа (выше) и рассрочка по своему плану. Выдать всё за первый платёж
значило бы подарить курс тому, кто заплатил четверть.

Агенту школы: «сделай рассрочку тарифа „Базовый“ на 3 платежа раз в 30 дней, первый
открывает вводный модуль» — он зовёт `set_offer_installments`, и изменение ждёт вашего «да».
### Рассрочка «в моменте» из заказа

Менеджер разговаривает с клиентом и собирает рассрочку прямо в карточке неоплаченного
заказа: **«Рассрочка по заказу»** под «Отметить оплату вручную». В окне — число платежей,
шаг (числом, в днях или часах) и первый платёж (пусто — поровну); ниже график датами,
суммы и что открывает каждый платёж: модули курсов делятся поровну, лишние — первым
платежам, последний открывает всё. Если у тарифа есть своя рассрочка на столько же
платежей — «что открывает», просрочка и напоминания берутся у неё.

**«Отправить ссылку на оплату»** сохраняет график и шлёт покупателю письмо «Рассрочка
по заказу» — на почту и в мессенджер, откуда он пришёл, — с графиком и кнопкой «Оплатить
первый платёж». **«Сохранить в заказ»** — только график, ссылку отправят позже. Дальше
всё как у рассрочки тарифа: график в заказе у школы и у ученика, платёж — ближайшая строка.

Собирают **до первой оплаты**: по заказу, где уже платили, окно не показывается, а сервер
откажет словами; у заказа «частью» свой график. Собрать может тот, кто отмечает оплаты
вручную (владелец, менеджер, администратор с правом); сборка — в журнале заказа.
Агенту: «сделай рассрочку по заказу 2088 на 4 платежа раз в 14 дней и отправь ссылку» —
`set_order_installments`, шаг ждёт вашего «да».

## Баланс ученика

Деньги школы на счету человека: начислено за приведённого друга, компенсация за сбой,
возврат на баланс. В карточке человека, вкладка **«Деньги»**, блок **«Баланс»**: сумма,
**«Начислить»** и **«Списать»**, ниже лента движений — что, когда и кто. Каждое движение
требует причины (готовые из списка или своя) и записывается с именем сотрудника; начислять
и списывать может тот, кто отмечает оплаты вручную. О начислении человеку уходит письмо
«Начислено на баланс».

**Спишется при следующей покупке** — сам, без галочки: заказ, оплачиваемый целиком, сначала
берёт с баланса, а кассе остаётся остаток. Хватило баланса — заказ оплачен сразу и доступ
открыт. Платёж с баланса — обычная строка платежей заказа («с баланса ученика»), чек по нему
не выбивается. Частью и в рассрочку баланс не тратится — у таких заказов свой график. На
странице покупки до нажатия сказано, сколько спишется с баланса и сколько останется.

Возврат оплаченного с баланса возвращается **на баланс** — письмо «Возврат на баланс»
не обещает денег на карте. В кабинете ученика над покупками — «Мои оплаты»: графики
рассрочки с «Оплатить … раньше» и баланс с последним движением.

Агенту: «начисли Марии 1 200 ₽ за приведённого друга» — `adjust_balance`, шаг ждёт вашего
«да»; баланс и движения — в ответе `person_money`.

## Подписки с автоплатежом

Тариф можно продавать подпиской: человек платит за период, касса списывает сама, пока он
не отменит автоплатёж. Включается в форме тарифа — **«Подписка с автоплатежом»**:

- **период** — числом и единицей: 1 месяц, 2 недели, 10 дней. Месяц календарный:
  подписка от 31 января продлевается 28 февраля;
- **цена периода** — это цена тарифа, второй цены у подписки нет. Подорожание тарифа
  тех, кто уже подписан, не касается: у них цена на день покупки;
- **автоплатёж включён по умолчанию** — снимите галочку, и продлевать период люди
  будут сами, кнопкой в кабинете;
- **пробный период** — N дней за X ₽, один раз на человека. Пробный за 0 ₽ проходит
  без карты: автоплатежа нет, пока человек не оплатит период сам.

Частичная оплата и рассрочка у подписки не включаются — у неё свой график. Срок доступа
тарифа для подписки не действует: доступ идёт до конца оплаченного периода и ещё сутки,
чтобы списание в срок не закрыло урок на час.

**На странице покупки** — цена за период («1 490 ₽ в месяц»), пробный период и прямым
текстом до кнопки: карта сохранится для автоплатежа, отменить его можно в кабинете в любой
момент. Кнопка — «Попробовать 7 дней за 1 ₽» или «Оформить подписку». Вторую подписку на
тот же тариф оформить нельзя; баланс подписку не оплачивает — первый платёж сохраняет карту.
Промокод действует на первый период; к пробному — нет.

**В кабинете**, в «Моих покупках», — карточка подписки: «Активна», цена, «Следующее
списание: 3 октября», карта («Карта ···· 4417») и обычная кнопка **«Отменить автоплатёж»** —
без письма в поддержку. Отменил — больше ничего не спишется, доступ остаётся до конца
оплаченного периода, приходит письмо «Автоплатёж отменён». Включить обратно — там же.
В «Доступах» курс подписки подписан «по подписке · продлится 26 сентября», а не тревожным
«до … · 8 дней»: продлит касса.

**Каждый период — свой заказ**: чек, возврат и «сколько принёс» идут обычным путём, письмо
«Заказ оплачен» — как у всех. Списания идут раз в час по расписанию. Возврат по заказу
подписки с отзывом доступа отменяет подписку: автоплатёж больше не спишет за доступ, которого
нет. Возврат без отзыва доступа — подписка идёт дальше.

**Списание не прошло** — подписка «Платёж не прошёл», доступ сохраняется, повтор — в
ближайшие 12:00 по часам школы (не раньше чем через шесть часов). Человеку — письмо
с причиной словами банка; в кабинете — красная карточка «Списание 1 490 ₽ не прошло»
с **«Оплатить сейчас»** и **«Сменить карту»**: оплата новой картой её и сохранит. Третья
неудача подряд — подписка закончилась, доступ по ней закрыт, письмо «Подписка закончилась»
с кнопкой «Оформить снова». Курс, купленный отдельно, при этом не трогается.

**В карточке человека**, вкладка «Деньги», — блок «Подписки»: до какого дня оплачено,
следующее списание, карта и что ответила касса в последний раз; закончившиеся тоже видны.
Автоплатёж за человека сотрудник не отменяет — только «Войти под пользователем», и в
журнале видно, кто нажал на самом деле. Письмо «Доступ заканчивается» подписчику
с автоплатежом не уходит: касса продлит сама.

Списывать без человека умеют ЮKassa и демо-касса (у демо карта — «···· 4242»). У ЮKassa
автоплатежи включает их поддержка по заявке магазина — без этого касса откажет в сохранении
карты, и отказ будет виден на кнопке покупки.

Агенту: «сделай тариф „Клуб“ подпиской 1 490 ₽ в месяц с пробной неделей за 1 ₽» —
`set_offer_subscription`, шаг ждёт вашего «да»; подписки человека — в ответе `person_money`.
Отменить автоплатёж за человека агент **не может**: это делает сам человек в кабинете.

## Воронки и этапы

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

Настраивают их администратор и **руководитель отдела продаж** (ступень роли «менеджер», см. «Права»):
менеджер ведёт сделки на доске, а устройство доски — одно на весь отдел. Заводятся в «Настройках → Воронки
и этапы»: слева список воронок, справа этапы
выбранной — таблицей «этап · вид · норма стояния · сделок». Порядок этапов меняется
перетаскиванием за ручку ⠿, правки сохраняются одной кнопкой «Сохранить». Если
на этапе есть сделки, простоявшие дольше нормы, у нормы написано «N стоят дольше».
Этап со сделками не удаляется: вместо «удалить всё равно» школа переносит сделки
на другой обычный этап — кнопкой «Перенести N сделок» — и после этого удаляет.
Сами сделки продукт не переносит: по ним считается выручка и работа менеджеров.
На «успех» пачкой не переносят (туда ставит оплата), на «отказ» — только по одной,
с причиной. У этапа меняются название, **норма стояния** в днях и вид:

| Вид этапа | Что значит |
|---|---|
| обычный | сделка стоит и ждёт работы менеджера |
| купили | двигает оплата, а не менеджер |
| отказ | спрашивает причину из списка школы |

**«Купили» и «отказ» — по одному на воронку.** Два этапа «купили» означают два
разных ответа на вопрос «сколько продали», и оба будут неправдой.

На доске сделок воронка выбирается в панели сверху; выбор остаётся в адресе,
поэтому ссылку на воронку можно отправить и сохранить в закладке. Если воронка
в ссылке уже удалена, откроется первая — это не отказ раздела.

**Удаление отказывает словами.** Этап со сделками и воронка со сделками не
удаляются: сначала переведите сделки туда, где им место. Последнюю воронку
удалить нельзя — заводить сделки станет некуда.

### Как устроен экран

Каждая воронка — отдельная таблица: **этап · сделок сейчас · норма стояния ·
вид**. Название и настройки этапа меняются кнопкой «Изменить», воронка
переименовывается кнопкой «Переименовать» — полей ввода в каждой строке нет,
чтобы таблица читалась, а не заполнялась.

Если удалить нельзя, **это видно до нажатия**: вместо кнопки «Удалить» в строке
стоит причина — «на нём сделки» у этапа, «последняя воронка» или число сделок
у воронки. Отказ сервера словами при этом остаётся: удаление из другого окна
или по API получит тот же ответ.

## Сделки: доска до оплаты

Заказ появляется, когда человек нажал «купить». Сделка — про то, что **до**
этого: переписку, звонок, обещание подумать. Раздел «Сделки» — доска
по этапам: колонка на этап, карточка на человека.

**Сумма сделки подписана как ожидаемая**, пока заказа нет: это намерение,
а не деньги. Появился заказ — сумма и оплата приходят из него, и «на глазок»
исчезает.

### Карточка переносится двумя путями

Карточку можно **перетащить** в другую колонку — колонка подсвечивается, пока
карточка в воздухе. Или перевести **списком** «Перевести…» на самой карточке.

Оба пути делают одно и то же и существуют оба намеренно: перетаскивание
не работает ни с клавиатуры, ни на телефоне, а список работает везде.

### Два этапа ведут себя иначе

| Этап | Правило |
|---|---|
| «купили» | закрывается **оплатой**, а не рукой — ни перетаскиванием, ни списком |
| «отказ» | требует **причину из списка школы**, и спрашивается она до перевода |

Первое — чтобы воронка и деньги не разошлись: иначе отчёт по конверсии считает
намерения менеджеров, а не выручку. Второе — чтобы воронка объясняла, почему
не покупают: свободный текст через год даёт четыреста уникальных причин
и ни одного отчёта. Причину спрашиваем **до** перевода — после него её уже
никто не впишет.

### Норма стояния

У этапа есть норма в днях. «9 стоят дольше двух дней» — то, что превращает
доску из картинки в инструмент: без нормы забытая сделка выглядит работающей
и обнаруживается через месяц по отсутствию денег. Просроченные карточки
обведены, и их число стоит в колонке и в строке над доской.

**Воронки отдельными сущностями и правка этапов** — в работе: сейчас этапы
общие для школы.

## Задачи менеджеров

Раздел **«Задачи»** — очередь менеджера по схемам РОПа: кому звонить сегодня, откуда задача
пришла и сколько касаний уже было. Задачи ставит шаг сценария **«Задача менеджеру»** — например,
после «заказ без оплаты 30 минут» или «ответил на вопрос после эфира».

**Очередь.** Вкладки — «На сегодня», «Новые», «В работе», «Отложенные», «Завершённые».
Первая — «На сегодня»: просроченные красные и всегда наверху. Над списком — числа: в «Моих
задачах» это сколько просрочено у вас, ближайший срок, оплат за неделю и сколько ждут в общей
очереди; в сводке отдела (у владельца, администратора и РОПа) — **«В очереди»** с числом
менеджеров, **«Просрочено»** с возрастом самой старой, **«Без менеджера»** и **«Закрыто сегодня»**
с оплатами, а под ними — просрочка по менеджерам строками: у кого сколько в работе и сколько
зависло. Владелец, открывая раздел, спрашивает не «что мне делать», а «где встало». Строка
говорит, откуда задача пришла — «Заказ №2088 · 34 900 ₽ · не оплачен», «Нулевой заказ · тариф
«Про»» или условие входа словами, — и сколько касаний было: «3 из 5».

**Кому.** Задача уходит персональному менеджеру человека. Персонального нет — она встаёт
в общую очередь, и её берёт тот, кто нажал **«Взять следующую из очереди»**; взявший становится
персональным менеджером человека. Двое, нажавшие разом, получают разные задачи. Владелец,
администратор и **руководитель отдела продаж** видят всех менеджеров и общую очередь — выбором над
списком — и могут нажать исход в чужой задаче. У них раздел открывается **сводкой команды** — «Задачи
менеджеров», все очереди сразу, — а «Мои задачи» — только если задачи стоят на них самих: владельцу продавать
некому (правка 20 сентября). Выбор над списком вкладки помнят. Руководитель отдела продаж — подгалочка под ролью
«менеджер» во вкладке «Права» карточки; ставит её владелец или администратор. Назначить или снять
персонального менеджера руками — шаг сценария или массовое действие «Назначить персонального менеджера»,
агент — `set_personal_manager`.

**Карточка задачи.** Кнопки — не список статусов, а исходы разговора, и набор зависит от шага:
«Вышел на связь», «Не вышел на связь», «Ещё касание» — когда попытки по схеме кончились; после
ответа — «Создаю заказ» и «Завершить — есть оплата»; всегда — «Отложить», «Отменён» и «Нет, это
дубль». Следующий срок система ставит сама: после недозвона — по графику схемы, после ответа —
через «сроки касаний после ответа». Ночью сроки не ставятся — переносятся на 9:00 по часам
школы. Последний недозвон закрывает задачу — «не дозвонились». «Отменён» требует причины из
списка схемы или своей, «Отложить» — дня и времени либо «через» числом. **«Вернуться»** в истории
касаний возвращает задачу на шаг назад, если исход нажали случайно, — в течение суток. Заметка
менеджера сохраняется сама.

Оплата по заказу задачи закрывает её сама — «оплата пришла»: менеджер не звонит тому, кто уже
заплатил. Другой менеджер взял задачу раньше — исход не ложится, и карточка говорит, кто взял.

**Статистика менеджеров** — кнопка «Статистика» рядом с выбором менеджеров, у руководителя отдела продаж,
администратора и владельца. За период (день, неделя, месяц или свой — две даты) по команде и по каждому
менеджеру: касаний и доля дозвонов, закрыто задач и сколько с оплатой, конверсия (оплаты из закрытых без
дублей), время до первого касания — среднее и рядом медиана («половина — быстрее 50 минут»); «в работе»
и «просрочено» — сейчас, просрочка жёлтым числом внутри «в работе», а не отдельной колонкой: она всегда
подмножество. Ниже — частые причины отмены с итогом и «что считается касанием». «Выгрузить в CSV» — те же
числа за тот же период. Агент отвечает теми же числами: `manager_stats`.

> **Меньше пяти закрытых задач — конверсию не считаем.** Ни в таблице, ни в выгрузке, ни у агента:
> вместо процента стоят слова «мало данных», строка серая, а над таблицей сказано, у скольких людей
> так получилось. Одна оплата из двух закрытых — это «50 %», которые встанут рядом с честными 30 %
> и решат разговор о человеке.

**Среднее и медиана рядом.** Среднее одно врёт в обе стороны: одна задача, взятая через трое суток,
поднимает «до первого касания» так, что число перестаёт описывать хоть кого-то.

**На телефоне** таблица разворачивается в карточки: имя, три главных числа строкой — касания, закрыто
и конверсия, — под ними «в работе» с жёлтой просрочкой. Период — обычным списком, без календарной сетки;
«Выгрузить в CSV» внизу, под карточками.

**Строка менеджера открывает карточку** поверх таблицы — и закрывается в неё же, период не сбрасывается.
В карточке три ответа на одном экране: **сколько** (касаний, закрыто, оплат, просрочено), **когда** — касания
по дням недели, и **по какой причине сорвалось** — частые причины отмены именно у этого человека. Оттуда же
один шаг в его очередь. Если закрытых меньше пяти, карточка говорит об этом прямо: конверсия по ним ничего
не значит — одна оплата из двух даёт 50 %.

**Быстрая связь** — «Позвонить» (на телефоне менеджера — крупная кнопка внизу экрана) и **«Написать
в Telegram / MAX / ВКонтакте» через бот школы**: поле сообщения открывается на месте, сообщение уходит
от бота и ложится в чат человека в «Обращениях» — ответ человека придёт туда же, а в истории задачи
появится строка «Написано через бот школы». Открытого обращения нет — сообщение откроет новое. Такие
кнопки есть там, где бот школы подключён и человек привязан; где нет — ссылка написать со своего аккаунта
(ответ придёт вам). Почта — своим письмом. Телефона нет — так и сказано: звонить некуда.

**Шаг сценария «Задача менеджеру»** — одна схема вместо двух зашитых: кому (персональному, иначе
в очередь, или всегда в очередь), название у менеджера, условие входа словами, график недозвонов
строкой чисел (3 → 8 → 12 ч — каждое число правится на месте, попытка добавляется и убирается),
первое касание, касаний по схеме, сколько «ещё касаний» может добавить менеджер, срок после ответа
и причины отмены. Начать можно со схем РОПа — «Горячий заказ» и «Тёплый лид после эфира».
Задача копирует схему при создании: правка шага уже поставленные задачи не меняет. Открытая задача
с тем же названием у человека уже есть — вторая не ставится.

Касание — любая попытка связаться, дозвонился менеджер или нет. Звонят вручную, с телефона:
телефонии в продукте нет. Рабочие часы для сроков — с 9:00 до 21:00 по часам школы.

Агенту: «что у меня на сегодня?» — `list_manager_tasks`; «отложи задачу Артёма до завтра, 10:00»,
«отмени — купил у других» — `update_manager_task`. Схему шага агент не правит — она в редакторе
сценария.

## Страницы школы

Раздел **«Страницы»** — продающие страницы школы. В списке у каждой видно,
что она продаёт и продаёт ли на самом деле:

- **«Что продаёт»** — продукт тарифов на странице и сколько их; у страницы
  без тарифа — «Заявки через форму»;
- **«Состояние»** — «Опубликована», «Черновик» или **«Открыта, но
  не продаёт»**: страница опубликована, а тариф на ней закончился, выключен,
  ещё не в продаже или удалён. Посетитель видит страницу и не может купить,
  поэтому строка выделена, а причина написана рядом;
- **«Заказы за 30 дней»** — сколько заказов по тарифам страницы и сколько
  по ним оплачено.

> **Заходы на страницу продукт пока не считает**, и заказ не помнит,
> с какой страницы пришёл. Поэтому заказы в списке — по тарифам страницы:
> если один тариф стоит на двух страницах, его заказы видны у обеих.

**«Продлить»** стоит у страницы, тариф которой закончился: окно спрашивает,
до какого дня продавать тариф. Продлевается продажа тарифа — он оживает
на всех страницах, где стоит. День считается по часам школы, задним числом
продлить нельзя. У выключенного тарифа и тарифа, продажи которого ещё
не начались, в строке ссылка «К тарифам». Обе кнопки видит тот, кому
открыты продукты и тарифы.

**Блок «Программа курса»** показывает модули выбранного курса и число уроков
в каждом. Программа подставляется из курса при каждом показе: добавили урок —
страница обновилась. Показываются только опубликованные уроки; модуль,
в котором их пока нет, на странице не виден.

На телефоне внизу страницы закреплена полоса «цена · Купить» — по первой
кнопке оплаты, тариф которой продаётся.

### Редактор страницы

Страница и виджет собираются **на том же холсте, что урок.** Текст правится
прямо на холсте; новый блок ставится из **каталога слева** — по разделам:
обложка, заголовок, текст, изображения, разметка, продающие, форма — или
набором «/» на холсте. Блоки перетаскиваются, дублируются и удаляются
кнопками у блока.

Нетекстовые блоки — тарифы, программа курса, форма, обложка — на холсте
выглядят так, как их увидит посетитель, с теми же ценами. Нажать «Купить»
или отправить форму на холсте нельзя: нажатие выделяет блок.

Выбранный блок настраивается **в панели справа**: поля блока, тариф или курс —
поиском, картинка — из библиотеки файлов, у формы — какие поля спрашивать,
что делать после отправки и какой тег поставить. Там же **оформление блока** —
как в уроке.

**Сохранение само:** правка уходит через мгновение, в шапке — «Сохраняем…»
и «Сохранено». Черновика правок у страницы нет: у опубликованной страницы
правка сразу видна посетителям. Убрать форму редактор спросит — уже пришедшие
заявки останутся в разделе «Заявки».

Во вкладке **«Настройки»** — название, адрес и **заголовок в поиске
и в мессенджере**. Пустой заголовок — в поиске и в превью ссылки будет
название страницы. Там же ссылка на страницу, а у виджета — код вставки
для чужого сайта. «Опубликовать» и «Снять с публикации» — в шапке.

## Виджет на чужом сайте

Виджет — это форма школы, которую вставляют на сторонний сайт. Редактор виджета
разложен вкладками редактора виджета, как в макете: **«Форма»** — холст и поля,
**«После отправки»** — записать человека или открыть оплату по тарифу и какой тег
поставить, **«Оформление»** — стили с предпросмотром на фоне сайта, **«Код»** — CSS, HTML и JS виджета, **«Код для вставки»** — две строки с кнопкой «Скопировать», **«Домены»** —
разрешённые сайты с показами и отказами, **«Настройки»** — название и адрес.
В строке виджета — «Работает · N доменов» и «Получить код»; справа от вкладок —
«Проблем нет» или число проблем формы.

```html
<div data-school-widget="webinar-flex"></div>
<script src="https://ваша-школа.ru/w/webinar-flex.js" async></script>
```

**Как показать форму** выбирается на той же вкладке, и способ записан в самих
строках кода, а не в настройках: один виджет можно поставить на разные сайты
по-разному.

- **В нужном месте** — форма встаёт там, где стоит код, и растёт по высоте вместе
  с содержимым.
- **По нажатию** — форма открывается поверх страницы от кнопки сайта. Кнопку можно
  заменить своей: форму открывает любой элемент с атрибутом `data-school-widget-open`.
  Закрывается крестиком, клавишей Esc и нажатием мимо.
- **Полоса снизу** — прилипает к нижнему краю поверх страницы и закрывается крестиком.

**Цели и события** — своей вкладкой. Кадр сообщает странице сайта, что произошло,
а цель вызывает счётчик сайта — в том же визите и с тем же источником, что привёл
человека. Готовый фрагмент для Яндекс Метрики или Google Analytics 4 — с адресом
виджета, номером счётчика и именем цели — ставится на страницу рядом с кодом
виджета. В настройках виджета номер счётчика не хранится: внутри кадра цель
засчиталась бы отдельным визитом «с сайта партнёра», и цифры разошлись бы
с рекламой. События на странице: `open`, `submit`, `success`, `error`, `resize` —
через `LMSWidget.on("success", …)` или событием `lms:widget` на `document`.
**Остановить отправку со страницы сайта** можно своей проверкой:
`LMSWidget.on("submit", function (e) { if (!siteCheck()) e.preventDefault(); })` или `e.preventDefault()`
у события `lms:widget` с `event: "submit"`. Кадр ждёт ответа страницы полсекунды и без ответа
отправляет — так форма работает и там, где загрузчик старый или страница молчит. Причину остановки
показывает сама страница сайта. Версия событийного интерфейса — `LMSWidget.version` («2»): имена
событий и поля `e.detail` в пределах версии не меняются.

**Оформление по закреплённым классам.** Свой CSS-блок в виджете оформляет форму
по именам, которые не меняются при обновлениях: `lms-widget` — страница виджета,
`lms-widget__form` — форма, `__title` и `__note` — заголовок и пояснение, `__field`,
`__label`, `__input`, `__hint` — поле, подпись, ввод и подсказка, `__consents`
и `__consent` — согласия, `__submit` — кнопка, `__thanks` — сообщение после отправки.
Цвет, шрифт и отступы — пожалуйста. **Скрыть согласия** и ссылки на документы школы
(display: none, visibility: hidden, opacity: 0, нулевая высота или размер шрифта)
и **сделать кнопку или поля ниже 44 пикселей** стили не могут: такой виджет
не сохранится, и отказ назовёт правило.

**Вкладка «Код»** — CSS, HTML и JS виджета в одном месте, и начинается она с границы:
код выполняется **в браузере посетителя чужого сайта**, внутри кадра. Может — оформление,
поведение формы, свои события для аналитики сайта и чтение того, что человек ввёл в эту
форму. Не может — получить данные другого ученика (кадр на чужом сайте открывается без
входа в школу), заменить проверку сервера, отметить согласия за посетителя и дотянуться
до страницы сайта. Вкладка правит первый блок CSS, HTML или скрипта в виджете, а нет
такого — заводит его; остальные блоки кода остаются на холсте.

В скрипте виджета есть объект `widget`:

| Вызов | Что делает |
|---|---|
| `widget.on("field:blur", fn)` | человек ушёл с поля; в `fn` — `name`, `kind`, `value`, `digits` |
| `widget.on("submit", fn)`, `"submit:success"`, `"submit:error"` | отправка, заявка принята, не принята; в `fn` — `widgetId` |
| `widget.setFieldError("phone", "Номер из 11 цифр")` | ошибка под полем: пока стоит, форма не отправляется; правка поля или пустой текст снимает |
| `widget.setText(".lms-widget__note", "Осталось мест: 12")` | текст в элементе формы по классу; согласия менять нельзя |
| `widget.emitToPage("lms:signup", { plan: "pro" })` | своё событие на странице сайта: `document.addEventListener("lms:signup", …)` или `LMSWidget.on("lms:signup", …)` |
| `widget.formValues()` | что человек ввёл в эту форму |
| `widget.api.get("/offers/" + id)` | открытый метод API школы — тариф этого виджета или вебинар; закрытый отказывает |

В данных своего события уходят только строки, числа и да/нет — не больше 20 полей,
и к ним добавляется `widget` — адрес виджета. **Скрипт, который обращается к согласиям**
(классом `lms-widget__consent`, выбором галочек или записью `.checked =`), не сохраняется,
а галочку, поставленную скриптом, форма не принимает: её ставит посетитель — мышью,
пальцем, клавишей или экранным диктором. Стили внутри HTML-блока проверяются так же, как CSS.
Ошибка, которую поставил код, выводится под полем с классом `lms-widget__error`.

Код правит тот, кому владелец открыл право «Код» лично; остальные видят код и границу,
но не меняют. Открытый напрямую на домене школы — кнопкой «Посмотреть» — виджет работает
с вашим входом, как код на страницах школы: поэтому право на код и личное.
Агент школы код виджета не пишет — это право человека.

**Открытые виджету методы API.** Код виджета ходит к API школы через `widget.api.get` и только
за тем, что можно показать любому посетителю: `/offers/:id` — тариф этого виджета (название,
цена, старая цена, валюта, продаётся ли сейчас) и `/webinars/:slug` — вебинар по адресу
страницы записи (название, ближайший эфир, идёт ли сейчас). Список пополняется решением,
а не по умолчанию: закрыто всё, что не открыто явно. Вызов закрытого метода, адрес метода
в переменной и прямое обращение к `/api/…` ловятся **при сохранении**: отказ называет строку
и метод, а рядом — «Открыть «После отправки»», где условие настраивается на сервере. Пока
вызов на месте, правка не сохраняется. Запрос к открытому методу идёт без куки: ответ одинаков
для любого посетителя.

**Внешние адреса.** Если скрипт обращается к чужому адресу (`fetch('https://crm…')`,
`sendBeacon`, картинка-пиксель), под редактором — предупреждение: отсюда могут уходить данные,
которые человек ввёл в форму. Это законно, если адрес указан в политике школы и посетитель дал
согласие, — поэтому не запрещается, а называется. «Добавить … в список адресов» заносит адрес
во вкладку «Домены» — с тем, кто и когда занёс; ведёт список тот, у кого право «Код».

**Вкладка «Оформление»** — та же панель кода, но CSS открыт первым, а справа —
**предпросмотр с применённым оформлением**: форма со стилями и HTML-блоками школы на фоне
сайта. Фон — **скриншот сайта** (картинка из файлов школы), **цвет** или **пусто**: чужую
страницу в кадр не подгрузить, а скриншот решает ту же задачу — видно, попадает ли форма
в среду. Фон один на команду — хранится у виджета и на сайт не попадает.

Предпросмотр показывает **сохранённый черновик** и обновляется после каждого сохранения —
в том числе до публикации. Скрипт блоков в нём не работает: предпросмотр рисуется
в песочнице, где браузер скриптов не исполняет, иначе стили и разметка школы оказались бы
на странице с сессией сотрудника. Как работает скрипт, видно на странице виджета — кнопкой
«Посмотреть». Картинки из блоков виджета в предпросмотре могут не показаться: у песочницы
нет входа в школу.

Кадр виджета на чужом сайте **прозрачный**: форма ложится на фон страницы, а не встаёт
светлым прямоугольником. Цвета формы под сайт задаются в «Оформлении».

**Журнал правок** — у каждого блока кода страниц и виджетов: кто, когда и что стало.
Правки одного человека подряд в пределах десяти минут — одна строка: автосохранение
иначе превратило бы журнал в тысячу строк «набрал букву». «Сравнить» показывает
построчно, что вернётся и что уйдёт по сравнению с действующей версией.
**«Вернуть версию от …»** откатывает код к выбранной строке и называет, сколько правок
откатится. Возврат проходит те же проверки, что сохранение, и остаётся в журнале
отдельной строкой с именем того, кто вернул. Вернуть версию может тот, у кого право
«Код»; видеть журнал — все, кто открывает виджет.

**Пометка рядом с кодом.** Если у автора последней правки больше нет права на код,
над редактором написано «Автор последней правки — …, доступ к коду отозван …. Код
работает». Пометка снимается сама, когда код правит человек с действующим правом:
она про забытость, а не про клеймо. Отозванное право код не выключает — опасность
не в том, что код работает, а в том, что о нём забыли.

**«Отключить скрипт»** — одним нажатием после окна «Что изменится на сайте школы»:
пропадут свои проверки полей, перестанут отправляться события `lms:…`, форма продолжит
принимать заявки. Включается той же кнопкой.

Агент школы журнал кода не читает и версии не возвращает — это работа человека с правом
«Код». У уроков журнал пока не ведётся.

**Два режима доставки: кадр и своя вёрстка.** По умолчанию форма приходит на сайт кадром
(«Код для вставки»): проверки и согласия работают сами, чужие стили не портят форму,
обновления коробки приходят сами. **Своя вёрстка** — для своего фреймворка или конструктора
сайтов, который отправляет форму запросом: школа рисует форму сама, а мы даём адрес отправки
и имена полей. Включается переключателем «Режим доставки» в «Коде для вставки», без заявки
в поддержку; кадр при этом продолжает работать. Режим виден и в строке виджета:
«режим доставки: кадр» или «своя вёрстка».

```http
POST https://ваша-школа.ru/api/widget/webinar-flex/submit
Content-Type: application/json
Idempotency-Key: <ваш ключ>
```

Имена полей — договор, как классы формы: стандартные поля — по виду (`firstName`, `lastName`,
`email`, `phone`, `telegram`, `comment`; `name` — то же, что `firstName`), свои вопросы —
по ключу `q_…` (список полей этой формы — в редакторе), согласия — `consent_data`,
`consent_terms` и `consent_marketing`, метки — `utm_source`, `utm_medium`, `utm_campaign`,
`utm_content`, `utm_term`. Тело — JSON или поля обычной формы
(`application/x-www-form-urlencoded`); отмеченная галочка — `true`, «on», «1» или «yes».

- **Ошибки проверки приходят в ответе**: `422` и `fields` — текст у каждого имени поля,
  все сразу, а не переход на страницу.
- **Повтор с тем же `Idempotency-Key`** не заводит вторую заявку и возвращает первый ответ;
  ключ помнится сутки.
- **Список доменов действует**: браузер с сайта не из «Доменов» получает `403`, и отказ виден
  там же; запрос с сервера конструктора — без заголовка `Origin` — принимается.
- Не больше 20 заявок в минуту с одного адреса — дальше `429` с `Retry-After`.
- Заявка проходит те же действия после отправки, что форма в кадре; адрес оплаты приходит
  полным.

С этого момента **вид формы, проверка полей и сбор согласий — забота школы**: обновления
коробки их не улучшают, и в редакторе это написано словами. Третьего режима — вставки формы
прямо в страницу сайта — нет намеренно: стили протекают в обе стороны, скрипты сайта
конфликтуют с формой, а оформление и так решается стилями внутри кадра.

Одна версия кода. **HTTP не поддерживается** — не «не рекомендуется», а не
работает: браузер не пустит форму с защищённого адреса в незащищённую страницу.
Два одинаковых виджета на одной странице работают без правки кода.

**Виджет показывается только на разрешённых сайтах.** Пустой список означает
«только свой домен», а не «всем»: умолчание, открытое интернету, однажды заведёт
учеников с чужого лендинга. Свой домен разрешён всегда и в списке не хранится.

**Отказ по домену — не ошибка, а список задач.** Типичное срабатывание запрета —
забытый сайт, а не взлом. Поэтому чужие домены показаны в том же списке
с числом отказов, и разрешаются одной кнопкой.

Запрет живёт **на сервере**, а не в скрипте: скрипт на чужой странице можно
переписать в консоли, а адрес страницы-носителя приносит сам браузер, когда
грузит форму. Не разрешён — форма не рисуется, и отправлять нечего.

## Формы и заявки

Форма — это то, чем лендинг превращает посетителя в человека в базе.

Добавляется **блоком «Форма»** в редакторе страницы или виджета. Там же
выбирается всё остальное:

- **какие поля спрашивать** — группой до двенадцати полей: имя, фамилия, почта,
  телефон, телеграм, комментарий и свои вопросы — строкой или выбором из списка.
  У каждого поля — подпись, подсказка под полем и «обязательное»; порядок меняется
  кнопками «выше» и «ниже». Имя, фамилия, почта и телефон попадают в профиль
  ученика; телеграм, комментарий и свои вопросы — в заявку, со своими подписями.
  «Обязательное» и варианты выбора проверяет сервер при приёме, а не только страница;
- **согласия** — обработка персональных данных и условия использования: две
  отдельные галочки, выключить нельзя, ссылки ведут на правовые документы школы
  и открываются в новой вкладке. «Спрашивать про рекламные письма» включается
  в настройках формы, отказ не мешает отправке. Без двух обязательных согласий
  заявка не принимается ни у какой формы. Каждое согласие записывается человеку
  в «Мои согласия» способом «формой на сайте» — с версией документа, адресом
  и браузером; реклама — только если галочка стояла;
- **что происходит после отправки** — вкладкой «После отправки»: действия идут
  в зашитом порядке, переставить нельзя, счётчик «включено N из 11». Создать или
  найти человека — всегда; создать заказ по тарифу; настроить заказ — промокод,
  ответственный менеджер, комментарий (только после заказа); добавить в группу
  (в поток — нельзя: туда зачисляют); поставить метку; записать ответ про рекламу —
  всегда; запустить сценарий; отправить сообщение письмом или в мессенджер; куда
  попадёт человек — всегда последним: сообщение на месте формы, страница оплаты
  или свой адрес (открывается всем окном, а не внутри виджета). Одного действия
  нет, и это сказано на экране: вызова чужого адреса у продукта пока нет. Группа,
  сценарий и менеджер проверяются при сохранении; на приёме их сбой заявку
  не отменяет. Метки страницы уходят в заказ;
- **что происходит с человеком после отправки** — четыре варианта, о них ниже;
- **какой тег поставить** отправившему — по нему потом собирается сегмент.

> **Почта или телефон обязательны.** Без них доступ прислать некуда,
> и «спасибо, заявка принята» было бы обещанием, которое некому исполнить.

**Второй раз тот же человек не заводится.** Форму отправили с той же
почтой — заявка новая, человек прежний. Иначе постоянный покупатель после
третьей заявки существует в школе трижды, и доступы у него разложены
по трём карточкам.

### Что происходит с человеком после отправки

Это выбор между **потерять человека на пароле** и **пустить в чужой кабинет**.
Обе крайности реальны, поэтому вариантов четыре, и они идут по возрастанию
доверия к почте. Настройка стоит у каждой формы отдельно — у формы на странице,
у виджета и у записи на вебинар.

| Вариант | Что случится |
| --- | --- |
| **Без авторизации** | Человек остаётся гостем, в кабинет не входит. Доступ придёт письмом на указанную почту. |
| **Частичная** | Заказ создаётся, данные записываются, оплатить можно сразу. Кабинет закрыт, пока человек не войдёт кодом или паролем. |
| **Полная с паролем** | Сразу после отправки попросим пароль от этой почты. Новому человеку — «Задайте пароль», забывшему — код на почту. |
| **Полная без пароля** | Этот браузер сразу входит в кабинет. На почту уходит письмо со ссылкой. |

По умолчанию — **без авторизации**: формы, которые стоят на страницах сегодня,
никого не впускают, и включение этой настройки ничего не меняет само собой.

> **У «полной без пароля» есть цена, и она написана рядом с выбором.**
> Кто знает чужую почту ученика, войдёт в его кабинет: увидит покупки, прогресс
> и переписку. Вариант подходит для бесплатных записей, но не для форм,
> за которыми стоят деньги.

**Сотрудника школы форма без пароля не впускает никогда.** У владельца,
администратора, менеджера, куратора и автора она попросит пароль, а потом код
второго шага, если он включён в профиле. Это правило зашито в продукт
и настройкой не снимается.

**Человека со включённым вторым шагом** форма тоже не впускает молча: он сам
попросил спрашивать код, и форма не вправе это отменять.

**Экран после отправки начинается с «заявка принята»** и только потом просит
пароль: человек уже заполнил форму, и просьба без этой строки читается как
«вы зря заполняли». Под кнопкой — «заявка уже сохранена, даже если сейчас
не войдёте». Почта показана и не редактируется.

**Пять неудачных попыток подряд** закрывают вход по паролю на пятнадцать минут — с предложением
взять код на почту, а не с тупиком. Сколько попыток осталось, человек видит сразу: «Пароль
не подошёл. Осталось 4 попытки, потом вход закроется на 15 минут».

**Человека, записавшегося на эфир, кнопка ведёт в эфир.** Панель после отправки говорит «заявка
принята» и только потом предлагает войти; вторичные действия — «Забыли пароль? Пришлём код»,
«Не ваша почта?» — стоят ссылками, чтобы не спорить с главной кнопкой.

**Эти входы не пишутся в журнал.** В команде из тридцати человек журнал
превратился бы в ленту «вошёл, вошёл, вошёл»; в нём остаются смены ролей,
выдачи доступов и действия с деньгами.

**Своя вёрстка виджета** — форма, которую школа рисует сама и отправляет
со своего сайта, — ведёт себя как «без авторизации»: поставить куку чужому
домену нельзя, и доступ приходит письмом.

### Кабинет при частичной авторизации

Это не урезанный кабинет, а **одна страница**: заказ, кнопка оплаты
и «Мои покупки» — вместе с записями на эфиры и личными ссылками в комнату.
Всё остальное показано **закрытым со словами**, а не спрятано: человек должен
понимать, что за дверью, и что открыть её — один код на почту. В шапке стоит
«вход не завершён».

**Оплатить можно сразу** — вход в кабинет для этого не нужен, и это главное,
ради чего частичная авторизация и придумана.

**Войти полностью** — код из шести цифр на почту; пароль придумывать
не обязательно. Кто помнит пароль, войдёт им.

**Ошиблись в почте** — написать в школу: адрес поправят и перенесут заказ,
а если по ошибке завелись два кабинета, школа [склеит их в один](/guide/students/).

### Где смотреть заявки

Раздел **«Заявки»**: сверху формы со счётчиками, под ними — где стоит выбранная
форма, что она спрашивает и что делает, дальше таблица: человек, телефон,
ответы, когда и **что сделали**. На телефоне заявки идут карточками.

**«Что сделали» собирается по следам:** заявка сама не записывает, что из неё
вышло. Показывается сильнейшее из того, что случилось с человеком после неё:
«Выдан доступ» — доступ к курсу в течение суток, «Заказ оплачен» или «Заказ
создан» — заказ, который создала форма, «Поставлен тег» — тег формы, поставленный
этой заявкой. Иначе — «Ничего».

**Выгрузить в таблицу** можно заявки выбранной формы — с теми же ответами
и тем же «что сделали», что на экране. На экране — последние сто.

Заявка нужна затем, чтобы к человеку пойти, поэтому в ней видно и ответы,
и кто их оставил. Пустые поля не показываются: «Телефон: —» в короткой
заявке читается как потерянные данные.

**Форма переживает страницу.** Убрали блок с лендинга — форма отвязалась,
но осталась в списке вместе со всеми заявками: терять обращения людей
из-за правки вёрстки нельзя.

## Срок доступа и когда он начинается

У тарифа два разных вопроса про время, и путать их дорого.

**Сколько человек учится** — «Доступ, дней» либо «до даты». Дата сильнее
дней: заполните её, и поле дней погаснет.

**Когда доступ открывается** — сразу после оплаты, с указанной даты или
через N дней после оплаты.

> **Срок считается от начала доступа, а не от оплаты.** Курс стартует
> в октябре, человек купил в августе — его сто восемьдесят дней идут
> с октября. Иначе два месяца оплаченного срока сгорели бы в ожидании.

**Дата старта в прошлом означает «уже началось».** Поток стартовал
первого, человек купил пятого — доступ у него с пятого, а не задним
числом: иначе часть расписания у него уже «прошла».

**«До 31 декабря» — это весь день.** Не полночь тридцать первого.

**Повторная покупка продлевает и не укорачивает.** Второй доступ к тому же
курсу не заводится — это была бы вторая история прохождения, — но оплата
обязана что-то дать. Короткий тариф, купленный за три дня до конца
годового доступа, не превращает год в три дня.

**Подписка выдаёт бессрочный доступ.** Подписок в продукте пока нет,
и выключить доступ через выдуманный срок, о котором никто не
договаривался, было бы хуже.

## Переход с тарифа на тариф

Человек купил «Сам» за 19 000, через месяц хочет «С проверкой заданий»
за 39 000. Брать с него полную цену — значит не продать переход вовсе:
девятнадцать тысяч он уже отдал.

В форме тарифа есть раздел **«Переход с другого тарифа»**: найдите и добавьте
тарифы, которые этот заменяет, и выберите, что зачитывать.

| Что зачитывать | Когда |
|---|---|
| **Ничего** | перекрытие ради доступа, цена полная |
| **Всё, что человек заплатил** | обычный апгрейд |
| **До нижней границы цены** | школа сама назначает цену перехода |

**«Не дешевле»** — нижняя граница: апгрейд не уходит в ноль. У школы есть
издержки на человека, и «доплатите 0 ₽» это не продажа, а раздача.

> **Считается по оплаченному, а не по цене перекрытого тарифа.** Человек
> мог купить по промокоду за 15 000 — зачтётся пятнадцать, а не девятнадцать.
> Зачёт это возврат уже полученных денег, а не скидка «по прайсу».

**Возвращённое не зачитывается.** Деньги, вернувшиеся человеку, школа
второй раз не получала.

**Покупатель видит зачёт до оплаты** — на странице покупки, строкой
«Засчитываем 19 000 ₽ за «Сам» — вы это уже оплатили». Цена на витрине
одна, а в корзине другая читается как ошибка, даже когда разница в пользу
покупателя.

### Складывать сроки или брать больший

Галочка **«Складывать сроки доступа»** решает, что делает повторная
покупка:

- **без галочки** берётся больший из сроков — это апгрейд: сто оставшихся
  дней не складываются с новыми ста восемьюдесятью;
- **с галочкой** сроки складываются — это продление того же самого, иначе
  покупка за месяц до конца съедает этот месяц.

Истёкший доступ продлевается от сегодня, а не от прошлогодней даты.

## Реквизиты продавца

Заполняются в «Настройки → Реквизиты»: наименование, ИНН, ОГРН, адрес,
банк и счета.

**Они не лежат в настройках без дела.** Заполненные реквизиты
показываются покупателю в трёх местах:

- на странице оплаты — рядом со ссылкой на оферту, **до** оплаты;
- на публичных правовых страницах — блоком внизу;
- в подвале каждого письма школы — короткой строкой.

> Это требование, а не оформление: наименование продавца, место нахождения
> и регистрационный номер доводятся до потребителя (ст. 9 закона «О защите
> прав потребителей»).

**Незаполненное поле не показывается.** «ОГРН: —» читается как отсутствие
регистрации, а самозанятый без расчётного счёта — обычный продавец.

**В текст оферты реквизиты вписывать не нужно.** Они подставляются
из настроек: вписанные в текст, они станут вторым местом, где живёт ИНН
школы, и при смене счёта разойдутся.

## Список заказов

Сверху — сколько заказов всего и сколько денег пришло за 30 дней, справа —
выгрузка в таблицу.

**Плитка «Не оплачены» — она же фильтр.** В ней сумма долга по заказам
в трёх состояниях: создан, ждёт оплаты, оплачен частично. Нажали — список
сузился до них, рядом появился чип «Не оплачены ✕» и итог выборки: сколько
заказов и на какую сумму.

**Поиск — по имени, почте, телефону и номеру заказа.** Имя, почта и телефон
ищутся тем же условием, что в разделе «Пользователи». Номер ищется точно:
«4128» — это заказ №4128, а не кусок чьего-то телефона.

**В колонке «что дальше»** — следующий шаг: «не начинал оплату», «ждём
оплату», «оплата не прошла». У оплаченного заказа там прочерк: с ним делать
нечего, и это самое полезное, что о нём можно сказать.

Выделенные заказы можно **отменить разом** — правила те же, что у отмены
в карточке заказа (ниже). Заказ, который не отменяется, выделить нельзя.

Плиток рассрочек, подписок и возвратов «в работе», как и чипа «чек не пробит»,
в списке нет: этих возможностей в продукте пока нет, а плитка с нулём
обещала бы то, чего не существует.

## Карточка заказа

Сверху — номер, дата, состояние и «Открыть ученика». Строка стоит на месте,
прокручивается карточка.

**Карточка начинается с шапки состояния.** Первая строка отвечает, что
с доступом, вторая — что с деньгами, кнопки — что сейчас делать:

- **не оплачен** — «Доступа нет — заказ не оплачен», что было с последней
  попыткой оплаты («касса ещё не подтвердила», «не прошла» — с причиной
  от кассы, «ссылку открывали 2 раза — до оплаты не дошло») и ряд кнопок:
  «Отправить ссылку ещё раз», «Скопировать ссылку», «Отметить оплату вручную»,
  справа «Отменить заказ»;
- **оплачен не весь** — сколько внесено и какой остаток, а если часть уже
  вернули — и сколько; доступ откроется, когда заказ оплатят целиком:
  частичная оплата его не даёт;
- **оплачен** — до какого числа работает доступ и когда пришли деньги;
  кнопка возврата, пока есть что вернуть;
- **возвращён** — сколько и когда вернули; кнопок нет;
- **отменён** — «денег не было» стоит в заголовке, если по заказу ничего
  не приходило: отмену постоянно путают с возвратом.

Кто отменил заказ или оформил возврат и почему, шапка называет по журналу
заказа — тем, кому он открыт: администратору и владельцу. Кнопка, которая
смотрящему не положена, не показывается — вместо неё сказано, кто это делает.

**«Что куплено» — условия на момент покупки:** продукт, тариф, промокод
со скидкой, срок доступа. Если цена тарифа с тех пор поменялась, написаны
обе: «в тарифе сейчас 3 200 ₽, у этого заказа 2 800 ₽». Если заказ оформлен
переходом с тарифа на тариф, есть строка «Зачтено» — без неё цена заказа
не сходится с ценой тарифа и выглядит ошибкой.

**В «Платежах» — счёт одной строкой:** сколько прошло, сколько отклонено,
сколько получено и возвращено. Отказ назван причиной, а не кодом; возврат
записан под тем платежом, по которому вернули.

**«Кто купил»** — контакты, сколько у человека заказов и на какую сумму,
прогресс по курсам, которые дал этот заказ, и были ли возвраты.

**«Деньги»** — тариф, скидка по промокоду, к оплате и оплачено; у недоплаченного
заказа — остаток, у вернувшего деньги — сколько возвращено. «Оплачено» — сколько
пришло всего: возврат его не уменьшает, он стоит отдельной строкой.

**Примечание сотрудников о покупателе** — то же, что в карточке человека:
правка здесь — правка там. Видит его только тот, кому открыты карточки людей.

Под платежами — что происходило с заказом: кто отменил, вернул деньги,
заполнил поле — с именами и временем. Там же — что прислала касса и когда
покупатель открывал страницу оплаты.

### Ссылка на оплату — без входа

У неоплаченного и частично оплаченного заказа справа есть карточка **«Ссылка
на оплату»** (у частично оплаченного — «Ссылка на остаток»): адрес вида
`адрес-школы/pay/ord-1043-…` и сколько раз его открывали. По ссылке платят,
**не входя в кабинет**: человек, открывший письмо с телефона, раньше терялся
на экране входа.

- **Живёт, пока заказ не оплачен и не отменён** — срока и автоотмены нет.
  Оплаченный заказ по ссылке показывает «оплачен», отменённый — «отменён».
- **Сумма — та, что спишет касса**: весь заказ, первая часть, очередной платёж
  рассрочки или остаток — кнопка и платёж считаются одной функцией.
- **Плательщик — из заказа**, поменять его по ссылке нельзя.
- В шапке — **«Отправить ссылку ещё раз»** (то же письмо, что в первый раз,
  не чаще раза в 10 минут; в ленте заказа — кто отправил) и **«Скопировать
  ссылку»**; у частично оплаченного — **«Ссылка на остаток»**.
- Письма с кнопкой «Оплатить» — о созданном заказе, о рассрочке, о сроке
  и о просрочке платежа — ведут на эту же ссылку, а не в кабинет.
- Ключ в ссылке подобрать нельзя: он выводится из ключа установки, 16 знаков.
  Чужой ключ и несуществующий номер отвечают одинаково — «такой страницы нет».

Агент школы отдаёт ссылку в подробностях заказа и умеет отправить её ещё раз.

## Возврат денег

Возвращают **оплаченное**. Отменяют неоплаченное — это разные операции,
и путать их дорого: одна кнопка на обе однажды закроет оплаченный заказ,
не вернув денег.

Возврат бывает **полным и частичным**: человек купил комплект из трёх
курсов и просит вернуть один. Вернуть больше, чем пришло, нельзя ни
на копейку — сумма уже возвращённого вычитается из доступного.

**Доступ закрывается отдельным решением.** При полном возврате он предлагается
закрытым: вернули всё — значит человек ничего не купил. При частичном
не трогается: какую часть он оставляет себе, знает школа, а не продукт.

Промокод возвращается в предел: иначе человек, однажды передумавший,
теряет право на акцию навсегда.

**Возврат — право администратора, а не менеджера.** У менеджера продажи
в KPI, и отдавать деньги в одиночку он не должен.

Покупателю уходит письмо: сколько вернули, на какую карту и что срок
зависит от банка. Молчание здесь — прямой путь к оспариванию платежа.

**Двойное нажатие не вернёт деньги дважды.** Возврат сначала заводится заявкой
«в работе» — и только потом идёт в кассу, с ключом от номера этой заявки. Второе
нажатие, пока первое не решилось, продолжает ту же заявку: касса узнаёт повтор
и второй раз не возвращает. Если связь с кассой оборвалась и неизвестно, вернула ли
она деньги, заявка остаётся «в работе»: повтор той же суммы безопасен, а возврат
на другую сумму продукт не начнёт, пока не решится первый.

> **Если касса возврата по API не даёт**, школа возвращает деньги в её
> личном кабинете, а продукт записывает это как возврат «вручную» и так
> его и называет. Возврат, проведённый вне системы и не записанный,
> разводит отчётность школы с банком — а находят это на сверке.

## Отмена заказа

Отменяют **неоплаченный** заказ — намерение, которое передумали.

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

Свой неоплаченный заказ человек отменяет сам, из кабинета. Чужой —
сотрудник с правом; причина попадает в журнал и в карточку заказа.

Покупателю уходит письмо об отмене. **Молчание здесь читается как обман:**
человек, у которого не прошла карта, сидит и ждёт, а деньги могли
и списаться.

Отменить можно и из списка заказов — выделенные разом, — и попросив агента
школы. Правила везде одни: заказ, который не отменяется, отказывает с той же
причиной, а агент перед отменой спрашивает подтверждение.

**Сам неоплаченный заказ не отменяется** — автоотмены по сроку нет: отменяет
менеджер, когда понятно, что оплаты не будет.

## Оплата мимо кассы

Деньги пришли переводом на карту, наличными или по счёту — в карточке неоплаченного
заказа **«Отметить оплату вручную»**. Сумма — остаток по заказу; пришла часть —
впишите её, и заказ станет частично оплаченным, а следующая отметка — доплатой.
«Как пришли деньги» обязательно: это строка журнала заказа. Дальше — то же, что
после оплаты через кассу: доступ открывается сразу, покупателю уходит письмо, партнёру
начисляется комиссия.

Отмечает **владелец** всегда, **менеджер** — ролью, **администратор** — если владелец
поставил ему галочку «Отмечать оплату вручную» в карточке сотрудника, вкладка «Права».
Чек касса не пробьёт — деньги прошли мимо неё, чек школа оформляет сама. Агент школы
оплату не отмечает: это деньги, и решает человек.

## Письма покупателю

Уходят сами, настраивать нечего:

| Когда | Что в письме |
|---|---|
| заказ создан | состав заказа, сумма, кнопка «Оплатить» |
| оплачено | подтверждение с составом и суммой |
| доступ открыт | что открыли и кнопка «Начать обучение» |
| заказ отменён | что отменено и что будет с деньгами |
| рассрочка | напоминание за три дня до платежа |

Квитанция и «доступ открыт» — **разные письма**, и это осознанно. Квитанция
про деньги: что, на сколько, номер заказа. «Доступ открыт» про учёбу: вот
ваш курс, вот кнопка. Слить их в одно — получить письмо, которое не годится
ни для бухгалтерии, ни для начала занятий.

## Деньги считаются целыми числами

Копейки, а не дробные рубли. Дробная арифметика на деньгах даёт расхождение
в копейку на тысяче заказов, и находят его в отчётности, а не в коде.

Сумма в письме и сумма на экране собираются одной функцией — до копейки.
