[Unity IAP] Androidで非消費アイテムを消費する


前置き

Unity IAPで課金処理を実装している時の話。

Androidで非消費アイテム(NonConsumable)を購入した場合、アプリを一度アンインストールして再インストールしても購入情報が保持されたままとなる。
(Unity IAPの初期化時に自動でリストア処理が実行される)

そのため非消費アイテムは1アカウントで1回しか購入することができない。
このままだとテストがしづらいため、購入アイテムをリセットするデバッグ機能を実装しておくと便利。

仕組み

そもそもAndroidの課金アイテムは以下の2種類しかない

  • 標準のアプリ内アイテム(一回限りの課金)
  • 定期購入(繰り返し自動課金)

参考
https://developer.android.com/google/play/billing/index.html?hl=ja

そのため、Unity IAPでの「消費アイテム(Consumable)」「非消費アイテム(NonConsumable)」の分類は、
Androidでは同じカテゴリ(上記の「標準のアプリ内アイテム」)になる。

ではどう分けているかと言うと、「消費アイテム」はアイテムを購入した後、すぐに「消費」処理を実行することで、
消費アイテムを実現するというのが、Android課金の基本的な実装方法。
つまり「消費」処理を実行するかしないかの違い。
UnityIAPも内部でそのような処理を実行している。

つまり、UnityIAP上は「非消費アイテム(NonConsumable)」となっているアイテムも、
消費してやれば所持状態が解除される。

実装

IAPManagerとしているのは課金処理を実行しているクラスを想定して書いているけど何でも良い。
Debug_ConsumeAllProducts()を実行すれば指定したIDのアイテムが消費されるはず。
処理実行後にアプリをアンインストールしてから再インストールするとキレイな状態になるはず。

IAPManager.cs
public class IAPManager {

    // 省略

    private class DebugStoreListener : IStoreListener {
        public void OnInitialized(IStoreController controller, IExtensionProvider extensions) {
        }
        public void OnInitializeFailed(InitializationFailureReason error) {
        }
        public void OnPurchaseFailed(Product i, PurchaseFailureReason p) {
        }
        public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) {
            return PurchaseProcessingResult.Complete;
        }
    }

    public void Debug_ConsumeAllProducts() {
        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());

        // 非消費アイテムのIDを必要なだけ指定する
        builder.AddProduct("<product_id>", ProductType.Consumable);
        builder.AddProduct("<product_id>", ProductType.Consumable);
        builder.AddProduct("<product_id>", ProductType.Consumable);
        // ...

        UnityPurchasing.Initialize(new DebugStoreListener(), builder);
    }
}

AbstractStore.FinishTransactionが消費処理のメソッドだと思うんだけど、呼ぶまでが遠そうだったため断念。

代わりにConsumableを指定した状態で、初期化処理を実行させる方法とした。
初期化処理で、所持アイテムのリストア処理としてProcessPurchaseが呼ばれる流れとなる。
ProcessPurchaseは問答無用でCompleteを返しているため、
これにより「消費アイテムの処理成功」状態となり、Unity IAPが消費処理を実行する。