在 Kotlin Multiplatform SDK 中通过 Flow 与付费墙编辑工具启用购买功能

本指南使用 Adapty Kotlin Multiplatform SDK v4 (beta) API。如果你使用的是 v3,请参阅迁移指南了解对应的方法名称。

要启用应用内购买,你需要了解以下三个核心概念:

  • 产品 – 用户可购买的内容(订阅、消耗型商品、永久授权)
  • 流程与付费墙 – 向用户展示产品的界面,使用无代码的流程与付费墙编辑工具构建,SDK 通过 getFlow 获取。如果你更倾向于用自己的代码构建 UI,请参阅实现自定义付费墙。
  • 版位 – 在应用中展示流程与付费墙的位置和时机(如 main、onboarding、settings)。在看板中将其关联到版位,然后在代码中通过版位 ID 来请求。这样可以轻松运行 A/B 测试,并向不同用户展示不同内容。

Adapty 为您提供三种在应用中开启购买功能的方式。请根据您的应用需求选择其中一种:

实现方式复杂度适用场景
Adapty Flow & 付费墙编辑工具✅ 简单您在无代码编辑工具中创建完整的、可直接购买的流程或付费墙。Adapty 自动渲染界面,并在后台处理所有复杂的购买逻辑、收据验证和订阅管理。
自定义付费墙🟡 中等您在应用代码中实现付费墙 UI,但仍从 Adapty 获取流程对象,以保持产品方案的灵活性。请参阅指南。
观察者模式🔴 复杂您已有自己的购买处理基础设施,并希望继续使用它。请注意,观察者模式在 Adapty 中存在一定限制。请参阅文章。
Important

以下步骤说明如何在应用代码中展示通过 Adapty 付费墙编辑工具创建的流程或付费墙。

如果你希望自己构建付费墙 UI,请参阅实现自定义付费墙。

要在应用中展示通过 Adapty 付费墙编辑工具创建的流程或付费墙,你只需在代码中完成以下操作:

  1. 获取流程或付费墙:从 Adapty 获取。
  2. 展示付费墙,Adapty 将为你处理购买逻辑:在应用中显示视图。
  3. 处理按钮操作:将用户交互与应用的响应关联起来。例如,当用户点击按钮时打开链接或关闭付费墙。

开始之前

开始之前,请先完成以下步骤:

  1. 在 Adapty 看板中,将你的应用连接到 App Store 和/或 Google Play。
  2. 在 Adapty 中创建产品。
  3. 创建流程或付费墙,并向其中添加产品。
  4. 创建版位并将流程或付费墙添加到版位中。
  5. 在应用代码中安装并激活 Adapty SDK。
Tip

完成这些步骤的最快方式是参照快速入门指南,或使用 Developer CLI 创建流程和版位。

1. 获取流程或付费墙

您的流程和付费墙与看板中配置的版位相关联。版位允许您为不同的目标受众展示不同的流程或付费墙,也可以运行 A/B 测试。

要获取在 Adapty Flow & Paywall Builder 中创建的流程或付费墙,您需要:

  1. 使用 getFlow 方法,通过版位 ID 获取 flow 对象。

  2. 使用 createFlowView 方法创建流程视图。视图包含显示所需的 UI 元素和样式。如果流程未配置视图,createFlowView 会返回错误——请在 onError 中处理该错误。

Important

若要获取视图,请先发布流程或付费墙。有未发布改动的流程或付费墙状态为 Dirty,其版位仍会继续提供上一个已发布的版本。

Adapty.getFlow("YOUR_PLACEMENT_ID")
    .onSuccess { flow ->
        AdaptyUI.createFlowView(flow)
            .onSuccess { view ->
                view.present()
            }
            .onError { error ->
                // the flow has no view configured, or view creation failed
            }
    }
    .onError { error ->
        // handle the error
    }

2. 展示流程或付费墙

现在,当你获取到流程后,只需添加几行代码即可将其展示出来。

要在设备屏幕上展示可视化流程,必须先创建视图。为此,请调用 AdaptyUI.createFlowView() 方法:

AdaptyUI.createFlowView(flow)
    .onSuccess { view ->
        view.present()
    }
    .onError { error ->
        // handle the error
    }

视图成功创建后,即可将其显示在设备屏幕上。每个视图只能使用一次:调用 dismiss() 后,需重新调用 createFlowView 才能再次显示该流程。

Tip

有关如何显示流程或付费墙的更多详情,请参阅我们的指南。

3. 处理按钮动作

当用户点击流程或付费墙中的按钮时,Kotlin Multiplatform SDK 会自动处理购买、恢复、关闭界面和打开链接等操作。

但是,其他按钮具有自定义或预定义的 ID,需要在代码中处理相应动作。或者,您可能希望覆盖这些按钮的默认行为。

例如,以下是关闭按钮的默认行为。您无需在代码中添加它,但在这里您可以了解如何在需要时实现。

请注意,默认情况下,流程在购买成功后仍保持打开状态。如果您希望在购买完成后关闭它,请在 flowViewDidFinishPurchase 回调中关闭该视图。

Tip

阅读我们的指南,了解如何处理按钮操作和事件。

AdaptyUI.setFlowsEventsObserver(object : AdaptyUIFlowsEventsObserver {
    override fun flowViewDidPerformAction(view: AdaptyUIFlowView, action: AdaptyUIAction) {
        when (action) {
            is AdaptyUIAction.CloseAction -> mainUiScope.launch { view.dismiss() }
            else -> Unit
        }
    }

    override fun flowViewDidFinishPurchase(
        view: AdaptyUIFlowView,
        product: AdaptyPaywallProduct,
        purchaseResult: AdaptyPurchaseResult
    ) {
        if (purchaseResult !is AdaptyPurchaseResult.UserCanceled) {
            mainUiScope.launch { view.dismiss() }
        }
    }
})

后续步骤

您的流程或付费墙已准备好在应用中展示。在 App Store 沙盒 或 Google Play Store 中测试购买流程,确保您可以从流程中完成测试购买。

接下来,您需要检查用户的访问等级,以确保向正确的用户展示付费墙或开放付费功能的访问权限。

完整示例

以下是如何将所有这些步骤整合到您的应用中的完整示例。

// Set up the observer for handling flow events
AdaptyUI.setFlowsEventsObserver(object : AdaptyUIFlowsEventsObserver {
    override fun flowViewDidPerformAction(view: AdaptyUIFlowView, action: AdaptyUIAction) {
        when (action) {
            is AdaptyUIAction.CloseAction -> mainUiScope.launch { view.dismiss() }
            else -> Unit
        }
    }

    override fun flowViewDidFinishPurchase(
        view: AdaptyUIFlowView,
        product: AdaptyPaywallProduct,
        purchaseResult: AdaptyPurchaseResult
    ) {
        if (purchaseResult !is AdaptyPurchaseResult.UserCanceled) {
            mainUiScope.launch { view.dismiss() }
        }
    }
})

// Get and display the flow
Adapty.getFlow("YOUR_PLACEMENT_ID")
    .onSuccess { flow ->
        AdaptyUI.createFlowView(flow)
            .onSuccess { view ->
                view.present()
            }
            .onError { error ->
                // the flow has no view configured — use custom logic
            }
    }
    .onError { error ->
        // handle the error
    }