Обработка событий флоу и пейвола — React Native
Этот гайд охватывает обработку событий для покупок, восстановлений, выбора продукта и отображения флоу. Вы также можете настроить обработку кнопок (закрытие флоу, открытие ссылок, пользовательские действия и т. д.). Подробнее см. в нашем гайде по обработке действий кнопок.
Флоу и пейволы, созданные с помощью Flow 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
{
//Record the event
}
// onDisappeared
{
//Record the event
}
// onWebPaymentNavigationFinished
{
//Record the event
}Вы можете зарегистрировать только нужные обработчики событий, а ненужные — пропустить. В этом случае лишние слушатели событий не создаются. Обязательных обработчиков событий нет.
Обработчики событий возвращают булево значение. Если возвращается true, процесс отображения считается завершённым: экран флоу закрывается, а слушатели событий для этого представления удаляются.
Некоторые обработчики событий имеют поведение по умолчанию, которое можно переопределить при необходимости:
onCloseButtonPress: закрывает флоу при нажатии кнопки закрытия.onUrlPress: открывает нажатую ссылку и оставляет флоу открытым.onAndroidSystemBack(только для модального отображения): оставляет флоу открытым при нажатии кнопки Back. Вернитеtrue, чтобы закрыть флоу.onRestoreCompleted: оставляет флоу открытым после успешного восстановления покупок. Вернитеtrue, чтобы закрыть флоу.onPurchaseCompleted: оставляет флоу открытым после завершения покупки. Вернитеtrue, чтобы закрыть флоу.onError: закрывает флоу, если его отрисовка завершилась с ошибкой.
Обработчики событий
| Обработчик события | Описание |
|---|---|
| onCustomAction | Вызывается, когда пользователь выполняет произвольное действие, например нажимает кастомную кнопку. |
| onUrlPress | Вызывается, когда пользователь нажимает на URL в вашем флоу. |
| onAndroidSystemBack | Только при модальном отображении: вызывается, когда пользователь нажимает системную кнопку Back на Android. |
| onCloseButtonPress | Вызывается, когда кнопка закрытия видна и пользователь нажимает её. Рекомендуется закрывать экран флоу в этом обработчике. |
| onPurchaseCompleted | Вызывается при завершении покупки — независимо от того, была ли она успешной, отменена пользователем или ожидает подтверждения. В случае успешной покупки возвращает обновлённый AdaptyProfile. Отмены пользователем и ожидающие платежи (например, требующие родительского подтверждения) вызывают это событие, а не onPurchaseFailed. |
| onPurchaseStarted | Вызывается, когда пользователь нажимает кнопку действия «Купить» для начала процесса покупки. |
| onPurchaseFailed | Вызывается, когда покупка завершается с ошибкой (например, из-за ограничений оплаты, недействительных продуктов, сбоев сети или ошибок верификации транзакций). Не вызывается при отмене пользователем или ожидающих платежах — в этих случаях срабатывает onPurchaseCompleted. |
| onRestoreStarted | Вызывается, когда пользователь начинает процесс восстановления покупок. |
| onRestoreCompleted | Вызывается при успешном восстановлении покупок и возвращает обновлённый AdaptyProfile. Рекомендуется закрывать экран, если у пользователя есть необходимый accessLevel. Подробнее см. в разделе Статус подписки. |
| onRestoreFailed | Вызывается при ошибке восстановления и возвращает AdaptyError. |
| onProductSelected | Вызывается, когда в представлении флоу выбран любой продукт, — позволяет отслеживать выбор пользователя до совершения покупки. |
| onError | Вызывается при ошибке во время рендеринга представления и возвращает AdaptyError. Такие ошибки не должны возникать — если вы с ними столкнулись, пожалуйста, сообщите нам. |
| onLoadingProductsFailed | Вызывается при ошибке загрузки продуктов и возвращает AdaptyError. Если вы не указали prefetchProducts: true при создании представления, AdaptyUI самостоятельно запросит необходимые объекты с сервера. |
| onAppeared | Вызывается, когда флоу отображается пользователю. На iOS также вызывается, когда пользователь нажимает кнопку веб-пейвола внутри флоу и веб-пейвол открывается во встроенном браузере. |
| onDisappeared | Только при модальном отображении: вызывается, когда пользователь закрывает флоу. На iOS также вызывается, когда веб-пейвол, открытый из флоу во встроенном браузере, исчезает с экрана. |
| onWebPaymentNavigationFinished | Вызывается после попытки открыть веб-пейвол для покупки — как при успехе, так и при ошибке. |
| onAnalytics | Зарезервировано для пользовательских аналитических событий из флоу. Флоу пока не отправляют их в ваш код, поэтому реализовывать его не нужно. |
| onRequestAppReview | Зарезервировано для запросов отзывов о приложении из флоу. Флоу пока не инициируют такие запросы, поэтому реализовывать его не нужно. |
| onRequestPermission | Зарезервировано для запросов системных разрешений (например, на push-уведомления или доступ к камере) из флоу. Флоу пока не инициируют запросы разрешений, поэтому реализовывать его не нужно. |
| onObserverPurchaseInitiated | Только в режиме наблюдателя: вызывается, когда пользователь нажимает кнопку покупки в флоу. Adapty не выполняет покупку — выполните её с помощью собственного кода, а затем передайте транзакцию в Adapty. См. раздел Обработка покупок в режиме наблюдателя ниже. |
| onObserverRestoreInitiated | Только в режиме наблюдателя: вызывается, когда пользователь нажимает кнопку восстановления в флоу. 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, выбор продуктов и т. д.), а также уведомления о действиях, связанных с покупками на пейволе. Ниже описано, как обрабатывать эти события.
Этот гайд предназначен исключительно для пейволов нового Paywall Builder, которые требуют 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 | Вызывается после попытки открыть веб-пейвол для совершения покупки — независимо от того, успешной она была или нет. |