Включение покупок с помощью пейволов в Flutter SDK
Чтобы включить встроенные покупки, нужно понять три ключевых понятия:
- Продукты — всё, что пользователи могут купить (подписки, расходуемые покупки, пожизненный доступ).
- Пейволы — конфигурации, определяющие, какие продукты предлагать. В Adapty пейволы — единственный способ получить продукты, но такой подход позволяет менять предложения, цены и наборы продуктов без изменений в коде приложения.
- Плейсменты — где и когда вы показываете пейволы в приложении (например,
main,onboarding,settings). Вы настраиваете пейволы для плейсментов в дашборде, а затем запрашиваете их по ID плейсмента в коде. Это упрощает запуск A/B-тестов и показ разных пейволов разным пользователям.
Adapty предлагает три способа включить покупки в приложении. Выберите подходящий в зависимости от требований вашего приложения:
| Реализация | Сложность | Когда использовать |
|---|---|---|
| Adapty Paywall Builder | ✅ Просто | Вы создаёте готовый пейвол в no-code конструкторе. Adapty автоматически отрисовывает его и берёт на себя весь процесс покупки, валидацию чеков и управление подписками. |
| Пейволы, созданные вручную | 🟡 Средне | Вы реализуете UI пейвола в коде приложения, но всё равно получаете объект пейвола из Adapty для гибкости в управлении продуктами. См. гайд. |
| Observer mode | 🔴 Сложно | У вас уже есть собственная инфраструктура обработки покупок, и вы хотите продолжать её использовать. Учтите, что observer mode имеет ограничения в Adapty. См. статью. |
Шаги ниже показывают, как реализовать пейвол, созданный в Paywall Builder.
Если вы не хотите использовать Paywall Builder, см. гайд по обработке покупок в пейволах, созданных вручную.
Чтобы отобразить пейвол, созданный в Paywall Builder, в коде приложения нужно всего лишь:
- Получить пейвол: запросить пейвол из Adapty.
- Показать пейвол — Adapty сам обработает покупки: отобразить контейнер пейвола в приложении.
- Обработать действия кнопок: связать действия пользователя на пейволе с реакцией приложения на них — например, открыть ссылку или закрыть пейвол при нажатии кнопок.
Перед началом работы
Выполните следующие шаги:
- Подключите приложение к App Store и/или Google Play в дашборде Adapty.
- Создайте продукты в Adapty.
- Создайте пейвол и добавьте в него продукты.
- Создайте плейсмент и добавьте пейвол в него.
- Установите и активируйте Adapty SDK в коде приложения.
Самый быстрый способ выполнить эти шаги — следовать быстрому старту или создать пейволы и плейсменты с помощью Developer CLI.
1. Получите пейвол
Ваши пейволы связаны с плейсментами, настроенными в дашборде. Плейсменты позволяют показывать разные пейволы разным аудиториям или запускать A/B-тесты.
Чтобы получить пейвол, созданный в Paywall Builder, нужно:
-
Получить объект
paywallпо ID плейсмента с помощью методаgetPaywallи проверить, является ли он пейволом, созданным в конструкторе, с помощью свойстваhasViewConfiguration. -
Создать представление пейвола с помощью метода
createPaywallView. Представление содержит элементы UI и стили, необходимые для отображения пейвола.
Чтобы получить конфигурацию представления, необходимо включить переключатель Show on device в Paywall Builder. В противном случае вы получите пустую конфигурацию представления, и пейвол не будет отображён.
try {
final paywall = await Adapty().getPaywall(placementId: "YOUR_PLACEMENT_ID", locale: "en");
// the requested paywall
} on AdaptyError catch (adaptyError) {
// handle the error
} catch (e) {
}
try {
final view = await AdaptyUI().createPaywallView(
paywall: paywall,
);
} on AdaptyError catch (e) {
// handle the error
} catch (e) {
// handle the error
}
2. Отобразите пейвол
Теперь, когда у вас есть конфигурация пейвола, достаточно добавить несколько строк для его отображения.
Чтобы отобразить пейвол, вызовите метод view.present() на объекте view, созданном методом createPaywallView. Каждый объект view можно использовать только один раз. Если нужно снова показать пейвол, вызовите createPaywallView ещё раз, чтобы создать новый экземпляр view.
try {
await view.present();
} on AdaptyError catch (e) {
// handle the error
} catch (e) {
// handle the error
}
Подробнее о том, как отобразить пейвол, см. наш гайд.
3. Обработайте действия кнопок
Когда пользователи нажимают кнопки на пейволе, Flutter SDK автоматически обрабатывает покупки и восстановление. Однако у других кнопок есть пользовательские или предопределённые ID, и действия по ним нужно обрабатывать в коде.
Чтобы контролировать или отслеживать процессы на экране пейвола, реализуйте методы AdaptyUIPaywallsEventsObserver и установите наблюдатель перед показом любого экрана. Если пользователь выполнил какое-либо действие, будет вызван paywallViewDidPerformAction, и приложение должно отреагировать в зависимости от ID действия.
Например, на вашем пейволе, скорее всего, есть кнопка закрытия и ссылки для открытия (например, условия использования и политика конфиденциальности). Поэтому нужно обрабатывать действия с ID Close и OpenUrl.
class _PaywallScreenState extends State<PaywallScreen> implements AdaptyUIPaywallsEventsObserver {
@override
void initState() {
super.initState();
// Register this class as the paywalls event observer
AdaptyUI().setPaywallsEventsObserver(this);
}
// This method is called when user performs an action on the paywall UI
@override
void paywallViewDidPerformAction(AdaptyUIPaywallView view, AdaptyUIAction action) {
switch (action) {
case const CloseAction():
case const AndroidSystemBackAction():
view.dismiss();
break;
case OpenUrlAction(url: final url):
// Open the URL using url_launcher package
_launchUrl(url);
break;
}
}
// Helper method to launch URLs
Future<void> _launchUrl(String url) async {
try {
final Uri uri = Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
} else {
// Handle case where URL cannot be launched
print('Could not launch $url');
}
} catch (e) {
// Handle any errors
print('Error launching URL: $e');
}
}
}
Следующие шаги
Есть вопросы или возникли проблемы? Загляните на наш форум поддержки, где можно найти ответы на распространённые вопросы или задать свой. Наша команда и сообщество всегда готовы помочь!
Ваш пейвол готов к отображению в приложении. Протестируйте покупки в песочнице App Store или Google Play Store, чтобы убедиться, что тестовая покупка через пейвол проходит успешно.
Теперь нужно проверить уровень доступа пользователей, чтобы показывать пейвол или открывать доступ к платным функциям только нужным пользователям.
Полный пример
Вот как все эти шаги можно объединить в приложении.
void main() async {
runApp(MaterialApp(home: PaywallScreen()));
}
class PaywallScreen extends StatefulWidget {
@override
State<PaywallScreen> createState() => _PaywallScreenState();
}
class _PaywallScreenState extends State<PaywallScreen> implements AdaptyUIPaywallsEventsObserver {
@override
void initState() {
super.initState();
// Register this class as the paywalls event observer
AdaptyUI().setPaywallsEventsObserver(this);
_showPaywallIfNeeded();
}
Future<void> _showPaywallIfNeeded() async {
try {
final paywall = await Adapty().getPaywall(
placementId: 'YOUR_PLACEMENT_ID',
);
if (!paywall.hasViewConfiguration) return;
final view = await AdaptyUI().createPaywallView(paywall: paywall);
await view.present();
} catch (_) {
// Handle any errors (network, SDK issues, etc.)
}
}
// This method is called when user performs an action on the paywall UI
@override
void paywallViewDidPerformAction(AdaptyUIPaywallView view, AdaptyUIAction action) {
switch (action) {
case const CloseAction():
case const AndroidSystemBackAction():
view.dismiss();
break;
case OpenUrlAction(url: final url):
// Open the URL using url_launcher package
_launchUrl(url);
break;
}
}
// Helper method to launch URLs
Future<void> _launchUrl(String url) async {
try {
final Uri uri = Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
} else {
// Handle case where URL cannot be launched
print('Could not launch $url');
}
} catch (e) {
// Handle any errors
print('Error launching URL: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Adapty Paywall Example')),
body: Center(
// Add a button to re-trigger the paywall for testing purposes
child: ElevatedButton(
onPressed: _showPaywallIfNeeded,
child: Text('Show Paywall'),
),
),
);
}
}