Enable purchases with Flow Builder in Unity SDK
This guide uses Adapty Unity SDK v4 (beta) APIs. If you’re on v3, see the migration guide for the corresponding method names.
To enable in-app purchases, you need to understand three key concepts:
- Products – anything users can buy (subscriptions, consumables, lifetime access)
- Flows – screen sequences that present products to users, built in the no-code Flow Builder. The SDK retrieves them via
GetFlow. If you’d rather build the UI in your own code, use a paywall instead — see Implement paywalls manually. - Placements – where and when you show flows in your app (like
main,onboarding,settings). You attach flows to placements in the dashboard, then request them by placement ID in your code. This makes it easy to run A/B tests and show different flows to different users.
Adapty offers you three ways to enable purchases in your app. Select one of them depending on your app requirements:
| Implementation | Complexity | When to use |
|---|---|---|
| Adapty Flow Builder | ✅ Easy | You create a complete, purchase-ready flow in the no-code builder. Adapty automatically renders it and handles all the complex purchase flow, receipt validation, and subscription management behind the scenes. |
| Manually created paywalls | 🟡 Medium | You implement your paywall UI in your app code, but still get the flow object from Adapty to maintain flexibility in product offerings. See the guide. |
| Observer mode | 🔴 Hard | You already have your own purchase handling infrastructure and want to keep using it. Note that the observer mode has its limitations in Adapty. See the article. |
The steps below show how to implement a flow created in the Adapty Flow Builder.
If you’d rather build the paywall UI yourself, see Implement paywalls manually.
To display a flow created in the Adapty Flow Builder, in your app code, you only need to:
- Get the flow: Get it from Adapty.
- Display it and Adapty will handle purchases for you: Show the view in your app.
- Handle button actions: Associate user interactions with your app’s response to them. For example, open links or close the flow when users click buttons.
Before you start
Before you start, complete these steps:
- Connect your app to the App Store and/or Google Play in the Adapty Dashboard.
- Create your products in Adapty.
- Create a flow and add products to it.
- Create a placement and add your flow to it.
- Install and activate the Adapty SDK in your app code.
The fastest way to complete these steps is to follow the quickstart guide or create flows and placements using the Developer CLI.
1. Get the flow
Your flows are associated with placements configured in the dashboard. Placements allow you to run different flows for different audiences or to run A/B tests.
To get a flow created in the Adapty Flow Builder, you need to:
-
Get the
flowobject by the placement ID using theGetFlowmethod. -
Create the flow view using the
CreateFlowViewmethod. The view contains the UI elements and styling needed to display the flow. If the flow has no view configured,CreateFlowViewreturns an error — handle it in the callback.
To get the view, you must switch on the Show on device toggle in the Flow Builder. Otherwise, CreateFlowView will return an error, and the flow won’t be displayed.
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
});
});
This quickstart provides the minimum configuration required to display a flow. For advanced configuration details, see our guide on getting flows.
2. Display the flow
Now, when you have the flow view, it’s enough to add a few lines to display it.
To display the flow, use the view.Present() method on the view created by the CreateFlowView method. Each view can only be used once: after you dismiss it, call CreateFlowView again to display the flow one more time.
view.Present((error) => {
// handle the error
});
For more details on how to display a flow, see our guide.
3. Handle button actions
When users click buttons in the flow, the Unity SDK automatically handles purchases and restoration. However, other buttons have custom or pre-defined IDs and require handling actions in your code.
For example, your flow probably has a close button and URLs to open (e.g., terms of use and privacy policy). To handle these actions, your class needs to implement the IAdaptyFlowsEventsListener interface and register as a listener.
Note that the flow stays open after a successful purchase. If you want to close it once the purchase finishes, dismiss the view in the FlowViewDidFinishPurchase callback.
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);
}
}
}
Next steps
Have questions or running into issues? Check out our support forum where you can find answers to common questions or ask your own. Our team and community are here to help!
Your flow is ready to be displayed in the app. Test your purchases in the App Store sandbox or in Google Play Store to make sure you can complete a test purchase from the flow.
Now, you need to check the users’ access level to ensure you display a flow or give access to paid features to right users.
Full example
Here is how all those steps can be integrated in your app together.
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();
}
}