处理流程与付费墙事件 - 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:打开点击的 URL 并保持流程开启。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 | 当流程显示给用户时触发。在 iOS 上,当用户点击流程内的网页付费墙按钮并在应用内浏览器中打开网页付费墙时也会触发。 |
| onDisappeared | 仅限模态弹出模式:当用户关闭流程时触发。在 iOS 上,从流程中打开的网页付费墙在应用内浏览器中消失时也会触发。 |
| onWebPaymentNavigationFinished | 尝试打开网页付费墙进行购买后触发,无论成功或失败。 |
| onAnalytics | 保留用于流程中的自定义分析事件。目前流程不会向您的代码发送此类事件,无需实现。 |
| onRequestAppReview | 保留用于流程中的应用评价请求。目前流程不会触发应用评价请求,无需实现。 |
| onRequestPermission | 保留用于流程中的系统权限请求(如推送通知或相机访问)。目前流程不会触发权限请求,无需实现。 |
| onObserverPurchaseInitiated | 仅限观察者模式:当用户在流程中点击购买按钮时触发。Adapty 不会执行购买——请使用您自己的购买代码完成购买,然后将交易报告给 Adapty。详见下方在观察者模式下处理购买。 |
| onObserverRestoreInitiated | 仅限观察者模式:当用户在流程中点击恢复按钮时触发。Adapty 不会执行恢复——请自行完成恢复,然后报告已恢复的交易。详见下方在观察者模式下处理购买。 |
在观察者模式下处理购买
如果你以观察者模式(observerMode: true)激活了 SDK 并展示了 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;
},
});本指南介绍购买、恢复、产品选择和付费墙渲染的事件处理方式。你还需要实现按钮处理功能(关闭付费墙、打开链接等)。详情请参阅按钮操作处理指南。
通过付费墙编辑工具配置的付费墙无需额外代码即可完成购买和恢复购买操作。不过,这些付费墙会生成一些事件供应用响应,包括按钮点击(关闭按钮、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 | 在尝试打开网页付费墙进行购买后触发,无论成功或失败。 |