在 React Native SDK 中通过 Flow Builder 启用付费功能
要启用应用内购买,你需要了解三个核心概念:
- 产品 – 用户可购买的一切内容(订阅、消耗型商品、永久授权)
- 流程 – 向用户展示产品的屏幕序列,在无代码的 Flow Builder 中构建,SDK 通过
getFlow 获取。如果你更倾向于用自己的代码构建 UI,请使用付费墙代替——详见手动实现付费墙。
- 版位 – 在应用中展示流程的位置和时机(例如
main、onboarding、settings)。你在看板中将流程绑定到版位,然后在代码中通过版位 ID 来请求它们。这样可以轻松运行 A/B 测试,并向不同用户展示不同的流程。
Adapty 为您提供三种在应用中开启内购的方式。请根据您的应用需求选择其中一种:
| 实现方式 | 复杂度 | 使用场景 |
|---|---|---|
| Adapty Flow Builder | ✅ 简单 | 你在无代码编辑工具中创建完整的、可购买的流程。Adapty 自动渲染并处理所有复杂的购买流程、收据验证和订阅管理。 |
| 手动创建付费墙 | 🟡 中等 | 你在应用代码中实现付费墙 UI,但仍从 Adapty 获取 flow 对象,以保持产品供给的灵活性。参见指南。 |
| 观察者模式 | 🔴 复杂 | 你已有自己的购买处理基础设施并希望继续使用。请注意,观察者模式在 Adapty 中存在一定限制。参见文章。 |
以下步骤说明如何实现在 Adapty Flow Builder 中创建的流程。
如果你更倾向于自行构建付费墙 UI,请参阅手动实现付费墙。
要显示在 Adapty Flow Builder 中创建的流程,在你的应用代码中,只需完成以下操作:
- 获取流程:从 Adapty 获取流程。
- 展示流程,Adapty 将自动处理购买:在应用中显示该视图。
- 处理按钮操作:将用户交互与应用的响应关联起来。例如,当用户点击按钮时打开链接或关闭流程。
开始之前
在开始之前,请先完成以下步骤:
- 在 Adapty 看板中将您的应用连接到 App Store 和/或 Google Play。
- 在 Adapty 中创建产品。
- 创建流程并将产品添加到其中。
- 创建版位并将流程添加到其中。
- 在您的应用代码中安装并激活 Adapty SDK。本指南使用 Adapty React Native SDK v4 API。
1. 获取流程
你的流程与在看板中配置的版位相关联。版位允许你为不同的目标受众运行不同的流程,或进行 A/B 测试。
要获取在 Adapty 付费墙编辑工具中创建的流程,请通过 getFlow 方法,使用版位 ID 获取 flow 对象。该流程包含显示所需的 UI 元素和样式。
try {
const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');
// the requested flow
} catch (error) {
// handle the error
}
2. 展示流程
现在,当你已经获取到流程后,只需添加几行代码即可展示它。
要将流程嵌入现有的组件树中,可以直接在 React Native 组件层级中使用 AdaptyFlowView 组件:
function MyFlow({ flow }) {
const onPurchaseCompleted = useCallback<FlowEventHandlers['onPurchaseCompleted']>(
(result, product) => result.type !== 'user_cancelled',
[],
);
return (
<AdaptyFlowView
flow={flow}
style={{ flex: 1 }}
onPurchaseCompleted={onPurchaseCompleted}
/>
);
}
要将流程显示为独立屏幕,请使用 createFlowView 方法创建一个 view,设置其事件处理程序,然后调用 view.present()。每个 view 只能使用一次。如果需要再次显示该流程,请再次调用 createFlowView 以创建新的 view 实例。
try {
const view = await createFlowView(flow);
view.setEventHandlers({
onPurchaseCompleted(result, product) {
return result.type !== 'user_cancelled';
},
});
await view.present();
} catch (error) {
// handle the error
}
当用户点击流程中的按钮时,React Native SDK 会自动处理购买、恢复购买、关闭流程以及打开 URL 等操作。
但是,其他按钮具有自定义或预定义的 ID,需要在代码中处理相应操作。或者,你可能希望覆盖其默认行为。
例如,以下是关闭按钮的默认行为。你无需在代码中添加它,但这里展示了如何在需要时实现。
对于 React 组件,直接在 AdaptyFlowView 组件中处理操作:
function MyFlow({ flow }) {
const onCloseButtonPress = useCallback<FlowEventHandlers['onCloseButtonPress']>(
() => true, // allow the flow to close
[],
);
const onCustomAction = useCallback<FlowEventHandlers['onCustomAction']>(
(actionId) => false,
[],
);
return (
<AdaptyFlowView
flow={flow}
style={{ flex: 1 }}
onCloseButtonPress={onCloseButtonPress}
onCustomAction={onCustomAction}
/>
);
}
对于模态呈现,使用 setEventHandlers 实现事件处理程序:
const unsubscribe = view.setEventHandlers({
onCloseButtonPress() {
return true; // allow the flow to close
},
});
后续步骤
有疑问或遇到问题?请访问我们的支持论坛,您可以在那里找到常见问题的解答,或者提出您自己的问题。我们的团队和社区随时为您提供帮助!
你的流程已准备好在应用中展示。测试购买,确保可以在流程中完成测试购买。
接下来,你需要检查用户的访问等级,以确保向正确的用户展示流程或开放付费功能。
完整示例
以下是将本指南中所有步骤整合到应用中的完整示例。
export default function FlowScreen() {
const [flow, setFlow] = useState(null);
const loadFlow = async () => {
try {
const flowData = await adapty.getFlow('YOUR_PLACEMENT_ID');
setFlow(flowData);
} catch (error) {
console.warn('Error loading flow:', error);
}
};
const onCloseButtonPress = useCallback<FlowEventHandlers['onCloseButtonPress']>(
() => true,
[],
);
const onPurchaseCompleted = useCallback<FlowEventHandlers['onPurchaseCompleted']>(
(result, product) => result.type !== 'user_cancelled',
[],
);
useEffect(() => {
loadFlow();
}, []);
return (
<View style={{ flex: 1 }}>
{flow ? (
<AdaptyFlowView
flow={flow}
style={{ flex: 1 }}
onCloseButtonPress={onCloseButtonPress}
onPurchaseCompleted={onPurchaseCompleted}
/>
) : (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Load Flow" onPress={loadFlow} />
</View>
)}
</View>
);
}
export default function FlowScreen() {
const showFlow = async () => {
try {
const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');
const view = await createFlowView(flow);
view.setEventHandlers({
onCloseButtonPress() {
return true;
},
onPurchaseCompleted(result, product) {
return result.type !== 'user_cancelled';
},
});
await view.present();
} catch (error) {
// handle any error that may occur during the process
console.warn('Error showing flow:', error);
}
};
// you can add a button to manually trigger the flow for testing purposes
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Show Flow" onPress={showFlow} />
</View>
);
}