Freemium-аддоны и пакеты
Freemium-дополнение бесплатно устанавливается и бесплатно работает — но часть его возможностей остаётся закрытой, пока владелец сервера не купит пакет (например Pro или Ultra) в маркетплейсе. Это середина между полностью бесплатным дополнением и премиум: установить может каждый, платными являются только дополнительные функции.
Платные ресурсы пока недоступны сторонним авторам
Freemium сейчас доступен только аккаунтам с доступом к панели на panomc.com — как и премиум, и для дополнений, и для тем. Продажа в маркетплейсе сторонним авторам пока не открыта, поэтому на шаге выбора цены оба варианта отключены, а API отклоняет их для всех остальных. Эта страница описывает, как работает freemium, чтобы вы могли планировать; пока программа не открыта, публикуйте дополнение бесплатным.
Freemium и премиум в одной таблице
| Премиум | Freemium | |
|---|---|---|
| Может ли установить любой? | Нет — нужна покупка | Да |
| Работает ли без оплаты? | Нет, отказывается запускаться | Да, платные функции закрыты |
| Что продаётся | Всё дополнение | Отдельные пакеты (Pro, Ultra …) |
| Как проверяет ваш код | requireValidLicense() при запуске | hasTier("pro") там, где нужна функция |
| Где указана цена | Цена ресурса | Цена каждого пакета |
Модели взаимоисключающие. Freemium-дополнение, запрашивающее лицензию, намеренно не запускается — выберите одну.
Шаг 1 — Пометьте дополнение как freemium
В gradle.properties:
pluginFreemium=trueЭто всё объявление. Сборка записывает его в манифест вашего jar, и Pano читает его при загрузке — панель знает, что дополнение freemium, ещё до его запуска. Свежий pano-boilerplate-plugin уже содержит это свойство со значением false и комментарием.
Убирайте проверку лицензии при переходе
Boilerplate вызывает licenseClient.requireValidLicense() в onStart. Удалите этот вызов при переходе на freemium — совмещение двух моделей это единственная комбинация, которую Pano отклоняет.
Шаг 2 — Закройте платные функции в коде
Оберните то, что открывает пакет:
override suspend fun onStart() {
if (hasTier("pro")) {
enableProFeature()
} else {
logger.info("Pro-функции закрыты")
}
}hasTier(id) означает «хотя бы этот пакет». Пакеты упорядочены, поэтому сервер, купивший Ultra, проходит и hasTier("pro") — перечислять более высокие пакеты не нужно, а добавление нового верхнего уровня позже не требует изменений в коде.
activeTier() возвращает id купленного пакета (или null) — удобно для лога или страницы состояния. Для собственно ограничения используйте hasTier.
Покупка не открывает мгновенно
Ваше дополнение спрашивает о пакетах при запуске, а покупка, сделанная позже, на сервер не приходит сама. Пока что-нибудь не перепроверит, функция остаётся закрытой. Для этого и нужна кнопка Обновить на странице дополнения в панели — см. В панели. Ответы берутся из кеша, поэтому hasTier никогда не блокирует ваш код.
Оба метода работают только в дополнении, объявившем pluginFreemium=true; вызов из обычного дополнения бросает исключение, поэтому ошибка выбора модели всплывает сразу, а не превращается в тихое false.
Шаг 3 — Определите пакеты в маркетплейсе
Пакеты публикуются магазином, а не объявляются в коде. Вы задаёте их на своём ресурсе — на шаге цены в мастере создания либо позже в редакторе ресурса — выбрав план Freemium:
| Поле | Примечания |
|---|---|
| ID пакета | Строчный слаг (pro, ultra). Именно его ваш код передаёт в hasTier() — держите его стабильным, смена ничего не откроет. |
| Название | То, что видят покупатели (Pro). |
| Цена | Разовая, больше 0. |
| Возможности | Список, показываемый покупателям под пакетом. |
Порядок списка — это цепочка улучшений: первый пакет самый низкий, следующий выше него. Поля уровня заполнять не нужно — перемещение пакета вверх или вниз и есть способ изменить ранг, поэтому совпадающие или пропущенные уровни невозможны.
До 5 пакетов на дополнение, до 10 возможностей в каждом.
Держите id и код синхронными
Какие пакеты существуют, решает магазин; какие id запрашивать — ваш jar. Если они разойдутся — например, pro переименован в professional — проверка тихо перестанет совпадать. Считайте id частью вашего публичного API.
В панели
На странице дополнения в панели сервера freemium-дополнение получает:
- значок Freemium рядом с отметкой проверки — и в списке, и на странице дополнения;
- карточку Пакеты с актуальным каталогом, активным пакетом и кнопкой покупки/улучшения — это представление отдаётся panomc.com и встраивается, поэтому всегда отражает магазин, а не устаревшую копию;
- кнопку Обновить — аналог обновления премиум-лицензии. Она перечитывает, чем владеет сервер: это выход из ситуации «купил Pro, а дополнение всё ещё пишет, что закрыто».
Для всего этого в панели нужен подключённый аккаунт Pano; без него панель сначала предложит его подключить.
Что Pano отклоняет
Полезно знать заранее:
- Freemium и цена на одном ресурсе — freemium означает бесплатную установку, он не может стоить денег.
- Freemium у темы — покупки внутри дополнения относятся к дополнениям.
- Freemium-дополнение, вызывающее
requireValidLicense()— взаимоисключает премиум; дополнение не запустится. hasTier()из не-freemium дополнения — бросает исключение, чтобы поймать неверную модель сразу.- Повторяющиеся id пакетов, пустые названия, цены 0 и ниже — отклоняются при сохранении пакетов.
Что дальше
- Премиум и лицензирование — модель «всё или ничего», если хотите продавать дополнение целиком.
- Сборка и публикация — поток релиза и создание ресурса, к которому привязаны пакеты.
- Конфигурация манифеста —
pluginFreemiumв контексте остальногоgradle.properties. - Разработка бэкенда — где живут
onStartи ваш классPanoPlugin.