Flutter - Обработка событий пейвола
Этот гайд охватывает обработку событий для покупок, восстановлений, выбора продуктов и отображения пейвола. Также необходимо реализовать обработку кнопок (закрытие пейвола, открытие ссылок и т.д.). Подробнее см. в нашем гайде по обработке действий с кнопками.
Пейволы, настроенные с помощью Paywall Builder, не требуют дополнительного кода для совершения и восстановления покупок. Однако они генерируют события, на которые ваше приложение может реагировать. К таким событиям относятся нажатия кнопок (кнопки закрытия, URL-адреса, выбор продуктов и т. д.), а также уведомления о действиях, связанных с покупками на пейволе. Узнайте ниже, как обрабатывать эти события.
Это руководство предназначено только для пейволов нового Paywall Builder, которые требуют Adapty SDK v3.0 или выше.
Чтобы управлять процессами на экране пейвола или отслеживать их, реализуйте методы AdaptyUIPaywallsEventsObserver и установите наблюдатель до отображения любого экрана:
AdaptyUI().setPaywallsEventsObserver(this);
Хотите увидеть реальный пример интеграции Adapty SDK в мобильное приложение? Посмотрите наши примеры приложений — они демонстрируют полную настройку: отображение пейволов, совершение покупок и другие базовые функции.
События, генерируемые пользователем
Пейвол появился
Этот метод вызывается, когда экран пейвола отображается на экране.
На iOS также вызывается, когда пользователь нажимает на кнопку web-пейвола внутри пейвола, и web-пейвол открывается во встроенном браузере.
void paywallViewDidAppear(AdaptyUIPaywallView view) {
}
Пейвол скрылся
Этот метод вызывается, когда экран пейвола закрывается.
На iOS также вызывается, когда веб-пейвол, открытый из пейвола во встроенном браузере, исчезает с экрана.
void paywallViewDidDisappear(AdaptyUIPaywallView view) {
}
Выбор продукта
Если продукт выбран для покупки (пользователем или системой), будет вызван этот метод:
void paywallViewDidSelectProduct(AdaptyUIPaywallView view, String productId) {
}
Пример события (нажмите, чтобы развернуть)
{
"productId": "premium_monthly"
}Начало покупки
Если пользователь инициирует процесс покупки, будет вызван этот метод:
void paywallViewDidStartPurchase(AdaptyUIPaywallView view, AdaptyPaywallProduct product) {
}
Пример события (нажмите, чтобы развернуть)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}Завершённая покупка
Этот метод вызывается, когда покупка прошла успешно, пользователь отменил её или покупка находится в состоянии ожидания:
void paywallViewDidFinishPurchase(AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchaseResult) {
switch (purchaseResult) {
case AdaptyPurchaseResultSuccess(profile: final profile):
// успешная покупка
break;
case AdaptyPurchaseResultPending():
// покупка ожидает подтверждения
break;
case AdaptyPurchaseResultUserCancelled():
// пользователь отменил покупку
break;
default:
break;
}
}
Примеры событий (нажмите, чтобы раскрыть)
// Successful purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "AdaptyPurchaseResultSuccess",
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
}
}
}
}
// Pending purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "AdaptyPurchaseResultPending"
}
}
// User cancelled purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "AdaptyPurchaseResultUserCancelled"
}
}Мы рекомендуем закрыть экран в этом случае. Подробнее о закрытии экрана пейвола читайте в разделе Реагирование на действия кнопок.
Завершение навигации к веб-оплате
Этот метод вызывается после попытки открыть веб-пейвол для конкретного продукта. Это включает как успешные, так и неудачные попытки навигации:
void paywallViewDidFinishWebPaymentNavigation(AdaptyUIPaywallView view,
AdaptyPaywallProduct? product,
AdaptyError? error) {
}
Параметры:
| Параметр | Описание |
|---|---|
| product | Объект AdaptyPaywallProduct, для которого был открыт веб-пейвол. Может быть null. |
| error | Объект AdaptyError, если навигация по веб-пейволу завершилась с ошибкой; null, если навигация успешна. |
Примеры событий (нажмите, чтобы раскрыть)
// Successful navigation
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": null
}
// Failed navigation
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "web_navigation_failed",
"message": "Failed to open web paywall",
"details": {
"underlyingError": "Browser unavailable"
}
}
}Неудачная покупка
Этот метод вызывается, когда покупка завершается с ошибкой (например, из-за проблем с оплатой или сетевых ошибок). Он не срабатывает при отмене покупки пользователем или для отложенных транзакций — эти случаи обрабатываются в paywallViewDidFinishPurchase:
void paywallViewDidFailPurchase(AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyError error) {
}
Пример события (нажмите, чтобы развернуть)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "purchase_failed",
"message": "Purchase failed due to insufficient funds",
"details": {
"underlyingError": "Insufficient funds in account"
}
}
}Восстановление начато
Если пользователь инициирует процесс восстановления покупок, будет вызван этот метод:
void paywallViewDidStartRestore(AdaptyUIPaywallView view) {
}
Успешное восстановление
Если восстановление покупки прошло успешно, будет вызван следующий метод:
void paywallViewDidFinishRestore(AdaptyUIPaywallView view, AdaptyProfile profile) {
}
Пример события (нажмите, чтобы развернуть)
{
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
},
"subscriptions": [
{
"vendorProductId": "premium_monthly",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
]
}
}Мы рекомендуем закрывать экран, если у пользователя есть требуемый accessLevel. Обратитесь к разделу Статус подписки, чтобы узнать, как его проверить, и к разделу Реакция на действия кнопок, чтобы узнать, как закрыть экран пейвола.
Ошибка восстановления
Если восстановление покупки завершается с ошибкой, будет вызван этот метод:
void paywallViewDidFailRestore(AdaptyUIPaywallView view, AdaptyError error) {
}
Пример события (нажмите, чтобы развернуть)
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}Загрузка данных и рендеринг
Ошибки загрузки продуктов
Если вы не передаёте массив продуктов при инициализации, AdaptyUI самостоятельно запросит нужные объекты с сервера. Если эта операция завершится неудачей, AdaptyUI сообщит об ошибке, вызвав этот метод:
void paywallViewDidFailLoadingProducts(AdaptyUIPaywallView view, AdaptyError error) {
}
Пример события (нажмите, чтобы развернуть)
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}Ошибки рендеринга
Если во время рендеринга интерфейса возникает ошибка, она будет передана через вызов этого метода. По умолчанию (начиная с v3.15.2) пейвол автоматически закрывается при ошибке рендеринга, но при необходимости это поведение можно переопределить.
void paywallViewDidFailRendering(AdaptyUIPaywallView view, AdaptyError error) {
// Default behavior: view.dismiss()
// Override with custom logic if needed, for example:
// - Log the error
// - Show an error message to the user
}
Пример события (нажмите, чтобы развернуть)
{
"error": {
"code": "rendering_failed",
"message": "Failed to render paywall interface",
"details": {
"underlyingError": "Invalid paywall configuration"
}
}
}В обычной ситуации такие ошибки возникать не должны, поэтому если вы столкнулись с подобной проблемой — пожалуйста, сообщите нам.