Магазины приложений: правила, комиссии, ревью и отказы
В главе о каналах канал определялся как ответ на вопрос «кто владеет отношениями с покупателем». Магазин приложений — крайняя точка этой шкалы: он владеет отношениями целиком. Он знает, кто купил, он выставил счёт, он получил деньги, он решает, увидит ли покупатель ваш продукт вообще, и он может убрать вас с полки без предупреждения.
Это единственный канал, где ваш релизный процесс проходит через чужой процесс с недетерминированной задержкой и правом отказа. Всё остальное — комиссия, правила, возрастные рейтинги, декларации о данных — следствия этого факта. Инженерное содержание главы именно в этом: магазин не «дополнительный способ продавать», а внешнее ограничение, которое надо заложить в архитектуру и в календарь релизов, иначе оно проявится в момент, когда исправлять уже поздно.
Про мобильный релизный конвейер как таковой — сборка, подпись, поэтапная раскатка, крэш-репортинг — есть отдельный подробный материал в треке мобильной разработки (релизы и магазины). Здесь мы смотрим на магазин со стороны поставки и денег: что вы покупаете за комиссию, какие обязательства берёте и как проектировать продукт, чтобы правила площадки не переписывали вам архитектуру каждые полгода.
Магазин — это четыре бизнеса в одном
Слово «магазин» сбивает с толку, потому что склеивает четыре разные функции. Разделите их — и станет видно, за что именно вы платите и что можно, в принципе, купить отдельно.
автоматика и человек"] R -->|"одобрено"| S["Витрина:
поиск, топы, страница"] R -->|"отказ"| D S --> U["Пользователь"] U -->|"платит картой"| K["Касса площадки:
продавец записи"] K -->|"комиссия удержана"| D S --> C["Канал доставки:
CDN, установка, обновление, откат"] C --> U K -->|"возврат по кнопке"| U P["Платформа: ОС, песочница,
подпись, отзыв доверия"] --- C
| Функция | Что даёт покупателю | Что даёт поставщику | Какое обязательство создаёт |
|---|---|---|---|
| Витрина | Поиск, отзывы, рейтинги, «это не вирус» | Доступ к аудитории без своего маркетинга | Метаданные обязаны соответствовать продукту; ранжирование не ваше |
| Касса | Одна карта на все покупки, кнопка возврата | Ноль работы с налогами и спорами | Комиссия, задержка выплат, обязанность продавать только через неё |
| Ревью | Некоторая уверенность, что приложение не сломает телефон | Отсутствие конкурентов, которые нарушают правила | Задержка релиза, отказ без обжалования по существу |
| Канал доставки | Установка и обновление одной кнопкой, откат аккаунтом | CDN, дельта-обновления, поэтапная раскатка бесплатно | Вы не можете доставить обновление в обход и не можете откатить сами |
Ключевое наблюдение: эти функции продаются одним пакетом, а нужны вам обычно не все. Зрелый B2B-продукт с корпоративными продажами платит комиссию за витрину, которой не пользуется. Небольшая утилита без бюджета на маркетинг, наоборот, покупает главным образом витрину, а касса ей почти безразлична. Отсюда и разные стратегии: одни выносят покупку на сайт при первой возможности, другие не выносят никогда, потому что конверсия «одна кнопка внутри приложения» перевешивает комиссию.
Комиссия: механизм, а не число
Любая таблица процентов протухает за полгода. Полезен механизм. Комиссия площадки описывается четырьмя параметрами, и меняются они независимо:
- База. От чего считают: от витринной цены целиком или от суммы за вычетом налога с продаж и НДС. Разница в двадцать процентов ставки налога — это реальные деньги, и площадки считают по-разному в разных странах.
- Ставка. Базовая ставка исторически 30 процентов для цифровых товаров в крупных мобильных и игровых магазинах. Дальше идут понижения: программы для небольших разработчиков (порог по годовому обороту, ставка около 15 процентов), пониженная ставка на второй и последующие годы подписки, ступени по накопленному обороту в игровых магазинах, отдельные ставки для медиа- и видеосервисов. На середину 2026 года разброс реально встречающихся эффективных ставок — от примерно 10 до 30 процентов.
- Отдельные сборы. Там, где регулятор заставил снизить ставку, появляются сборы иной природы: плата за установку, плата за «услуги магазина», отдельный процент за использование платформенной технологии, отдельный процент платёжному провайдеру. Ставка падает, сумма меняется мало — это устойчивый паттерн, а не совпадение.
- Что не считается цифровым товаром. Физические товары, доставка еды, такси, реклама, покупки между людьми и, в большинстве правил, «настоящие» офлайн-услуги комиссией не облагаются вообще. Это самая большая развилка в экономике продукта: одно и то же приложение может платить 30 процентов или ноль в зависимости от того, что именно продаётся.
Чистая выручка с одной продажи считается так:
$$ R_{\text{net}} = \frac{P}{1 + t} \cdot (1 - c) \cdot (1 - f) \cdot (1 - r) $$
где $P$ — витринная цена с налогом, $t$ — ставка налога с продаж или НДС, $c$ — комиссия площадки, $f$ — потери на конвертации валюты и выплатах, $r$ — доля возвращённых покупок. При витринной цене 1000 рублей, налоге 20 процентов, комиссии 30 процентов, конвертации 2 процента и возвратах 3 процента до вас доезжает примерно 554 рубля — 55 процентов от того, что заплатил покупатель.
Три вещи, которые ломают интуицию и попадают в отчётность неправильно чаще всего:
- Комиссия не возвращается автоматически при возврате. Правила разных площадок расходятся: где-то удержанная комиссия возвращается вам вместе с отменой продажи, где-то нет, где-то зависит от причины возврата. Проверять надо не в статье, а в своём отчёте о выплатах, сверив несколько реальных возвратов вручную. Это первое, что стоит сделать после первой сотни продаж.
- Деньги приходят с задержкой. Типовой цикл — закрытие календарного месяца плюс тридцать-сорок пять дней, часто с минимальным порогом выплаты. Для продукта с оплатой рекламы вперёд это означает кассовый разрыв в два-три месяца, который надо финансировать. Подробнее про денежные циклы — юнит-экономика.
- Валюта выплаты не ваша. Площадка продала в тридцати валютах, а платит вам в одной, по своему курсу и со своим спредом. Это ещё один-два процента, которые в модели обычно забывают.
Полезно иметь калькулятор, а не оценку «примерно тридцать процентов»:
from dataclasses import dataclass
@dataclass(frozen=True)
class Channel:
"""Канал продажи с точки зрения того, сколько денег доедет до вас."""
name: str
commission: float # доля, удерживаемая площадкой
tax_included: bool # цена на витрине уже включает налог
fx_and_payout: float # потери на конвертации и выплате
fixed_monthly: float # постоянные издержки канала в месяц, в рублях
cac: float # стоимость привлечения одной покупки, в рублях
def net_per_sale(price: float, tax_rate: float, refund_rate: float, ch: Channel) -> float:
"""Чистая выручка с одной продажи после налога, комиссии, конвертации и возвратов."""
base = price / (1 + tax_rate) if ch.tax_included else price
after_commission = base * (1 - ch.commission)
after_fx = after_commission * (1 - ch.fx_and_payout)
return after_fx * (1 - refund_rate) - ch.cac
def monthly_profit(sales: int, price: float, tax_rate: float,
refund_rate: float, ch: Channel) -> float:
return sales * net_per_sale(price, tax_rate, refund_rate, ch) - ch.fixed_monthly
store = Channel("магазин", 0.30, True, 0.02, 700, 0) # взнос разработчика в месяц
store_small = Channel("магазин, сниженная ставка", 0.15, True, 0.02, 700, 0)
own_site = Channel("свой сайт", 0.07, True, 0.015, 12000, 350) # провайдер-продавец плюс реклама
for ch in (store, store_small, own_site):
per_sale = net_per_sale(1000, 0.20, 0.03, ch)
print(f"{ch.name:28} {per_sale:7.1f} руб. с продажи, "
f"{monthly_profit(500, 1000, 0.20, 0.03, ch):9.0f} руб. в месяц при 500 продажах")
Смысл упражнения не в цифрах, а в том, что свой сайт выигрывает по проценту и проигрывает по стоимости привлечения. Комиссия магазина — это в значительной степени плата за трафик, который вы иначе покупали бы сами. Считать надо не ставку, а полную стоимость одной оплаченной установки. Если вы не знаете свой CAC, вы не можете обосновать уход с площадки, каким бы грабежом ни казалась её ставка.
Продавец записи: главное, что вы покупаете за комиссию
Самая недооценённая часть комиссии — не витрина и не CDN, а роль продавца записи (merchant of record). Когда покупатель нажимает «купить» внутри приложения, по документам ему продаёт площадка, а не вы. Из этого вытекает всё остальное.
| Кто продавец записи | Кто разбирается с налогами | Кто отвечает на спор с банком | Кто выставляет счёт-фактуру |
|---|---|---|---|
| Площадка | Площадка, в сотне юрисдикций сразу | Площадка | Площадка |
| Вы напрямую | Вы: регистрация по НДС там, где есть порог | Вы, включая штрафы за долю чарджбэков | Вы, в формате каждой страны |
| Внешний провайдер-продавец | Провайдер за 4–8 процентов оборота | Провайдер | Провайдер |
Продавать цифровой продукт физлицам в Евросоюзе означает считать НДС по ставке страны покупателя, хранить два независимых доказательства его местонахождения, подавать отчётность и держать эту машину живой при каждом изменении ставок. Для соло-разработчика это не «часть работы», а отдельный проект. Пятнадцать процентов комиссии за то, что этого проекта не существует, — часто выгодная сделка, и именно поэтому провайдеры-продавцы для веб-продаж живы и берут сопоставимые деньги.
Порог, где выгоднее переставать платить процент и брать фиксированные издержки на себя, считается просто: делите годовую стоимость собственного комплаенса (бухгалтер, налоговый консультант, регистрации, софт) на разницу ставок. Если разница 10 процентов, а комплаенс стоит миллион рублей в год, порог — десять миллионов рублей оборота. Механика налогов и валют подробно разобрана в главе о биллинге, ограничения по юрисдикциям — в главе про ограничения.
Это не юридический совет. Вопрос юристу формулируется конкретно: «по нашей схеме продаж кто является продавцом записи в стране X, возникает ли у нас обязанность регистрации по косвенным налогам и что меняется, если мы добавим оплату на сайте параллельно с оплатой в магазине».
Правила площадок: четыре класса и почему они ограничивают архитектуру
Правила магазина читаются как список запретов, но работают как техническое задание. Их удобно делить на четыре класса — у каждого свой характер и своя цена нарушения.
Инженерное содержание — в первом классе, и оно жёстче, чем кажется:
- Нельзя доставлять исполняемый код мимо магазина. Это убивает целый класс решений: собственные системы горячих патчей, скачиваемые нативные модули, интерпретаторы произвольного кода. Обычное исключение — код, исполняемый встроенным веб-движком платформы, и конфигурация, которая переключает уже проверенное поведение. Граница проходит там, где «данные» перестают быть данными и становятся программой. Практическое следствие: фича-флаги можно, тайную функциональность нельзя. Флаг, который включает то, что ревьюер видел и одобрил, — нормальная практика. Флаг, который после одобрения превращает калькулятор в казино, — основание для удаления приложения и блокировки аккаунта.
- Обязательные механизмы платформы. Правила регулярно требуют не просто «не делать», а «делать»: предложить платформенный вход, если есть вход через сторонние соцсети; дать в приложении кнопку удаления аккаунта, если есть кнопка регистрации; поддержать системный диалог согласия на отслеживание. Каждое такое требование — работа на спринт, которая появляется в вашем бэклоге по чужому решению и с чужим дедлайном.
- Разрешения по назначению. Запрос доступа к контактам, геолокации или буферу обмена должен быть обоснован функцией, видимой ревьюеру. Платформы добавляют технические проверки: манифесты приватности, декларации причин использования системных API, автоматический анализ бинаря на запрещённые вызовы. Это уже не текст правил, а гейт сборки, который валит загрузку артефакта.
Второй класс — деньги — самый политически подвижный, о нём ниже. Третий и четвёртый дёшевы в исправлении, но именно они дают большинство отказов, потому что их проверяют первыми.
Практический приём: держите правила площадки как список требований к продукту, а не как файл в закладках. Раз в квартал кто-то читает changelog правил и заводит задачи. Иначе изменение правил превращается в аварию: «через шесть недель все обновления должны собираться новым SDK, иначе загрузка блокируется» — это реальный жанр писем от площадок.
Anti-steering, регуляторы и почему таблица процентов бесполезна
Правило «нельзя рассказывать пользователю, что на сайте дешевле» (anti-steering) — самая оспариваемая часть магазинной модели. Последние годы это поле непрерывно меняется под давлением судов и регуляторов, и меняется по-разному в разных странах.
Из этой истории надо унести не даты, а механизм: регулятор запрещает конкретное ограничение — площадка вводит альтернативу, где номинальная комиссия ниже, но добавляются сборы другой природы. Экономика для среднего разработчика меняется слабо, а сложность растёт: теперь у вас в проде несколько наборов правил, зависящих от страны аккаунта покупателя.
Отсюда единственный устойчивый инженерный вывод:
Способ оплаты должен быть конфигурацией, а не архитектурой. Возможность включить внешнюю ссылку на оплату для одной страны и выключить для другой — это фича-флаг и серверная конфигурация, а не рефакторинг на два месяца.
И столь же устойчивый вывод про деньги: не стройте финансовую модель на ожидании, что комиссия скоро упадёт. Она формально падает уже несколько лет, а эффективная ставка держится.
Ревью: очередь с недетерминированной задержкой
Ревью — не тестирование. Это комбинация автоматических проверок бинаря и человека, у которого есть чек-лист и очень мало времени на вашу сборку. Понимание этой модели меняет то, как вы подаёте приложение.
Что из этой схемы важно для календаря:
- Между «одобрено» и «опубликовано» должен быть ваш ручной шаг. Автопубликация после одобрения экономит одно нажатие и лишает вас контроля над датой. Одобрение может прийти в пятницу вечером.
- Время ревью — распределение, а не число. На середину 2026 года типовая мобильная сборка проходит за часы или сутки, но хвост распределения — недели: первый релиз нового аккаунта, смена категории, спорная функциональность, праздники, «дополнительная проверка». Планируйте по хвосту.
- Ускоренное рассмотрение — исчерпаемый ресурс. Его дают на настоящие аварии: критическая уязвимость, падение при старте, юридическое требование. Потратите на маркетинговый дедлайн — не получите, когда понадобится.
- Раскатка — ваш инструмент, а откат — нет. Остановить раскатку можно, «вернуть вчерашнюю версию» тем, кто уже обновился, — нельзя. Единственный откат — новая сборка с исправлением, которая снова идёт через ревью. Поэтому в магазинном мире особенно дорого стоит серверный выключатель функции. Механику безопасных релизов см. в SRE: безопасные релизы и стратегиях выката.
Что заметно снижает вероятность отказа, по опыту почти любой команды:
- Рабочий демо-аккаунт с данными. Приложение, которое ревьюеру показывает пустой экран входа, отклоняется по формальному основанию «неполнота». Аккаунт должен жить дольше ревью и содержать заполненный контент.
- Заметки для ревьюера. Короткий текст: что делает приложение, как воспроизвести нетривиальный сценарий, почему запрашивается каждое чувствительное разрешение, где взять код подтверждения, если вход по одноразовому паролю. Видео на минуту дешевле, чем неделя переписки.
- Скриншоты, совпадающие с реальностью. Несоответствие витрины и продукта — самая частая и самая дешёвая по исправлению причина отказа.
- Честная декларация о данных. Расхождение декларации с реальным поведением SDK ловится автоматикой и уже относится к классу «доверие», а не «оформление».
Отказы: таксономия и что с ними делать
Отказ — нормальная часть процесса, а не катастрофа. Катастрофа — отказ, который вы получили в день запуска рекламной кампании. Поэтому отказы полезно классифицировать заранее по цене в днях.
| Класс отказа | Типичная причина | Цена | Как предотвратить |
|---|---|---|---|
| Метаданные | Скриншоты не от той версии, описание обещает лишнее, чужой бренд в тексте | Часы | Чек-лист витрины в релизном шаблоне |
| Неполнота | Не работает вход, нет демо-аккаунта, падение при первом запуске | Часы–дни | Прогон сборки на чистом устройстве без вашего окружения |
| Минимальная функциональность | Обёртка вокруг сайта, приложение-визитка, дубликат своего же продукта | Дни–недели | Решать до разработки: продукт должен делать что-то на устройстве |
| Деньги | Продажа цифрового мимо кассы, ссылка на внешнюю оплату там, где нельзя | Дни–недели | Флаг на способ оплаты по стране, ревью текстов юристом |
| Приватность | Декларация не совпадает с поведением, сбор данных без согласия, нет политики | Дни–недели | Генерировать декларацию из инвентаря SDK, а не писать руками |
| Права | Чужие товарные знаки, ассеты, музыка, скриншоты чужих сервисов | Недели | Реестр лицензий на ассеты; см. лицензии |
| Возраст и содержание | Анкета рейтинга не соответствует контенту, UGC без модерации и жалоб | Недели | Механизм жалоб и блокировки до подачи, а не после отказа |
| Аккаунт | Повторные нарушения, обход правил, подозрение на мошенничество | Месяцы или навсегда | Не обходить правила; это единственный класс, который может закрыть бизнес |
Три практических правила при получении отказа:
Определите, спор это о факте или о трактовке. Если ревьюер написал «приложение падает при запуске», а оно не падает, — это факт, и апелляция уместна: приложите видео, номер сборки, логи. Если написано «функциональность недостаточна» — это трактовка, и спорить бесполезно, надо менять продукт или аргументировать иначе. Апелляция по трактовке съедает недели и почти всегда заканчивается тем же ответом.
Отвечайте фактами и один раз. Переписка с площадкой — не диалог, а обмен документами. Каждое сообщение должно содержать номер сборки, точный пункт правил, конкретное объяснение и доказательство. Эмоции добавляют круги, а не скорость.
Считайте отказ за баг, а не за случайность. Один и тот же класс отказа второй раз — это дефект процесса. Заведите чек-лист релиза, куда попадает каждая причина, по которой вас уже отклоняли. Через год у вас будет список, дороже которого в релизном процессе ничего нет.
Отдельно про самый дорогой сценарий: риск уровня аккаунта. Удаление приложения, блокировка аккаунта разработчика, удержание невыплаченных денег. Он реализуется при систематических нарушениях, обходе правил или подозрении на мошенничество, и он не про код. Технические следствия простые и их стоит заложить заранее: аккаунт оформлен на компанию, а не на личную почту сотрудника; доступ есть более чем у одного человека; ключи подписи и учётные данные лежат в хранилище секретов (управление секретами), а не на ноутбуке; у пользователей есть способ связаться с вами вне магазина.
Покупки в коде: чек — это не доказательство
Экономическая модель магазина проникает прямо в код: право пользователя на функциональность (entitlement) появляется в результате покупки, о которой вам сообщает недоверенный источник — клиент. Отсюда единственно правильная схема.
Что здесь неочевидно и стоит денег, если сделать иначе:
- Проверять чек надо на сервере, серверным API площадки. Проверка на клиенте — это проверка тем, кого вы проверяете. Криптографическая подпись чека помогает, но ключ и логика проверки на клиенте всё равно подделываются.
- Право хранится у вас, а не в магазине. Иначе кроссплатформенная подписка невозможна: человек купил на телефоне, зашёл в браузере и не понимает, за что платил. Своё хранилище прав, к которому привязан аккаунт, а не устройство, — обязательная часть архитектуры.
- Уведомления от магазина — источник правды о жизненном цикле. Продление, отмена, возврат, повышение тарифа и «отказ от продления» приходят вебхуками. Приложение об этих событиях может никогда не узнать: человек отменил подписку в настройках системы и больше не открывал приложение.
- Идемпотентность обязательна. Уведомления повторяются, приходят не по порядку и дублируются. Ключ идемпотентности — идентификатор транзакции площадки; см. идемпотентность и гарантии доставки.
- Не подтвердили покупку — деньги вернутся. Площадки требуют явного подтверждения, что товар выдан, и автоматически возвращают деньги за неподтверждённые покупки. Пропущенный вызов подтверждения — тихая утечка выручки, которая не видна ни в одной метрике продукта.
Абстракция, которая переживает смену площадки и появление оплаты на сайте:
/** Право пользователя на функциональность — то, что хранится у вас. */
interface Entitlement {
userId: string;
productId: string;
source: "app_store" | "play" | "web" | "promo";
expiresAt: Date | null; // null для бессрочных покупок
externalTxId: string; // идентификатор транзакции у площадки — ключ идемпотентности
}
/** Единый интерфейс для любой кассы: магазина, веба, промокода. */
interface PurchaseVerifier {
/** Проверяет чек в источнике истины и возвращает право или null, если чек невалиден. */
verify(receipt: string, userId: string): Promise<Entitlement | null>;
/** Разбирает входящее уведомление площадки о жизненном цикле подписки. */
parseNotification(payload: unknown): Promise<Entitlement | null>;
}
async function grant(store: PurchaseVerifier, receipt: string, userId: string) {
const ent = await store.verify(receipt, userId);
if (!ent) return { ok: false, reason: "invalid_receipt" };
// Идемпотентность: повтор того же уведомления не должен продлевать подписку дважды.
const inserted = await db.upsertEntitlement(ent, { conflictKey: "externalTxId" });
if (!inserted.changed) return { ok: true, reason: "already_applied" };
await audit.log("entitlement_granted", { userId, productId: ent.productId,
source: ent.source, txId: ent.externalTxId });
return { ok: true };
}
Стоит ли писать это самому или взять готовый сервис управления подписками — вопрос из той же серии, что и продавец записи: сервис берёт процент от оборота или фиксированную плату, зато закрывает различия площадок, отчётность и хвост крайних случаев. Считайте по той же формуле порога.
Метаданные и декларации — часть сборки, а не документ
Витрина и декларации — это данные, которые обязаны соответствовать коду. Расхождение ловится автоматикой площадки и переводит вас из класса «оформление» в класс «доверие», который стоит на порядок дороже. Поэтому декларацию лучше не писать, а генерировать из инвентаря зависимостей.
# sdk-inventory.yaml — источник правды для декларации о данных и для юриста
sdks:
- name: analytics-core
version: "4.2.1"
purpose: "продуктовая аналитика"
collects: [device_id, app_version, screen_views]
linked_to_user: true # связывается с аккаунтом
used_for_tracking: false # не используется для рекламы у третьих лиц
license: Apache-2.0
- name: crash-reporter
version: "2.9.0"
purpose: "диагностика падений"
collects: [crash_logs, device_model, os_version]
linked_to_user: false
used_for_tracking: false
license: MIT
- name: ads-network
version: "7.0.0"
purpose: "монетизация рекламой"
collects: [advertising_id, coarse_location, ip_address]
linked_to_user: true
used_for_tracking: true # требует системного согласия на отслеживание
license: proprietary
Из такого файла генерируются три разные вещи: анкета о собираемых данных для каждой площадки, экран «Лицензии» в приложении (атрибуция обязательна даже для разрешительных лицензий — см. лицензии) и список обработчиков персональных данных для юридических документов. Как выглядит результат такого перечня в готовом виде, видно в политике обработки персональных данных этого портала: там перечислены цели, сроки и кому данные передаются. Магазины требуют примерно того же, только в виде анкеты.
Отдельная строка того же класса — экспортная декларация о криптографии: при загрузке сборки площадка спрашивает, использует ли приложение шифрование и подпадает ли оно под исключения. Ответ «не знаю» останавливает релиз, а неверный ответ создаёт проблему совсем другого масштаба. Разбор — в главе про ограничения.
Возрастной рейтинг тоже собирается анкетой: вы отвечаете на вопросы о содержании, а система выдаёт рейтинги для разных стран. Врать в анкете дорого: несоответствие обнаруживается пользовательскими жалобами, а не ревью, и приводит к снятию с публикации. Подробно про рейтинги и то, где они становятся отдельной статьёй расходов, — в дистрибуции игр.
Не только мобильные: тот же шаблон везде
«Витрина + касса + ревью + канал обновлений» — не мобильная специфика, а общий шаблон, который повторяется в десятке мест с разной жёсткостью.
Несколько ориентиров по состоянию на середину 2026 года, которые полезно знать при выборе:
- Магазины расширений браузера проверяют жёстче мобильных при почти нулевой монетизации: расширение имеет доступ ко всем страницам, поэтому ревью упирается в минимальность разрешений и запрет удалённого кода. Встроенной кассы в них, как правило, уже нет — деньги берут своим бэкендом, то есть комиссия ноль, а весь биллинг ваш.
- Каталоги плагинов для сред разработки берут заметно меньше мобильных магазинов, порядка 15 процентов, и ревью там мягче — аудитория профессиональная, а последствия ошибки меньше.
- Менеджеры пакетов и репозитории дистрибутивов — «магазины без кассы»: ревью бывает строгим (пакет в дистрибутиве проверяют мейнтейнеры), комиссии нет, потому что нет продажи. Это канал распространения, а не канал денег; см. упаковку и установку.
- Маркетплейсы облачных провайдеров ближе к каналу продаж для организаций: комиссия ниже мобильной, зато сделка идёт через закупочный процесс покупателя, и главная ценность — списание оплаты с уже согласованного облачного бюджета. Об этом — в главе о каналах.
- Консольные магазины — самый закрытый вариант: нужен статус разработчика, комплект для разработки, сертификация со своим списком технических требований. Разбор — в дистрибуции игр.
Общий вывод простой: чем шире полномочия вашего кода на устройстве пользователя, тем жёстче ревью, и это правильно. Расширение браузера видит банковский кабинет, мобильное приложение — геолокацию и контакты, пакет в дистрибутиве ставится с правами суперпользователя. Строгость пропорциональна возможному ущербу, а не жадности площадки.
Экономика присутствия: считать надо не только процент
Постоянные издержки магазина обычно невелики: взнос разработчика порядка ста долларов США в год для крупных мобильных площадок, где-то единоразовый взнос в районе двадцати пяти долларов, устройства для проверки, сертификаты. Настоящие расходы в другом:
- Замедленный релизный цикл. Каждое исправление стоит не «час разработки», а «час разработки плюс ревью плюс раскатка». Это меняет экономику мелких багов: дешевле собрать десять исправлений в один релиз, чем выпускать по одному. Прямое следствие — вам нужны серверные выключатели для всего, что может сломаться.
- Хвост старых версий. Часть пользователей не обновляется никогда. Ваш API обязан работать со сборками годичной давности, а иногда и старше; см. обновления и версии.
- Постоянная работа по чужим требованиям. Новый обязательный SDK, новая декларация, новое системное согласие — это регулярный поток задач, который надо закладывать в план команды, а не считать форс-мажором.
- Невозможность мгновенного отката. См. выше: цена дефекта в магазинном приложении выше, чем в вебе, потому что откат не мгновенный. Это аргумент за более строгий контроль качества перед релизом, а не за «выкатим и посмотрим».
Собранная воедино стоимость канала выглядит так: комиссия плюс налоги плюс возвраты плюс конвертация плюс постоянные взносы плюс дополнительная стоимость каждого релиза плюс поддержка старых версий. Сравнивать со «своим сайтом» надо целиком, включая стоимость привлечения и стоимость собственного комплаенса, иначе сравнение всегда ложно выигрывает в пользу сайта.
Что спросить у юриста
Юридические вопросы здесь настоящие, и решать их самостоятельно нельзя. Полезно принести юристу не проблему, а конкретные вопросы:
- Кто является продавцом записи по нашей схеме и в каких странах у нас возникают налоговые обязанности при продаже через магазин и при продаже с сайта?
- Можем ли мы в стране X упоминать в приложении оплату на своём сайте, и в какой форме?
- Наш продукт — цифровой товар или услуга в смысле правил площадки и в смысле налогового законодательства? Ответы могут не совпадать.
- Как соотносятся наша политика возвратов и правила площадки, и что мы обязаны написать в оферте? Живой пример формулировок — оферта и условия возврата этого портала.
- Что мы обязаны раскрывать в анкете о персональных данных с учётом законодательства нашей юрисдикции, а не только правил магазина?
- Каковы риски по возрастному рейтингу и пользовательскому контенту, и какая модерация считается достаточной?
Правило простое: где вопрос про то, что можно написать в договоре или что мы обязаны государству, — это к юристу. Где вопрос про то, что делает код, — это к вам, и юрист без вашего ответа работать не сможет.
Типичные ошибки
- Считать комиссию единственной статьёй. Налог, конвертация, возвраты и задержка выплаты вместе дают ещё пять-десять процентов, и они не видны, пока не сверишь отчёт о выплатах вручную.
- Ставить дату релиза до одобрения. Маркетинг куплен, ревью не прошло, ускоренное рассмотрение на такое не дают. Дата назначается после статуса «готово к выпуску», а не до подачи.
- Публиковать автоматически после одобрения. Теряется контроль над днём и часом выката.
- Проверять чеки на клиенте. Приводит к бесплатным подпискам, которые обнаруживаются по расхождению отчёта площадки и вашей базы, иногда спустя месяцы.
- Хранить право на функциональность в магазине, а не у себя. Ломает кроссплатформенность и делает миграцию на другую кассу невозможной.
- Писать декларацию о данных вручную. Она устаревает при первом обновлении рекламного SDK.
- Спорить в апелляции о трактовке. Недели ожидания и тот же ответ; быстрее исправить продукт.
- Считать флаги способом обойти ревью. Это не «хитрость», а тот класс нарушения, за который теряют аккаунт.
- Строить план на снижении комиссии регулятором. Номинальная ставка падает, эффективная — нет.
- Не иметь связи с пользователями вне магазина. Если приложение снимут, вы не сможете даже объяснить людям, что произошло.
Мини-итог
Магазин продаёт вам четыре вещи одним пакетом: витрину, кассу, доверие и канал обновлений. Плата за пакет — не только процент, но и потеря контроля над релизным календарём и над правилами игры. Считайте эффективную ставку целиком: комиссия, налог, конвертация, возвраты, задержка выплаты, удорожание каждого релиза. Сравнивайте её не с нулём, а со стоимостью самостоятельного привлечения покупателя и самостоятельного налогового комплаенса.
Правила площадки — это требования к архитектуре: запрет на доставку кода мимо магазина, обязательные механизмы платформы, соответствие деклараций реальному поведению SDK. Ревью — очередь с хвостом распределения в недели и правом отказать; планируйте по хвосту, публикуйте вручную, держите ускоренное рассмотрение для аварий. Отказы классифицируйте по цене в днях и превращайте каждый в пункт релизного чек-листа. И проектируйте так, чтобы способ оплаты был конфигурацией: правила меняются чаще, чем вы успеваете переписывать код.
Источники
- Правила ревью App Store — https://developer.apple.com/app-store/review/guidelines/
- Политики Google Play для разработчиков — https://play.google/developer-content-policy/
- Программа сниженной ставки для небольших разработчиков — https://developer.apple.com/app-store/small-business-program/
- Серверные API для проверки покупок — https://developer.apple.com/documentation/appstoreserverapi и https://developers.google.com/android-publisher
- Манифесты приватности и обязательные декларации — https://developer.apple.com/documentation/bundleresources/privacy_manifest_files, раздел о безопасности данных Google Play — https://support.google.com/googleplay/android-developer/answer/10787469
- Правила Microsoft Store — https://learn.microsoft.com/windows/apps/publish/store-policies
- Документация Steamworks для издателей — https://partner.steamgames.com/doc/home
- Digital Markets Act и его применение — https://digital-markets-act.ec.europa.eu/
- Международная система возрастных рейтингов IARC — https://www.globalratings.com/
- Отраслевые отчёты по подписочной экономике как источник порядков величин — https://www.revenuecat.com/state-of-subscription-apps/
Что дальше
Всё, что разобрано здесь, в играх проявляется в предельной форме: магазин часто единственный практичный канал, возрастной рейтинг обязателен и платен, региональные цены — отдельная дисциплина, а консоли добавляют сертификацию и физический комплект разработчика. Об этом следующая глава: Дистрибуция игр: магазины, консоли, рейтинги, региональные цены.