はじめに
今回はUnity IAP
のCodelessIAP
という機能を用いて、簡単に非消費型(買い切り型)のアプリ内課金を実装してみるという記事になります。
先に言っておくと、Unityでの実装はすごく簡単ですが割とストア関連・テスト関連で躓くことの方が多いかもしれません。
Unity IAP SDKのインストール
Windos -> General -> Service
からService
ウィンドウを立ち上げます。

In-App Purchasing
をON
にします。

プロジェクトIDを作成していない場合
プロジェクトIDをまだ作成していなかった場合は以下の操作を行う必要があります。
組織・プロジェクトIDをリンクさせ、COPPAコンプライアンスという13歳未満を対象としているかどうかを選択します。

無事に以下の画像の画面が開けたら、Welcome
という欄の中にImport
ボタンがあるので、こちらからPlugins
をインストール。

するとPlugins/UnityPurchasing
がインポートされているはずです。
実装
IAP Buttonsを配置
Hierarchy
上で右クリックをし、Unity IAP -> IAP Button
を選択し、IAP Button
コンポーネントがアタッチされたButton
を作成します。

今回実装するのは広告削除・追加コンテンツといった買い切り型のアプリ内課金なので、以下の二つのボタンが必要になります。
- Non-Consumable(非消費型)Button:購入をするボタン
- Restore Button:購入データ復元のボタン(Androidの場合は不要だが、iOSの場合は必要)

IAP CatalogでProductsを定義
IAP Button
コンポーネントから、IAP Catalog...
というボタンを押し、IAP Catalog Window
を開きます。

プロダクトの定義の仕方については以下の公式ドキュメントを参照してみてください。
docs.unity3d.com
ざっと要点をまとめてみるとこんな感じ。
ID
はcom.<company name>.<game name&>.<product name>
のように表記します。文字は全て小文字で表記。(例.com.hanachiru.novelgame.removeads
)Type
はNon Consumable
Google Configuration
・Apple Configuration
のPrice
を設定(Google
のPrice
は日本円,Apple
は選択する)Automatically inititalize Unity Purchasing
を有効にする

※ 画像では誤ってProduct ID
に大文字を含んでしまっていますが、全て小文字にしてください。
※ GooglePlayのPrice
はドル表記ではなく、日本円表記で記載するみたいでした
またiOS
のPrice
と日本円の対応は以下になるそうです。(2022/2/4時)


IAP Buttonにプロダクトを設定する
購入用のIAP Button
をインスペクターからいじります。
Product ID
の設定ButtonType
をPurchase
にTitle Text
・Description Text
・Price Text
を用いるとIAP Catalog
で設定したものを反映させることができる(別に使わなくても良い)

次にRestore
用のIAP Button
のインスペクターを設定。
Button Type
をRestore
に設定

スクリプトを実装する
IAP Button
が押され、購入成功・失敗したときの処理を実装します。
public class IAPManager : MonoBehaviour { [SerializeField] private IAPButton buyButton; private void Awake() { // 購入ボタンを押されたとき、成功・失敗したときのイベントを登録する buyButton.onPurchaseComplete.AddListener(OnPurchaseComplete); buyButton.onPurchaseFailed.AddListener(OnPurchaseFailed); } private void OnDestroy() { // イベント解除 buyButton.onPurchaseComplete.RemoveListener(OnPurchaseComplete); buyButton.onPurchaseFailed.RemoveListener(OnPurchaseFailed); } private static void OnPurchaseComplete(Product product) { // 購入に成功した時とき Debug.Log("Remove Ads"); } private static void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) { // 購入処理に失敗したとき Debug.Log($"{product.definition.id} failed : {failureReason}"); } }

正しく設定をすると、以下のようにフェイクの購入画面が立ち上がるはずです。

Google Playで公開される場合はRestoreボタンを非表示にする
iOS
の場合はRestore
用のボタンが必須ですが、逆にAndriod
の場合は表示しないようにしないといけません。(Andriod
の場合は起動時に自動でRestore
される)
コードを少し追加します。
public class IAPManager : MonoBehaviour { [SerializeField] private IAPButton buyButton; [SerializeField] private IAPButton restoreButton; private void Awake() { // Androidの場合はRestore用のボタンを非表示にする if (Application.platform != RuntimePlatform.IPhonePlayer) { restoreButton.gameObject.SetActive(false); } buyButton.onPurchaseComplete.AddListener(OnPurchaseComplete); buyButton.onPurchaseFailed.AddListener(OnPurchaseFailed); } private void OnDestroy() { buyButton.onPurchaseComplete.RemoveListener(OnPurchaseComplete); buyButton.onPurchaseFailed.RemoveListener(OnPurchaseFailed); } private static void OnPurchaseComplete(Product product) { // 購入に成功した時とき Debug.Log("Remove Ads"); } private static void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) { // 購入処理に失敗したとき Debug.Log($"{product.definition.id} failed : {failureReason}"); } }

ストアの設定
Google Play Consoleで設定を行う
まずGoogle Playに提出するGooglePlayProductCatalog.csv
を生成します。
IAP Catalog
を立ち上げ、App Store Export -> Google Play CSV
を選択。

無事にファイルが出力できたら、Google Play Console
を開いてください。
対象アプリ(まだ作成していない場合は新規作成)の商品 -> アプリ内アイテムを選択し、設定を行います。
また以下のようにアイテム設定ができない場合は、必要情報を記入、アプリをビルドしてクローズドテストとして公開等すればいけるはずです。

無事に以下のような画面が表示されたら、作成したGooglePlayProductCatalog.csv
をアップロードすれば完了です。



App Store Connectで設定を行う
App Store Connect
のApp内課金 -> 管理
からApp内課金の項目を追加していきます。
- App内の課金のタイプは非消費型
- 参照名は自由に
- 製品IDは
IAP Catalog
に書いたID
(com.<company name>.<game name&>.<product name>
) - 価格は
IAP Catalog
に記載した値段 - App情報はストアの表示名
- スクリーンショットを添付

テスト課金
Andriod
Google Play Console
のダッシュボードを見てみると、クローズドテストに関するToDOリストがあるはずです。(なければクローズドテストにaab(apk)
をアップロードすれば出てくるはず)

こちらのタスクをまずはこなしてください。
テスターを指定すれば、対象者はアプリをダウンロードできますが、テスト課金でなく実際に課金されてしまうことに注意してください。

課金テストをする場合は、すべてのアプリが見える画面にて設定 -> ライセンス テスト
を選択、対象者のメールアドレスを記載すればOKです。

iOS
App Store Connect
の契約 / 税金 / 口座情報にて口座情報等を設定していない場合は設定します。(私はこれを忘れてずっと悩んでました)
App Store Connect
を開き、上のメニューバーにあるユーザーとアクセス
を選択。

sandbox -> テスター
を選択し、プラスマークよりテスターを追加します。

UnityでiOSビルドを行い、xcodeproj
を開きます。
あとはお手元のiPhone
にビルドを行い、テスターとして設定したアカウントにて購入を行えばOKです。
(補足) レシート検証
Codeless IAP
ではレシート検証が行われないとのことなので注意してください。(必ずやらなければならないわけではないです)
今回は例として、CrossPlatformValidator
を用いた簡易なローカル検証を実装してみます。
難読化
メニューバーよりWindow -> Unity IAP -> IAP Receipt Validation Obfuscator
を選択。

提示されている手法を上から実行していきます。
- Google Play Consoleを開き、対象アプリを選択、収益化のセットアップのライセンスからキーをコピー

Receipt Validation Obfuscator
にキーをペースト

Obfuscate Google Play License Key
をクリックOpen Analytics Dashboard
からリンクを飛び、Google Play License Key
をペースト

購入処理のコードに追記する
公式ドキュメントにサンプルコードがあるので、そちらに少し修正を加えて利用させていただきます。
private static void OnPurchaseComplete(Product product) { bool validPurchase = true; // R.V. のないプラットフォームに有効です // Unity IAP の検証ロジックはこれらのプラットフォームにのみ含まれます。 # if UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX // エディターの難読化ウィンドウで準備した機密を持つ // バリデーターを準備します。 var validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), Application.identifier); try { // Google Play で、result は 1 つの product ID を取得します // Apple stores で、receipts には複数のプロダクトが含まれます var result = validator.Validate(product.receipt); // 情報提供の目的で、ここにレシートをリストします Debug.Log("Receipt is valid. Contents:"); foreach (IPurchaseReceipt productReceipt in result) { Debug.Log(productReceipt.productID); Debug.Log(productReceipt.purchaseDate); Debug.Log(productReceipt.transactionID); } } catch (IAPSecurityException) { Debug.Log("Invalid receipt, not unlocking content"); validPurchase = false; } # endif if (validPurchase) { // 購入に成功した時とき Debug.Log("Remove Ads"); } }
具体的にはサンプルの以下の箇所を変更しています。
Application.bundleIdentifier
は廃止されたようなので、Application.identifier
に書き換えe.purchasedProduct.receipt
をproduct.receipt
に書き換え
またこのコードではレシートが有効であるかどうかの確認しかしていないので、レシートの中身を検証したいなどありましたら公式ドキュメント等を参照してください。
レシート検証 - Unity マニュアル