Включение покупок с помощью Flow & Paywall Builder в Unity SDK

Этот гайд использует API Adapty Unity SDK v4 (beta). Если вы используете v3, обратитесь к гайду по миграции за соответствующими названиями методов.

Чтобы подключить встроенные покупки, нужно разобраться в трёх ключевых концепциях:

  • Продукты – всё, что пользователи могут купить (подписки, расходуемые покупки, пожизненный доступ)
  • Флоу и пейволы – экраны для показа продуктов пользователям, созданные в конструкторе без кода Flow & Paywall Builder. SDK получает их через GetFlow. Если вы предпочитаете строить UI в собственном коде, см. Реализация кастомных пейволов.
  • Плейсменты – где и когда в приложении показываются флоу и пейволы (например, main, onboarding, settings). Вы привязываете их к плейсментам в дашборде, а затем запрашиваете по ID плейсмента в коде. Это упрощает проведение A/B-тестов и показ разных вариантов разным пользователям.

Adapty предлагает три способа включить покупки в приложении. Выберите подходящий в зависимости от требований вашего приложения:

РеализацияСложностьКогда использовать
Adapty Flow & Paywall Builder✅ ЛегкоВы создаёте готовый к покупке флоу или пейвол в no-code конструкторе. Adapty автоматически его отображает и берёт на себя всю сложную логику покупок, валидацию чеков и управление подписками.
Кастомные пейволы🟡 СреднеВы реализуете UI пейвола в коде своего приложения, но по-прежнему получаете объект флоу от Adapty, сохраняя гибкость в управлении продуктами. См. гайд.
Observer mode🔴 СложноУ вас уже есть собственная инфраструктура обработки покупок, и вы хотите продолжать её использовать. Обратите внимание, что observer mode имеет свои ограничения в Adapty. См. статью.
Important

Шаги ниже показывают, как реализовать флоу или пейвол, созданный в Adapty Flow & Paywall Builder.

Если вы предпочитаете создавать UI пейвола самостоятельно, смотрите Реализация пользовательских пейволов.

Чтобы отобразить флоу или пейвол, созданный в Adapty Flow & Paywall Builder, в коде вашего приложения нужно только:

  1. Получите флоу или пейвол: Получите его из Adapty.
  2. Отобразите его — Adapty возьмёт на себя покупки: Покажите экран в вашем приложении.
  3. Обработайте действия кнопок: Свяжите действия пользователя с реакцией вашего приложения. Например, открывайте ссылки или закрывайте пейвол при нажатии кнопок.

Прежде чем начать

Прежде чем начать, выполните следующие шаги:

  1. Подключите приложение к App Store и/или Google Play в дашборде Adapty.
  2. Создайте продукты в Adapty.
  3. Создайте флоу или пейвол и добавьте в него продукты.
  4. Создайте плейсмент и добавьте в него флоу или пейвол.
  5. Установите и активируйте SDK в коде приложения.
Tip

Самый быстрый способ выполнить эти шаги — следовать краткому руководству или создать флоу и плейсменты с помощью Developer CLI.

1. Получите флоу или пейвол

Ваши флоу и пейволы привязаны к плейсментам, настроенным в дашборде. Плейсменты позволяют показывать разные флоу или пейволы для разных аудиторий или проводить A/B-тесты.

Чтобы получить флоу или пейвол, созданный в Adapty Flow & Paywall Builder, необходимо:

  1. Получить объект flow по ID плейсмента с помощью метода GetFlow.

  2. Создайте представление флоу с помощью метода CreateFlowView. Представление содержит UI-элементы и стили, необходимые для его отображения. Если для флоу не настроено представление, CreateFlowView вернёт ошибку — обработайте её в колбэке.

Important

Чтобы получить представление, опубликуйте флоу или пейвол. Флоу или пейвол с неопубликованными изменениями имеет статус 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
    });
});
Info

Этот quickstart содержит минимальную конфигурацию, необходимую для отображения флоу или пейвола. Подробнее о расширенной настройке читайте в гайде по получению флоу и пейволов.

2. Отобразите флоу или пейвол

Теперь, когда у вас есть объект флоу, достаточно добавить несколько строк, чтобы его отобразить.

Для отображения флоу используйте метод view.Present() на объекте view, созданном методом CreateFlowView. Каждый view можно использовать только один раз: после закрытия вызовите CreateFlowView снова, чтобы отобразить флоу ещё раз.

view.Present((error) => {
    // handle the error
});
Info

Подробнее об отображении флоу или пейвола читайте в нашем гайде.

3. Обработка нажатий на кнопки

Когда пользователи нажимают кнопки во флоу или на пейволе, Unity SDK автоматически обрабатывает покупки и восстановление. Однако остальные кнопки имеют пользовательские или предопределённые идентификаторы и требуют обработки действий в вашем коде.

Например, на вашем пейволе скорее всего есть кнопка закрытия и URL-адреса для открытия (например, условия использования и политика конфиденциальности). Чтобы обрабатывать эти действия, ваш класс должен реализовывать интерфейс IAdaptyFlowsEventsListener и регистрироваться в качестве слушателя.

Обратите внимание, что флоу остаётся открытым после успешной покупки. Если вы хотите закрыть его после завершения покупки, закройте экран в обратном вызове FlowViewDidFinishPurchase.

Tip

Читайте наши гайды о том, как обрабатывать действия и события кнопок.

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);
        }
    }
}

Следующие шаги

Tip

Есть вопросы или возникли проблемы? Загляните на наш форум поддержки, где можно найти ответы на распространённые вопросы или задать свой. Наша команда и сообщество всегда готовы помочь!

Ваш флоу или пейвол готов к отображению в приложении. Протестируйте покупки в песочнице 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();
    }
}