Androidにおいて、Unity IAP を使って課金処理を実装しました。色々なサイトを参考にさせていただいたのですが、実装してみないとわからない点が多くありましたので、複数回に分けて記事にまとめます。
- In App Purchasing
4.1.2 - Unity
2020.3.21.f1 - Android
10/11
この記事では課金の評価についてまとめます。セットアップや実装については以下の記事をご参照ください。
評価環境の準備
Androidのアプリの課金評価をするためにはGoogle Play Consoleの該当アプリに課金アイテムを追加し、アプリを内部テストやクローズドテストなどにリリースする必要があります。
アプリ内アイテムの追加
Google Play Console のアプリ管理画面からアプリ内アイテムを選択し、課金アイテムを追加します。商品名やアイテムIDは本番で使用するものと同じものを使用します。

ここにで設定するアイテムIDは実装したコードに埋め込んでおかなければなりません。こちらで紹介しているサンプルコードのproductNameGooglePlayNonConsumableにアイテムIDを設定しておきます。
static IStoreController storeController; // Purchasing システムの参照
static IExtensionProvider storeExtensionProvider; // 拡張した場合のPurchasing サブシステムの参照
static string productIDNonConsumable = "nonconsumable"; // 非消費型製品の汎用ID
static string productNameGooglePlayNonConsumable = "TestItem"; // Google Play Store identifier for the non-consumable product.
上記の例ではアイテムIDが”TestItem”の場合の設定になります。
内部テストリリース
アプリを通常リリースするのと同じように内部テストリリースにリリースします。内部テストリリースは審査もなく、リリース後一定時間でPlay Storeからダウンロードできるようになります。
内部テストリリースの手順についてはこちらに詳しく説明されています。
ユーザーと権限にアカウントを追加
Google Play Console のトップページからユーザーと権限を選択し、テスターのアカウント(gmailアドレス)を追加します。これを入力し忘れたアカウントでテストすると実際に課金されてしまうので、注意が必要です。

テスト手順
購入する
アプリから購入する時、テスト用のアカウントで購入しようとすると、いくつかの決済方法が選択できます。それぞれの使用方法と何を確認すべきかについて説明します。
テストカード、常に承認
購入したらすぐに決済が承認されるテスト用のカードです。実際に課金されることはありません。決済完了後、ProcessPurchase()がコールバックされるので、正しく購入処理ができているかを確認することができます。
テストカード、常に不承認
購入したらすぐに決済が不承認されるテスト用のカードです。 購入完了後、すぐにOnPurchaseFailed()がコールバックされるので、正しくエラーハンドリングができているかを確認することができます。
スローテストカード、数分後に承認
購入したら2,3分後に決済が承認されるテスト用のカードです。実際に課金されることはありません。 コンビニ払いなど、決済完了までに時間がかかる購入処理をテストするために使用できます。
承認前に ProcessPurchase() がコールバックされることはありませんが、Pendingのレシートを確認することができます。数分後、承認のタイミングでアプリが起動している場合は ProcessPurchase() がコールバックされるので、購入処理が正しく行えるかを確認します。
また、承認のタイミングでアプリが起動していない場合は次回起動時のUnityPurchasing.Initialize()の初期化完了後に ProcessPurchase() がコールバック されます。
スローテストカード、数分後に不承認
購入したら2,3分後に決済が不承認されるテスト用のカードです。不承認されるまではPendingのレシートが確認できますが、不承認後はレシートがなくなります。v4.1.2で私の評価する範囲内では不承認されたことをアプリがコールバックで知ることはできませんでした。また、初期化でレシートを同期するまではPendingのレシートが残り続けるので、厄介です。
アプリの振る舞いの例としては購入処理後、Pendingのレシートがある限りは支払い保留中として、アプリが再起動される時にPendingのレシートがなくなっていたら不承認となったと判断し、また購入待ちとするようなハンドリングがよいかと思います。
コンビニ払いが支払われなかった場合はこのカードでテストできるかと思います。
返金する
返金は Google Play Console から行います。本番環境からの購入とテスト環境からの購入が同じリストにあるので、間違ってテスト以外の購入を返金しないように気を付けます。
Google Play Console のトップページの注文管理を選択して、払い戻しをする決済をリストから選び→を選択します。

払い戻しを選択します。

利用資格を削除するを選択して、右下の払い戻しボタンで払い戻します。

非消費型アイテムは利用資格を削除しないとStoreにレシートが残り続け、再購入の評価が行えない状態となります。必ず払い戻しと同時に削除するようにします。
返金時、利用資格を削除し忘れた際の対応
非消費アイテムの返金の際に配布したアイテムを削除するかしないかを設定することができます。もし返金と同時に削除しなかった場合、課金アイテムのレシートがPlayStore及びデバイスに残り続けることになり新たにアイテムを購入することができなくなります。
このような時、非消費型アイテムを削除する方法について説明します。
ProductTypeの変更
コードでProductType.NonConsumableを設定している箇所をProductType.Consumableに変更します。これでこのアイテムは消費型アイテムとして購入時に扱われることになります。
public void InitializePurchasing()
{
// If we have already connected to Purchasing ...
if (IsInitialized()) {
return;
}
var module = StandardPurchasingModule.Instance();
var builder = ConfigurationBuilder.Instance(module);
#if false
builder.AddProduct(productIDNonConsumable, ProductType.NonConsumable, new IDs()
{
{ productNameGooglePlayNonConsumable, GooglePlay.Name }
});
#else
/* for clearing consuble item for android */
builder.AddProduct(productIDNonConsumable, ProductType.Consumable, new IDs()
{
{ productNameGooglePlayNonConsumable, GooglePlay.Name }
});
#endif
UnityPurchasing.Initialize(this, builder);
}
アプリを再インストール
アプリを一度削除して、再インストールします。再インストール時に購入済みのレシートの復元処理が走り、復元できたレシートがあった場合は通常購入時と同じようにProcessPurchase()で購入完了コールバックを受けるのですが、ProductType.Consumableで初期化したアイテムはここで購入完了処理をするとレシートが削除されます。
これにより、非消費型アイテムもストア、デバイス両方から削除することができます。
おわりに
Androidの課金評価はストアにアプリをアップロードが必要となり、一見手間がかかるように見えます。しかし、通常の課金と同じような流れで課金→返金を繰り返して評価することができるので、個人的にはsandboxを用いたiOSの評価環境より圧倒的に秀逸であると感じました。返金後に即座にメールで通知がくるのもわかりやすくてよいです。
一方、iOSのsandbox環境は返金が完了したのか、購入が完了したのかが管理画面から全く分かりません。また、返金完了がアプリからしかわからないというクソ仕様で繰り返しテストするのに常にアプリから購入できるかどうかをpollingする必要がありました。タイムラグも相まって、非常に評価しづらい環境でした。
さらにiOSは、sandbox環境で購入しようとすると、購入画面が二度表示されたり、ユーザーキャンセルはしていないのにエラー要因でユーザーキャンセルが通知されたりとボロボロでした。。
AndroidとiOSのアプリ開発でそれぞれメリットデメリットがありますが、課金の評価に関してはAndroidの圧勝だと思われます。
コメント