Стек для adult-проекта: что он решает, а что нет
Коротко. Язык и фреймворк почти никогда не бывают причиной, по которой adult-проект перестаёт зарабатывать. Причины другие и повторяются из проекта в проект: смена платёжного провайдера, рост медиатеки, потеря рекламного канала. Выбор стека определяет не скорость разработки, а стоимость переживания этих трёх событий. Ниже — какие границы внутри системы делают их дешёвыми, и по каким признакам видно, что границ нет.
Эта страница про архитектуру и границы. Если нужен обзор того, что вообще применяется в нише сегодня, он в материале новые технологии в веб-разработке для индустрии 18+, а про железо и размещение — в разборе хостинга для adult-сайта.
Три события, которые переживает каждый платный проект
Это не гипотезы, а обычная биография проекта, живущего дольше двух лет. Вопрос не в том, случатся ли они, а в том, сколько будет стоить каждое.
| Событие | Что происходит | Что решает архитектура |
| Смена платёжного провайдера |
Провайдер поднимает ставку, ужесточает условия или закрывает категорию. Переход нужен за недели, а не за квартал |
Есть ли внутри своя запись о деньгах или она подменена выгрузкой из провайдера |
| Рост медиатеки |
Файлы перестают помещаться туда, где лежали. Трафик на отдачу становится заметной статьёй расходов |
Ходит ли видео через приложение или мимо него |
| Потеря канала привлечения |
Площадка закрывает категорию, сеть режет объём. Нужно быстро перевесить бюджет |
Можно ли посчитать окупаемость по источнику, не собирая цифры руками |
Обратите внимание, чего в этой таблице нет: ни языка, ни фреймворка, ни базы данных. Всё решается тем, где в системе проведены границы, а не тем, на чём написан код по обе стороны от них.
Биллинг: слой, где ошибка стоит денег в тот же день
Платёжный провайдер сообщает о событиях сервер-серверным вызовом — postback. Это источник истины по деньгам: браузер пользователя может закрыться, страница «спасибо» может не загрузиться, а списание при этом состоится. Отсюда три требования, которые в adult-проекте невыполнимы задним числом.
-
Обработчик идемпотентен. Один и тот же вызов приходит дважды — из-за таймаута, повтора, сбоя сети. Второй раз не должен ни начислять комиссию, ни продлевать доступ. Практически это значит, что у события есть идентификатор от провайдера, и он уникален в вашей таблице.
-
Событие сохраняется до обработки, а не после. Сначала запись «пришло вот это», потом разбор. Иначе упавший разбор уносит с собой и факт события, а провайдер повторит не бесконечно.
-
Отказ — это тоже событие. Возврат, оспаривание, отмена подписки приходят тем же каналом. Система, которая записывает только успешные списания, показывает выручку, которой нет.
Из этих трёх требований вырастает единственное архитектурное решение, которое действительно стоит принять заранее: собственный журнал финансовых событий. Не отчёт, который можно выгрузить из личного кабинета провайдера, а своя таблица, где каждая строка — произошедшее событие со ссылкой на источник. Проект, у которого он есть, меняет провайдера за недели. Проект, у которого его нет, обнаруживает, что вся его история продаж живёт в чужом кабинете, доступ к которому вот-вот закончится.
Медиа: почему видео не должно проходить через приложение
Самая частая ошибка в молодом проекте — отдавать файлы тем же процессом, который рисует страницы. Работает до первых серьёзных объёмов, потом перестаёт: длинные соединения занимают потоки приложения, и сайт начинает тормозить не от нагрузки на логику, а от того, что кто-то смотрит длинный ролик.
| Способ отдачи | Когда уместен | Чем платите |
| Через приложение |
Прототип, небольшая галерея, платный доступ к отдельным файлам |
Потоки приложения; масштабируется хуже всего |
| Отдельный отдающий узел |
Растущая медиатека, когда приложение и файлы уже мешают друг другу |
Ещё один сервер и его сопровождение |
| Объектное хранилище со ссылками с ограниченным сроком |
Платный доступ к большому каталогу |
Хранение плюс исходящий трафик; появляется зависимость от провайдера |
| Сеть доставки контента |
География шире одной страны, важно время до первого кадра |
Дороже за гигабайт; не каждая сеть работает с этой категорией |
⚠ Не каждый провайдер хранения и доставки принимает контент 18+. Это условие проверяется до выбора, а не после переезда: обнаружить ограничение на этапе, когда терабайты уже загружены, дороже, чем изначально взять более дорогого провайдера, который категорию обслуживает.
Прикидка расходов на отдачу делается на салфетке и обычно расходится с ожиданиями в разы:
Исходящий трафик за месяц = среднее число просмотров × средний вес просмотренного фрагмента
Счёт = хранение (объём × ставка) + отдача (трафик × ставка)
Обратите внимание, что в первую формулу входит вес просмотренного фрагмента, а не всего файла: люди редко досматривают до конца, и оценка по полному весу завышает счёт вдвое и больше. Ровно так же она занижает его, если на сайте автовоспроизведение превью.
Данные людей: где проходит граница
В этой нише в одной системе оказываются несопоставимые по чувствительности вещи: публичные анкеты и фотографии — и документы, подтверждающие возраст и согласие, платёжные данные, переписка. Их нельзя держать в одном контуре с одинаковым доступом.
-
Документы о возрасте и согласии хранятся отдельно, с журналом обращений: кто смотрел, когда, зачем. Они нужны редко, но нужны именно в том виде, в каком их примет проверяющая сторона.
-
Платёжные данные не хранятся вовсе. Их держит провайдер, у вас остаётся идентификатор. Это не экономия на разработке, а снятие с себя целого класса требований.
-
Переписка и история просмотров — персональные данные, и для европейского трафика это значит обязанность уметь их выдать и удалить по запросу. Систему, где всё сшито в одну таблицу без признака владельца, придётся переделывать.
Подробный разбор требований — в материале про правовые вопросы разработки сайтов интим-услуг. Здесь важно одно: это архитектурное решение, а не юридическое. Границу проводят при проектировании, и стоит она тогда ничего.
Что стек не решает
Список короткий, но он экономит месяцы, потраченные не туда.
- Не решает позиции в поиске. Скорость влияет, всё остальное — нет.
- Не решает доступ к рекламе. Категорию закрывают по категории, а не по технологии.
- Не решает конверсию. Её определяют цена, доверие и то, сколько шагов до оплаты.
- Не решает удержание. Оно про содержание и про то, есть ли повод вернуться.
Поэтому спор «на чём писать» почти всегда стоит меньше, чем спор «где провести границы». Команда, которая умеет один инструмент хорошо, сделает надёжнее, чем команда, взявшая модный.
Признаки, что границ нет
Если узнаёте у себя три пункта из пяти, проблема не в производительности и не в языке.
- Чтобы узнать выручку за месяц, кто-то заходит в кабинет провайдера.
- Повторно пришедший postback создаёт вторую запись, и это лечат уборкой дублей руками.
- Видео отдаёт тот же процесс, что рисует страницы.
- Окупаемость по источникам трафика считается в таблице, которую ведут вручную.
- Документы о возрасте лежат в той же папке, что и публичные фотографии.
Если границ нет, а проект уже работает
Переписывать целиком не нужно почти никогда. Границы проводятся по одной, в порядке убывания риска, и каждая даёт результат сама по себе.
| Очередь | Что делается | Что становится возможным |
| Первая |
Свой журнал финансовых событий. Пишется параллельно существующему учёту, ничего не ломая |
Сменить провайдера, не потеряв историю. Сверить его отчёт со своим |
| Вторая |
Идемпотентность обработчика и запись отказов наравне с оплатами |
Выручка в отчёте перестаёт расходиться с выручкой на счёте |
| Третья |
Вынос отдачи медиа из приложения |
Нагрузка от просмотров перестаёт влиять на скорость страниц |
| Четвёртая |
Разделение чувствительных данных и публичных, журнал обращений |
Запрос на удаление или проверка перестают быть авралом |
Порядок именно такой не случайно. Первые две границы возвращают контроль над деньгами и стоят дешевле всего, потому что не требуют трогать то, что видит пользователь. Третья заметна снаружи и делается, когда объёмы уже мешают. Четвёртая — единственная, которую иногда приходится делать вне очереди: если европейский трафик уже идёт, ждать нельзя.
Что проверить прямо сейчас
- Есть ли своя таблица финансовых событий и переживёт ли она уход провайдера.
- Уникален ли идентификатор события провайдера в вашей базе.
- Записываются ли возвраты и оспаривания наравне с успешными списаниями.
- Отдаются ли файлы мимо приложения.
- Принимает ли ваш провайдер хранения категорию 18+ письменно, а не на словах.
- Отделены ли документы о возрасте от остального контента и ведётся ли журнал обращений к ним.
- Можно ли по одному запросу собрать всё, что система знает о конкретном человеке.
Как это делает adults.dev
Мы начинаем не с выбора технологии, а с трёх границ: журнал финансовых событий отдельно от провайдера, отдача медиа отдельно от приложения, чувствительные данные отдельно от публичных. Внутри этих границ инструмент подбирается под задачу и под то, чем вы сможете пользоваться дальше сами, а не под наши предпочтения.
На практике разговор обычно начинается с вопроса «сколько будет стоить сменить биллинг». Если ответ неизвестен — это и есть первая работа, независимо от того, что написано в требованиях.
Обсудить архитектуру проекта:
Telegram: @adultsdev
E-mail: info@adults.dev