Обработка событий флоу и пейвола — React Native
Этот гайд охватывает обработку событий для покупок, восстановлений, выбора продуктов и отображения флоу. Вы также можете настроить обработку кнопок (закрытие флоу, открытие ссылок, пользовательские действия и т. д.). Подробнее см. в нашем гайде по обработке действий кнопок.
Потоки и пейволы, созданные во Flow & Paywall Builder, не требуют дополнительного кода для совершения и восстановления покупок. Однако они генерируют события, на которые ваше приложение может реагировать. Эти события включают нажатия кнопок (кнопки закрытия, URL, выбор продуктов и т. д.), а также уведомления о действиях, связанных с покупками, происходящих в потоке. Узнайте, как реагировать на эти события, ниже.
Чтобы управлять процессами на экране флоу или отслеживать их в мобильном приложении, реализуйте обработчики событий:
Примеры событий (нажмите, чтобы развернуть)
// onCloseButtonPress
{
//Record the event
}
// onAndroidSystemBack
{
//Record the event
}
// onUrlPress
{
"url": "https://example.com/terms"
}
// onCustomAction
{
"actionId": "login"
}
// onProductSelected
{
"productId": "premium_monthly"
}
// onPurchaseStarted
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"price": {
"amount": 9.99,
"currencyCode": "USD",
"currencySymbol": "$",
"localizedString": "$9.99"
}
}
}
// onPurchaseCompleted - Success
{
"purchaseResult": {
"type": "success",
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
}
}
},
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"price": {
"amount": 9.99,
"currencyCode": "USD",
"currencySymbol": "$",
"localizedString": "$9.99"
}
}
}
// onPurchaseCompleted - Cancelled
{
"purchaseResult": {
"type": "user_cancelled"
},
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"price": {
"amount": 9.99,
"currencyCode": "USD",
"currencySymbol": "$",
"localizedString": "$9.99"
}
}
}
// onPurchaseFailed
{
"error": {
"code": "purchase_failed",
"message": "Purchase failed due to insufficient funds",
"details": {
"underlyingError": "Insufficient funds in account"
}
},
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"price": {
"amount": 9.99,
"currencyCode": "USD",
"currencySymbol": "$",
"localizedString": "$9.99"
}
}
}
// onRestoreCompleted
{
"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"
}
]
}
}
// onRestoreFailed
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}
// onError
{
"error": {
"code": "rendering_failed",
"message": "Failed to render flow interface",
"details": {
"underlyingError": "Invalid flow configuration"
}
}
}
// onLoadingProductsFailed
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}
// onAppeared
{
"view": {
"id": "3f8a1c7e-9b24-4d51-8e30-6c5b2a9f1d47",
"placementId": "onboarding_paywall",
"variationId": "d21c4b6a-57e8-4f39-b0a2-8c7e13f5d94b",
"locale": "es"
}
}
// onDisappeared
{
//Record the event
}
// onWebPaymentNavigationFinished
{
//Record the event
} Вы можете зарегистрировать только нужные обработчики событий, а ненужные — пропустить. В этом случае лишние слушатели событий не создаются. Обязательных обработчиков событий нет.
Обработчики событий возвращают булево значение. Если возвращается true, процесс отображения считается завершённым: экран флоу закрывается, а слушатели событий для этого представления удаляются.
Некоторые обработчики событий имеют поведение по умолчанию, которое можно переопределить при необходимости:
onCloseButtonPress: закрывает флоу при нажатии кнопки закрытия.onUrlPress: открывает нажатую ссылку и оставляет флоу открытым.onAndroidSystemBack(только для модального отображения): оставляет флоу открытым при нажатии кнопки Back. Вернитеtrue, чтобы закрыть флоу.onRestoreCompleted: оставляет флоу открытым после успешного восстановления покупок. Вернитеtrue, чтобы закрыть флоу.onPurchaseCompleted: оставляет флоу открытым после завершения покупки. Вернитеtrue, чтобы закрыть флоу.onError: закрывает флоу, если его отрисовка завершилась с ошибкой.
Обработчики событий
| Обработчик события | Описание |
|---|---|
| onCustomAction | Вызывается, когда пользователь выполняет пользовательское действие, например нажимает кастомную кнопку. |
| onUrlPress | Вызывается, когда пользователь нажимает на URL во флоу. |
| onAndroidSystemBack | Только для модального представления: вызывается, когда пользователь нажимает системную кнопку Android Back. |
| onCloseButtonPress | Вызывается, когда кнопка закрытия видима и пользователь нажимает на неё. Рекомендуется закрывать экран флоу в этом обработчике. |
| onPurchaseCompleted | Вызывается при завершении покупки — успешном, отменённом пользователем или ожидающем подтверждения. В случае успешной покупки предоставляет обновлённый AdaptyProfile. Отмены пользователем и ожидающие платежи (например, требующие родительского подтверждения) вызывают это событие, а не onPurchaseFailed. |
| onPurchaseStarted | Вызывается, когда пользователь нажимает кнопку «Купить», чтобы начать процесс покупки. |
| onPurchaseFailed | Вызывается при сбое покупки из-за ошибок (например, ограничений платежей, недопустимых продуктов, сетевых сбоев, ошибок верификации транзакций). Не вызывается при отмене пользователем или ожидающих платежах — в этих случаях вызывается onPurchaseCompleted. |
| onRestoreStarted | Вызывается, когда пользователь начинает процесс восстановления покупок. |
| onRestoreCompleted | Вызывается при успешном восстановлении покупок и предоставляет обновлённый AdaptyProfile. Рекомендуется закрывать экран, если у пользователя есть необходимый accessLevel. Подробнее см. в разделе Статус подписки. |
| onRestoreFailed | Вызывается при сбое процесса восстановления и предоставляет AdaptyError. |
| onProductSelected | Вызывается при выборе любого продукта во флоу, что позволяет отслеживать выбор пользователя до совершения покупки. |
| onError | Вызывается при возникновении ошибки в процессе рендеринга представления и предоставляет AdaptyError. Такие ошибки не должны возникать — если вы столкнулись с подобным, пожалуйста, сообщите нам. |
| onLoadingProductsFailed | Вызывается при сбое загрузки продуктов и предоставляет AdaptyError. Если вы не установили prefetchProducts: true при создании представления, AdaptyUI самостоятельно получит необходимые объекты с сервера. |
| onAppeared | Вызывается, когда флоу отображается пользователю, и предоставляет view, который появился — см. Аргумент view. На iOS также вызывается, когда пользователь нажимает кнопку веб-пейвола внутри флоу и веб-пейвол открывается во встроенном браузере. |
| onDisappeared | Только для модального представления: вызывается, когда флоу закрывается пользователем. На iOS также вызывается, когда веб-пейвол, открытый из флоу во встроенном браузере, исчезает с экрана. |
| onWebPaymentNavigationFinished | Вызывается после попытки открыть веб-пейвол для покупки — успешной или неудачной. |
| onAnalytics | Вызывается, когда флоу сообщает о событии аналитики, например о просмотре экрана. См. События аналитики ниже. |
| onRequestAppReview | Зарезервировано для запросов отзыва о приложении из флоу. Флоу пока не инициируют запросы отзывов, поэтому реализовывать этот обработчик не нужно. |
| onRequestPermission | Зарезервировано для запросов системных разрешений (например, push-уведомлений или доступа к камере) из флоу. Флоу пока не инициируют запросы разрешений, поэтому реализовывать этот обработчик не нужно. |
| onObserverPurchaseInitiated | Только для режима наблюдателя: вызывается, когда пользователь нажимает кнопку покупки во флоу. Adapty не выполняет покупку — совершите её с помощью собственного кода, а затем сообщите о транзакции в Adapty. См. Обработка покупок в режиме наблюдателя ниже. |
| onObserverRestoreInitiated | Только для режима наблюдателя: вызывается, когда пользователь нажимает кнопку восстановления во флоу. Adapty не выполняет восстановление — сделайте это самостоятельно, а затем сообщите о восстановленных транзакциях. См. Обработка покупок в режиме наблюдателя ниже. |
Аргумент view
Аргумент view требует React Native SDK версии 4.0.3 или выше. Из всех обработчиков флоу только onAppeared получает описание самого вью — объект FlowEventView со следующими полями:
| Field | Description |
|---|---|
| id | Идентификатор данного экземпляра представления. Он является внутренним для SDK и не соответствует ничему в дашборде Adapty. |
| placementId | Плейсмент, для которого был получен флоу. |
| variationId | Вариант, к которому был определён флоу, для атрибуции вашей собственной аналитики к A/B-тесту. |
| locale | Локализация флоу, с которой было построено представление. Отличается от запрошенной вами локали, если у флоу нет такой локализации. Считывайте её, чтобы привести остальную часть вашего экрана в соответствие с языком, на котором отобразился флоу. См. Использование локализаций и кодов локалей. |
События аналитики
const unsubscribe = view.setEventHandlers({
onAnalytics(name, params) {
return false; // keep the flow open
},
});Флоу отправляет событие flow_screen_showed каждый раз, когда пользователь открывает один из его экранов. Adapty учитывает эти события в собственной аналитике флоу и также передаёт их в ваше приложение, чтобы вы могли построить такую же воронку в своей аналитике.
| Параметр | Описание |
|---|---|
instanceId | Идентификатор экрана, который открыл пользователь. |
screen_order | Порядковый номер экрана во флоу. |
is_last_screen | true, если у экрана нет следующего шага. Флоу с ветвлением может завершаться на нескольких разных экранах — каждый из них возвращает true. |
Оба поля isBackendEvent и isCustomerEvent равны true для этого события: Adapty продолжает его учитывать, и ваше приложение тоже его получает.
Подробнее о том, что с ними делать, — в разделе Отслеживание просмотров экранов флоу.
Флоу также передаёт значения, которые пользователи вводят и выбирают. Подробнее — в разделе Обработка данных из флоу.
Обработка покупок в режиме наблюдателя
Если вы активировали SDK в режиме наблюдателя (observerMode: true) и показываете флоу, отрендеренный Adapty, SDK не выполняет покупки самостоятельно. Когда пользователь нажимает кнопку покупки или восстановления, SDK вызывает onObserverPurchaseInitiated или onObserverRestoreInitiated. Выполните покупку или восстановление с помощью собственного кода, управляйте индикатором загрузки флоу через предоставленные колбэки и после этого сообщите о транзакции в Adapty.
const unsubscribe = view.setEventHandlers({
onObserverPurchaseInitiated(product, onStartPurchase, onFinishPurchase) {
onStartPurchase(); // show the flow's loading indicator
myPurchaseApi(product.vendorProductId)
.then((transactionId) => adapty.reportTransaction(transactionId))
.finally(() => onFinishPurchase()); // hide the loading indicator
return false; // keep the flow open; dismiss it yourself after success
},
onObserverRestoreInitiated(onStartRestore, onFinishRestore) {
onStartRestore();
myRestoreApi()
.finally(() => onFinishRestore());
return false;
},
});Это руководство охватывает обработку событий для покупок, восстановлений, выбора продукта и отображения пейвола. Вам также необходимо реализовать обработку кнопок (закрытие пейвола, открытие ссылок и т. д.). Подробнее читайте в руководстве по обработке действий кнопок.
Пейволы, настроенные с помощью Paywall Builder, не требуют дополнительного кода для совершения и восстановления покупок. Однако они генерируют события, на которые ваше приложение может реагировать. К таким событиям относятся нажатия кнопок (кнопки закрытия, URL, выбор продуктов и т. д.), а также уведомления о действиях, связанных с покупками, совершённых на пейволе. Ниже описано, как реагировать на эти события.
Этот гайд охватывает только пейволы, созданные в старом конструкторе, для которых требуется Adapty SDK v3.0 или выше.
Для управления процессами на экране пейвола и мониторинга событий реализуйте обработчики событий:
Примеры событий (нажмите, чтобы развернуть)
// onCloseButtonPress
{
//Record the event
}
// onAndroidSystemBack
{
//Record the event
}
// onUrlPress
{
"url": "https://example.com/terms"
}
// onCustomAction
{
"actionId": "login"
}
// onProductSelected
{
"productId": "premium_monthly"
}
// onPurchaseStarted
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"price": {
"amount": 9.99,
"currencyCode": "USD",
"currencySymbol": "$",
"localizedString": "$9.99"
}
}
}
// onPurchaseCompleted - Success
{
"purchaseResult": {
"type": "success",
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
}
}
},
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"price": {
"amount": 9.99,
"currencyCode": "USD",
"currencySymbol": "$",
"localizedString": "$9.99"
}
}
}
// onPurchaseCompleted - Cancelled
{
"purchaseResult": {
"type": "user_cancelled"
},
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"price": {
"amount": 9.99,
"currencyCode": "USD",
"currencySymbol": "$",
"localizedString": "$9.99"
}
}
}
// onPurchaseFailed
{
"error": {
"code": "purchase_failed",
"message": "Purchase failed due to insufficient funds",
"details": {
"underlyingError": "Insufficient funds in account"
}
},
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"price": {
"amount": 9.99,
"currencyCode": "USD",
"currencySymbol": "$",
"localizedString": "$9.99"
}
}
}
// onRestoreCompleted
{
"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"
}
]
}
}
// onRestoreFailed
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}
// onRenderingFailed
{
"error": {
"code": "rendering_failed",
"message": "Failed to render paywall interface",
"details": {
"underlyingError": "Invalid paywall configuration"
}
}
}
// onLoadingProductsFailed
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}
// onPaywallShown
{
//Record the event
}
// onPaywallClosed
{
//Record the event
}
// onWebPaymentNavigationFinished
{
//Record the event
} Вы можете регистрировать только те обработчики событий, которые вам нужны, — остальные можно пропустить. Неиспользуемые обработчики событий при этом не создаются. Обязательных обработчиков нет.
Обработчики событий возвращают булево значение. Если возвращается true, процесс отображения считается завершённым: экран пейвола закрывается, а все слушатели событий для этого представления удаляются.
У некоторых обработчиков событий есть поведение по умолчанию, которое можно переопределить при необходимости:
onCloseButtonPress: закрывает пейвол при нажатии кнопки закрытия.onUrlPress: открывает нажатый URL и оставляет пейвол открытым.onAndroidSystemBack(только для модального представления): закрывает пейвол при нажатии кнопки Back.onRestoreCompleted: закрывает пейвол после успешного восстановления.onPurchaseCompleted: закрывает пейвол, если пользователь не отменил покупку.onRenderingFailed: закрывает пейвол, если его рендеринг завершился с ошибкой.
Обработчики событий
| Обработчик событий | Описание |
|---|---|
| onCustomAction | Вызывается, когда пользователь выполняет пользовательское действие, например нажимает кастомную кнопку. |
| onUrlPress | Вызывается, когда пользователь нажимает на URL в вашем пейволе. |
| onAndroidSystemBack | Только для модального представления: вызывается, когда пользователь нажимает системную кнопку Android Back. |
| onCloseButtonPress | Вызывается, когда кнопка закрытия видима и пользователь нажимает её. Рекомендуется закрывать экран пейвола в этом обработчике. |
| onPurchaseCompleted | Вызывается по завершении покупки — успешной, отменённой пользователем или ожидающей подтверждения. В случае успешной покупки возвращает обновлённый AdaptyProfile. Отмены пользователем и отложенные платежи (например, требующие родительского разрешения) вызывают это событие, а не onPurchaseFailed. |
| onPurchaseStarted | Вызывается, когда пользователь нажимает кнопку действия «Купить», чтобы начать процесс покупки. |
| onPurchaseFailed | Вызывается, когда покупка завершается с ошибкой (например, ограничения платежей, недействительные продукты, сетевые сбои, ошибки верификации транзакций). Не вызывается при отмене пользователем или отложенных платежах — в этих случаях вызывается onPurchaseCompleted. |
| onRestoreStarted | Вызывается, когда пользователь запускает процесс восстановления покупок. |
| onRestoreCompleted | Вызывается при успешном восстановлении покупок и возвращает обновлённый AdaptyProfile. Рекомендуется закрывать экран, если у пользователя есть требуемый accessLevel. О том, как это проверить, читайте в разделе Статус подписки. |
| onRestoreFailed | Вызывается, когда процесс восстановления завершается с ошибкой, и возвращает AdaptyError. |
| onProductSelected | Вызывается при выборе любого продукта в пейволе — позволяет отслеживать, что пользователь выбирает перед покупкой. |
| onRenderingFailed | Вызывается при возникновении ошибки во время рендеринга и возвращает AdaptyError. Такие ошибки не должны возникать, поэтому если вы столкнулись с ней — сообщите нам. |
| onLoadingProductsFailed | Вызывается при сбое загрузки продуктов и возвращает AdaptyError. Если при создании представления вы не задали prefetchProducts: true, AdaptyUI самостоятельно получит необходимые объекты с сервера. |
| onPaywallShown | Вызывается, когда пейвол отображается пользователю. На iOS также вызывается, когда пользователь нажимает кнопку веб-пейвола внутри пейвола и веб-пейвол открывается во встроенном браузере. |
| onPaywallClosed | Только для модального представления: вызывается, когда пользователь закрывает пейвол. На iOS также вызывается, когда веб-пейвол, открытый из пейвола во встроенном браузере, исчезает с экрана. |
| onWebPaymentNavigationFinished | Вызывается после попытки открыть веб-пейвол для совершения покупки — независимо от того, успешной она была или нет. |