Flutter - 处理付费墙事件
本指南涵盖购买、恢复、产品选择及付费墙渲染的事件处理。你还必须实现按钮处理(关闭付费墙、打开链接等)。详情请参阅按钮操作处理指南。
使用付费墙编辑工具配置的付费墙无需额外代码即可完成购买和恢复购买操作。但它们会生成一些事件,供你的应用响应。这些事件包括按钮点击(关闭按钮、URL、产品选择等)以及付费墙上与购买相关的操作通知。请阅读下文,了解如何响应这些事件。
本指南仅适用于新版付费墙编辑工具付费墙,需要 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"
}
}
}正常情况下不应出现此类错误,如果遇到,请告知我们。