# Unity Iap の初期化

> Unity Iapパッケージの初期化、基本設定の構成、設定の確認を行い、サポートされているプラットフォーム間でアプリケーション内課金の処理を開始する方法を説明します。

Unity アプリ内課金（IAP）を使用する前に、[IAP パッケージを初期化](#initialize-in-app-purchasing)します。

> **Important:**
>
> [D2C(ダイレクト ツー コンシューマー)支払いプロバイダーを統合する](./payment-providers/workflow.md)場合は、いくつかの違いがあるため、代わりに[スタートアップ シーケンスをハンドルするためのサービスの初期化](./payment-providers/initialize-services.md)を参照してください。

プロジェクトで [Unity Analytics](/analytics.md) または [Unity Authentication](/authentication.md) を使用する場合は、IAP を初期化する前にまず Unity Gaming Services（UGS）を初期化する必要があります。次の「 [Initialize Unity Gaming Services](#initialize-unity-gaming-services) 」セクションにハウツーが記載されています。

## Unity Gaming Services の初期化##initialize-unity-gaming-services

`UnityServices.InitializeAsync()` を呼び出して、すべての Unity Gaming Services を初期化します。このメソッドは、初期化の進行状況の追跡に使用できる`Task`を返します。

詳細については、[初期化例](/services/services-core-api.md#initialization-example)を参照してください。完全に機能するサンプルについては、**06 Initialize Gaming Services** サンプルをインポート（**Package Manager** > **アプリ内課金** > **Samples**）。

詳細については、[Services Core API](/services/services-core-api.md) を参照してください。

## アプリ内課金の初期化##initialize-in-app-purchasing

### 前提条件##prerequisites

購入する製品について、[エディターでカタログ](./create-catalog-in-editor.md)を作成する の手順を実行します。

### 初期化手順##initialization-steps

初期化期化は、以下のステップで構成されます。

1. アプリストアの`StoreController`の取得。
2. `StoreController`へのイベントリスナーの接続。
3. アプリストアへの接続。
4. アプリストアからプロダクトを取得する。
5. アプリストアからの購入を取得します。

```cs
using System.Collections.Generic;
using UnityEngine.Purchasing;

public class MyIAPManager
{
    private StoreController m_StoreController;
    public MyIAPManager()
    {
        // Define products
        var catalogProvider = new CatalogProvider();
        catalogProvider.AddProduct("100_gold_coins", ProductType.Consumable,
            new StoreSpecificIds()
            {
                {"100_gold_coins_google", GooglePlay.Name},
                {"100_gold_coins_mac", MacAppStore.Name}
            });

        // Get StoreController
        m_StoreController = UnityIAPServices.StoreController();

        // Add event listeners
        m_StoreController.OnStoreDisconnected += OnStoreDisconnected;

        m_StoreController.OnProductsFetched += OnProductsFetched;
        m_StoreController.OnProductsFetchFailed += OnProductsFetchFailed;

        m_StoreController.OnPurchasesFetched += OnPurchasesFetched;
        m_StoreController.OnPurchasesFetchFailed += OnPurchasesFetchFailed;

        // Connect to store
        m_StoreController.Connect().ContinueWith(_ =>
        {
            // Fetch products from store
            catalogProvider.FetchProducts(
                list => m_StoreController.FetchProducts(list)
                
        });
    }

    /// <summary>
    /// Invoked when connection is lost to the current store, or on a Connect() failure.
    /// </summary>
    /// <param name="failure">Information regarding the failure.</param>
    private void OnStoreDisconnected(StoreConnectionFailureDescription failure)
    {
    }

    /// <summary>
    /// Invoked with products that are successfully fetched.
    /// </summary>
    /// <param name="products">Products successfully returned from the app store.</param>
    private void OnProductsFetched(リスト<Product>プロダクト)
    {
        // Fetch purchases for successfully retrieved products
        m_StoreController.FetchPurchases();
    }

    /// <summary>
    /// Invoked when an attempt to fetch products has failed or when a subset of products failed to be fetched.
    /// </summary>
    /// <param name="failure">Information regarding the failure.</param>
    private void OnProductsFetchFailed(ProductFetchFailed failure)
    {
    }

    /// <summary>
    /// Invoked when previous purchases are fetched.
    /// </summary>
    /// <param name="orders">All active pending, completed, and deferred orders for previously fetched products.</param>
    private void OnPurchasesFetched(オーダーオーダー)
    {
    }

    /// <summary>
    /// Invoked when an attempt to fetch previous purchases has failed.
    /// </summary>
    /// <param name="failure">Information regarding the failure.</param>
    private void OnPurchasesFetchFailed(PurchasesFetchFailureDescription failure)
    {
    }

    /// <summary>
    /// Invoked when a purchase needs to be processed and fulfilled.
    /// </summary>
    /// <param name="order">The order awaiting fulfillment.</param>
    private void OnPurchasePending(PendingOrder order)
    {
    }
}
```

#### StoreController の取得##get-a-storecontroller

`StoreController`は、アプリ内課金機能を操作するための主要インターフェースです。`StoreController` のインスタンスは、[UnityIAPServices.StoreController](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.UnityIAPServices.html#UnityEngine_Purchasing_UnityIAPServices_StoreController_System_String_) を呼び出すことで取得できます。デフォルトのストアコントローラーか、ストア名が指定されている場合はリクエストされた特定のストアコントローラーを返します。

#### StoreController へのイベントハンドラーのアタッチ、設定、添付##attach-event-handlers-to-the-storecontroller

ストアを正しく機能させるには、次のイベントにハンドラをアタッチ、設定、添付します。

* [OnStoreDisconnected](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_OnStoreDisconnected)
* [OnProductsFetched](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_OnProductsFetched)
* [OnProductsFetchFailed](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_OnProductsFetchFailed)
* [OnPurchasesFetched](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_OnPurchasesFetched)
* [OnPurchasesFetchFailed](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_OnPurchasesFetchFailed)
* [OnPurchasePending](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_OnPurchasePending)

アプリ内課金をプロジェクトに統合する際に、追加のハンドラーの実装が必要になる場合があります。`StoreController` で使用可能なイベントの完全なリストについては、[イベント](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#events) を参照してください。

#### アプリストアへの接続##connect-to-your-app-store

[StoreController.Connect](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_Connect) を呼び出してアプリストアに接続します。返される`Task`は、接続が完了または失敗したときに解決されます。接続が失敗すると、`OnStoreDisconnected` イベントが発生します。IAP 機能を使用するには、ストアに接続する必要があります。

#### フェッチプロダクト##fetch-products

> **Note:**
>
> フェッチする前にプロダクトを定義します。手順については、[エディターでのカタログの作成](/iap/create-catalog-in-editor.md) を参照してください。

製品が購入可能かどうかを検証するには、 [StoreController.FetchProducts](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_FetchProducts_System_Collections_Generic_List_UnityEngine_Purchasing_ProductDefinition__UnityEngine_Purchasing_IRetryPolicy_) を呼び出します。成功すると、正常に返されたプロダクトのリストで `OnProductsFetched` イベントが実行されます。 失敗すると、`OnProductsFetchFailed` イベントが実行されます。

購入は、正常に返された製品に対してのみフェッチまたは開始できます。ランタイムに複数回`FetchProducts`を呼び出すことができますが、`FetchProducts`を再度呼び出す前に以前のリクエストが終了するのを待つ必要があります。

Apple App Store を使用すると、`FetchProducts`の完了後に未処理の注文に対して `OnPurchasePending` が呼び出される場合があります。

##### GetProducts##getproducts

[`GetProducts`](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_GetProducts) と `FetchProducts` は交換できません。初期化中に`FetchProducts`を呼び出すようにしてください。呼び出されるたびに、`FetchProducts`は結果のプロダクトを`GetProducts`によって返されるリストに追加します。

#### 購入の取得##fetch-purchases

[`StoreController.FetchPurchases`](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_FetchPurchases)を呼び出して、プレイヤーの現在のアクティブな注文をリクエストします。アクティブなオーダーには、`PendingOrders`、`ConfirmedOrders`(アクティブなサブスクリプションとアクティブな非消費型)、`DeferredOrders`が含まれます。詳細については、[購入](/iap/purchases.md) を参照してください。

`FetchPurchases` の呼び出しは、2 つのイベントハンドラの 1 つをトリガーします。`OnPurchasesFetched` は、ストアまたは`OnPurchasesFetchFailed`から返された Pending、Confirmed、およびディファードのすべての注文を含む `Orders` オブジェクトで実行されます。これらは、障害のイベントで実行されます。
google play を使用すると、処理されていない購入に対して `OnPurchasePending` イベントが発生します。

これは、アプリ内課金機能の使用を開始するために厳密には必須ではありません。ただし、新しい購入を開始する前に、既存の購入をフェッチしてハンドルすることをお勧めします。そうしないと、予期しない動作が発生する可能性があります。

ランタイムに追加の製品を取得する場合は、購入を再度取得する必要があることに注意してください。

##### 購入をオフラインで取得##fetch-purchases-offline

Apple StoreKit 2 などの一部のプラットフォームライブラリは、製品データをキャッシュせずにオフラインアクセスのためのエンタイトルメントをデバイスにキャッシュします。このアプローチは推奨されませんが、`OnProductsFetchFailed` コールバックの後で`FetchPurchases`を呼び出すことはできます。この場合、`FetchPurchases`は購入情報を返しますが、リンクされた製品には`type`[な`ProductType.Unknown`](https://docs.unity3d.com/Packages/com.unity.purchasing@5.2/api/UnityEngine.Purchasing.ProductType.html)が含まれます。また、`ProductDefinition.id`と`ProductDefinition.storeSpecificId`の両方にストア固有の識別子が設定されます。

> **Note:**
>
> StoreKit 1 には適用されません。StoreKit 1 はレシートをデバイスにキャッシュしますが、パッケージではレシートデータを解析するためにフェッチされた製品データが必要です。プロダクトの取得に失敗した場合、`FetchPurchases`は購入情報を返しません。

##### GetPurchases##getpurchases

[`GetPurchases`](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/api/UnityEngine.Purchasing.StoreController.html#UnityEngine_Purchasing_StoreController_GetPurchases) と `FetchPurchases` は交換できません。初期化中に `FetchPurchases` を呼び出すようにしてください。`GetProducts` や `FetchProducts` とは異なり、`FetchPurchases` は `GetPurchases` によって返されたリストを生成するだけでなく、上書きもします。そうでない場合、パッケージはイベントからの注文データに基づいて、ストアとの同期をできるだけ維持しようとします。

### Codeless IAP の自動初期化##automatically-initialize-codeless-iap

Codeless IAP の設定方法の詳細は、『 [Codeless IAP の設定](/iap/codeless-iap.md#set-up-codeless-iap) 』を参照してください。

> **Note:**
>
> 自動初期化もスクリプトで手動で初期化する場合は、エラーが発生する可能性があるため有効にしないでください。

### Codeless IAP の自動 Unity ゲーム サービス初期化##automatic-unity-game-services-initialization-for-codeless-iap

Codeless IAP を使用している場合は、**IAP Catalog** ウィンドウの下部にある **Automatically initialize Unity Gaming Services** チェックボックスをオンにして、Unity Gaming Services 自動初期化をイネーブルにします。
これにより、アプリケーションの起動時に Unity Gaming Services が即座に初期化されます。

この特徴を使用するには、**Automatically initialize UnityIAPServices (recommended)** を有効にする必要があります。**IAP カタログ**にこれらのチェックボックスが表示されない場合は、カタログウィンドウに製品がまだ追加されていない可能性があります。

デフォルトの初期化オプションで Unity Gaming Services を初期化します。一部のサービスには特定の初期化オプションが必要で、デフォルト設定では動作しない場合があります。カスタムオプションが必要な場合は、前述のコード化された API を使用して Unity Gaming Services を初期化します。
