在 Unity SDK 中使用 Flow 和付费墙编辑工具启用购买功能
本指南使用 Adapty Unity SDK v4(测试版)API。如果您使用的是 v3,请参阅迁移指南了解对应的方法名称。
要启用应用内购买,您需要了解以下三个核心概念:
- 产品 – 用户可以购买的内容(订阅、消耗型商品、永久授权)
- 流程与付费墙 – 向用户展示产品的界面,通过无代码的 Flow & Paywall Builder 构建,SDK 通过
GetFlow获取。如果你想用自己的代码构建 UI,请参阅实现自定义付费墙。 - 版位 – 在应用中何时何处展示流程与付费墙(如
main、onboarding、settings)。在看板中将它们绑定到版位,然后在代码中通过版位 ID 请求。这样可以轻松进行 A/B 测试,并向不同用户展示不同内容。
Adapty 为您提供三种在应用中开启购买功能的方式。请根据您的应用需求选择其中一种:
| 实现方式 | 复杂度 | 适用场景 |
|---|---|---|
| Adapty Flow 与付费墙编辑工具 | ✅ 简单 | 您在无代码编辑工具中创建完整的、可立即购买的流程或付费墙。Adapty 自动渲染并在后台处理所有复杂的购买逻辑、收据验证和订阅管理。 |
| 自定义付费墙 | 🟡 中等 | 您在应用代码中实现付费墙 UI,但仍从 Adapty 获取流程对象,以保持产品内容的灵活性。请参阅指南。 |
| 观察者模式 | 🔴 复杂 | 您已有自己的购买处理基础设施并希望继续使用。请注意,观察者模式在 Adapty 中有一定限制。请参阅文章。 |
以下步骤介绍如何展示在 Adapty 付费墙编辑工具中创建的流程或付费墙。
如果你想自行构建付费墙 UI,请参阅实现自定义付费墙。
要在应用代码中展示在 Adapty 付费墙编辑工具中创建的流程或付费墙,你只需:
- 获取流程或付费墙:从 Adapty 获取。
- 展示它,Adapty 将为你处理购买流程:在你的应用中显示该视图。
- 处理按钮操作:将用户交互与应用的响应关联起来。例如,当用户点击按钮时打开链接或关闭付费墙。
开始之前
在开始之前,请完成以下步骤:
- 在 Adapty 看板中将你的应用连接到 App Store 和/或 Google Play。
- 在 Adapty 中创建产品。
- 创建流程或付费墙并向其添加产品。
- 创建版位并将你的流程或付费墙添加到其中。
- 在应用代码中安装并激活 Adapty SDK。
完成这些步骤最快的方式是参照快速入门指南,或使用 Developer CLI 创建流程和版位。
1. 获取流程或付费墙
你的流程和付费墙与在看板中配置的版位相关联。版位允许你为不同的目标受众展示不同的流程或付费墙,也可以运行 A/B 测试。
要获取在 Adapty Flow & Paywall Builder 中创建的流程或付费墙,你需要:
-
通过 版位 ID,使用
GetFlow方法获取flow对象。 -
使用
CreateFlowView方法创建流程视图。该视图包含显示所需的 UI 元素和样式。如果流程未配置视图,CreateFlowView将返回错误——请在回调中处理。
如需获取视图,请先发布流程或付费墙。存在未发布修改的流程或付费墙状态为 Dirty,其版位将继续使用最后一次发布的版本。
Adapty.GetFlow("YOUR_PLACEMENT_ID", (flow, error) => {
if (error != null) {
// handle the error
return;
}
// Create the flow view
AdaptyUI.CreateFlowView(flow, (view, error) => {
if (error != null) {
// the flow has no view configured, or view creation failed
return;
}
// view - the flow view ready to be presented
});
});
此快速入门提供了显示流程或付费墙所需的最低配置。如需了解高级配置详情,请参阅我们的获取流程和付费墙指南。
2. 展示流程或付费墙
现在,您已获取流程视图,只需添加几行代码即可将其展示出来。
要展示流程,请对 CreateFlowView 方法创建的 view 调用 view.Present() 方法。每个 view 只能使用一次:关闭后,请再次调用 CreateFlowView 以重新展示流程。
view.Present((error) => {
// handle the error
});
有关如何展示流程或付费墙的更多详情,请参阅我们的指南。
3. 处理按钮操作
当用户点击流程或付费墙中的按钮时,Unity SDK 会自动处理购买和恢复操作。但其他按钮具有自定义或预定义的 ID,需要在代码中处理相应的操作。
例如,付费墙通常有一个关闭按钮以及需要打开的 URL(如使用条款和隐私政策)。要处理这些操作,您的类需要实现 IAdaptyFlowsEventsListener 接口并注册为监听器。
请注意,流程在购买成功后会保持打开状态。如果您希望在购买完成后关闭它,请在 FlowViewDidFinishPurchase 回调中关闭该视图。
public class YourClass : MonoBehaviour, IAdaptyFlowsEventsListener
{
void Start()
{
// Register this class as the flows events listener
Adapty.SetFlowsEventsListener(this);
}
// IAdaptyFlowsEventsListener method - handles button actions
public void FlowViewDidPerformAction(
AdaptyUIFlowView view,
AdaptyUIUserAction action
) {
switch (action.Type) {
case AdaptyUIUserActionType.Close:
view.Dismiss(null);
break;
case AdaptyUIUserActionType.OpenUrl:
AdaptyUI.OpenUrl(action.Value, AdaptyWebPresentation.ExternalBrowser, null);
break;
default:
break;
}
}
// IAdaptyFlowsEventsListener method - dismiss the flow after a purchase
public void FlowViewDidFinishPurchase(
AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchasedResult
) {
if (purchasedResult.Type != AdaptyPurchaseResultType.UserCancelled) {
view.Dismiss(null);
}
}
}
下一步
有疑问或遇到问题?欢迎访问我们的支持论坛,在那里你可以找到常见问题的解答,也可以提出自己的问题。我们的团队和社区随时为你提供帮助!
您的流程或付费墙已准备好在应用中展示。请在 App Store 沙盒或 Google Play Store 中测试您的购买,以确保您能从流程中完成测试购买。
接下来,您需要检查用户的访问等级,以确保向正确的用户展示付费墙或开放付费功能。
完整示例
以下是将所有步骤整合到应用中的完整示例。
using System;
using System.Collections.Generic;
using UnityEngine;
using AdaptySDK;
public class FlowManager : MonoBehaviour, IAdaptyFlowsEventsListener
{
[SerializeField] private string placementId = "YOUR_PLACEMENT_ID";
void Start()
{
// Register for flow events
Adapty.SetFlowsEventsListener(this);
GetAndDisplayFlow();
}
private void GetAndDisplayFlow()
{
Adapty.GetFlow(placementId, (flow, error) => {
if (error != null) {
Debug.LogError("Error getting flow: " + error.Message);
return;
}
CreateAndPresentFlowView(flow);
});
}
private void CreateAndPresentFlowView(AdaptyFlow flow)
{
AdaptyUI.CreateFlowView(flow, (view, error) => {
if (error != null) {
// the flow has no view configured — use custom logic
Debug.LogError("Error creating flow view: " + error.Message);
return;
}
view.Present((presentError) => {
if (presentError != null) {
Debug.LogError("Error presenting flow: " + presentError.Message);
return;
}
Debug.Log("Flow presented successfully");
});
});
}
// IAdaptyFlowsEventsListener implementation
public void FlowViewDidPerformAction(
AdaptyUIFlowView view,
AdaptyUIUserAction action
) {
switch (action.Type) {
case AdaptyUIUserActionType.Close:
Debug.Log("Close button pressed");
view.Dismiss(null);
break;
case AdaptyUIUserActionType.OpenUrl:
AdaptyUI.OpenUrl(action.Value, AdaptyWebPresentation.ExternalBrowser, null);
break;
default:
break;
}
}
public void FlowViewDidFinishPurchase(
AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchasedResult
) {
if (purchasedResult.Type != AdaptyPurchaseResultType.UserCancelled) {
view.Dismiss(null);
}
}
// Required interface methods (implement as needed)
public void FlowViewDidAppear(AdaptyUIFlowView view) { }
public void FlowViewDidDisappear(AdaptyUIFlowView view) { }
public void FlowViewDidSelectProduct(AdaptyUIFlowView view, string productId) { }
public void FlowViewDidStartPurchase(AdaptyUIFlowView view, AdaptyPaywallProduct product) { }
public void FlowViewDidFailPurchase(AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyError error) { }
public void FlowViewDidStartRestore(AdaptyUIFlowView view) { }
public void FlowViewDidFinishRestore(AdaptyUIFlowView view, AdaptyProfile profile) { }
public void FlowViewDidFailRestore(AdaptyUIFlowView view, AdaptyError error) { }
public void FlowViewDidReceiveError(AdaptyUIFlowView view, AdaptyError error) { }
public void FlowViewDidFailLoadingProducts(AdaptyUIFlowView view, AdaptyError error) { }
public void FlowViewDidFinishWebPaymentNavigation(AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyError error) { }
public void FlowViewDidReceiveAnalyticEvent(AdaptyUIFlowView view, string name, IDictionary<string, object> @params) { }
public void ShowFlow()
{
GetAndDisplayFlow();
}
}