Unity SDKでFlow Builderを使ってアプリ内課金を有効にする

このガイドでは、Adapty Unity SDK v4(ベータ版)の API を使用しています。v3 をお使いの場合は、対応するメソッド名についてマイグレーションガイドをご確認ください。

アプリ内課金を有効にするには、3 つの重要な概念を理解する必要があります。

  • プロダクト – ユーザーが購入できるもの(サブスクリプション、消耗型アイテム、永続アクセス)
  • フロー – ノーコードのフロービルダーで作成した、プロダクトをユーザーに提示する画面シーケンスです。SDKはGetFlowを使って取得します。独自のコードでUIを構築したい場合は、代わりにペイウォールを使用してください — ペイウォールを手動で実装するを参照してください。
  • プレースメント – アプリ内でフローを表示する場所とタイミング(mainonboardingsettingsなど)。ダッシュボードでフローをプレースメントに紐付け、コード内でプレースメントIDを使ってリクエストします。これにより、A/B テストの実行や、ユーザーごとに異なるフローの表示が簡単に行えます。

Adapty では、アプリ内で購入を有効にする 3 つの方法を提供しています。アプリの要件に応じて選択してください。

実装方法複雑さ使用するタイミング
Adapty フロービルダー✅ 簡単ノーコードビルダーで購入準備完了のフローを作成します。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 フロービルダーで作成したフローを取得するには、次の手順を行います:

  1. GetFlow メソッドを使って、プレースメント ID から flow オブジェクトを取得します。

  2. CreateFlowView メソッドを使って、フローのビューを作成します。ビューにはフローを表示するための UI 要素とスタイリングが含まれています。フローにビューが設定されていない場合、CreateFlowView はエラーを返します。コールバック内で適切に処理してください。

Important

ビューを取得するには、Flow Builder で Show on device トグルをオンにする必要があります。オンにしないと、CreateFlowView がエラーを返し、フローが表示されません。

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

このクイックスタートでは、フローを表示するために必要な最小限の設定を説明します。詳細な設定については、フローの取得に関するガイドを参照してください。

2. フローを表示する

フローのビューを取得したら、あとは数行追加するだけで表示できます。

フローを表示するには、CreateFlowView メソッドで作成した view に対して view.Present() メソッドを呼び出します。各 view は一度しか使用できません。閉じた後にもう一度フローを表示するには、CreateFlowView を再度呼び出してください。

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

フローの表示方法についての詳細は、ガイドをご覧ください。

3. ボタンアクションを処理する

ユーザーがフロー内のボタンをタップすると、Unity SDK は購入や復元を自動的に処理します。ただし、カスタムまたは事前定義済みの ID を持つボタンについては、コード側でアクションを処理する必要があります。

たとえば、フローには通常、閉じるボタンや開くべき 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 ストアでテスト購入を行い、フローから正常にテスト購入できることを確認してください。

次に、ユーザーのアクセスレベルを確認して、適切なユーザーにフローを表示したり、有料機能へのアクセスを付与したりできるようにする必要があります。

完全な実装例

以下は、すべての手順をアプリに統合した場合の例です。

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