次のページに沿って試してみる。
Integrating Unity IAP In Your Game
Android向け
■ サンプルコードのままでは購入時にエラーが発生する件
前述のページのサンプルコードは一見Androidでも動くようにみえる。
が、実際には「出版社はこのアイテムを購入できません」というエラーが発生する。
このエラー自体はほかの原因でも発生するようだが、今回のサンプルコードのケースではまず必要な部分が抜けている。
実に単純な話でアプリのライセンスキーが設定されていないことが理由。
自分の勘所が悪く情報にたどり着くまでに遠回りしてしまったが、ひとまず期待通り動作させる記述がわかった。
サンプルコードのメソッド InitializePurchasing() へライセンスキーをセットする処理を追加する。
具体的には次のようにbuilderインスタンスを取得した後に設定を付与する。
var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
#if UNITY_ANDROID
builder.Configure<IGooglePlayConfiguration>().SetPublicKey("パブリックキー");
#endif
この修正により実機で動作することを確認できた。
※ もちろんサンプルコードのうち product id なども適宜自分のアプリ用に書き換えること。
2016/04/28 しばらく手一杯でIAPモジュールの更新をキャッチアップできていなかった。
IAPモジュールの更新が行われ公開鍵に関してはより安全な方法で設定できるようになっているようだ。
具体的にはこちらマニュアル:レシート検証。
ページの主題はクライアント側でレシートを検証する手順の説明だが、公開鍵を暗号化して保存する手順について記述されている。
これでソースに公開鍵を記述しなくて済む。
購入結果のレシート情報
■ Android
ストアでの決済が正常終了すると以下の構造で処理結果が用意されるようだ。
下の記述ではPayloadとjsonを普通のプロパティのように記述しているが、実際にはそれぞれ文字列で格納されている。
{
"Store":"GooglePlay",
"TransactionID":"GPA.1111-2222-3333-44444",
"Payload": {
"json":{
"orderId":"GPA.1111-2222-3333-44444",
"packageName":"com.example.application",
"productId":"com.example.application.item",
"purchaseTime":9999999999999,
"purchaseState":0,
"purchaseToken":"トークン文字列"
},
"signature":"シグネチャ文字列"
}
}
もしproductIdなどを取り出す場合には要注意。Payloadを文字列として取り出してJSONオブジェクトへ変換し、そのオブジェクトのjsonプロパティを文字列として取り出してJSONオブジェクトへ変換するという手順が必要。(下記のコードはLitJSONを使った場合のもの。JsonUtilityを使うのであればモデルクラスの用意が必要か?)
var receiptJson = JsonMapper.ToObject(receipt);
var payload = JsonMapper.ToObject((string)receiptJson["Payload"]);
var content = JsonMapper.ToObject((string)payload["json"]);
var productId = (string)content["productId"];
上記のjsonパートの詳細はIn-app Billing ReferenceのTable 4に説明がある。
■ iOS
ストアでの決済が正常終了すると以下の構造で処理結果が用意されるようだ。
Payloadは長い文字列。ストアのセッション情報か?。AndroidでPayloadが文字列表現だった理由がわかる。
{
"Store":"AppleAppStore",
"TransactionID":"1999999999999999",
"Payload": "ABCDEFGH~"
}
Payloadはレシートの検証の際に使用する。
クライアントで検証を行う手順はUnityのサイトに記述がある。
サーバーで検証を行う手順についてはここでは触れない。
アプリケーション全体を通してシングルトンで利用する
サンプルコードの public void InitializePurchasing() の中を見ると分かるが、初期化時点の Purchaser のインスタンスをつかんでしまっている。
UnityPurchasing 自体がどうやらシングルトン実装らしく初期化を何度呼び出しても最初につかんだ Purchaser のインスタンスが生きている模様。(2回目以降の初期化呼び出しは無視される?)
今のところつかんだインスタンスを差し替えることは出来ないようなので Purchaser はアプリケーション全体を通してシングルトンで利用するのが正解か。
要するにゲームの開始時点で Purchaser を初期化したら、その GameObject は DontDestroyOnLoad() しておく。
購入処理の終了をアプリケーションへコールバックしたいのであれば Purchaser に UnityEvent を用意しておき、アプリケーション側からは必要に応じて AddListener()、RemoveListener() するのがよさそう。
IAPのデモ
Unityが提供するパッケージにはIAPのデモが含まれていて、コードはBitbucketで公開されている。
ちなみに、このデモのコードにはAndroidでのパブリックキーを渡す記述が書いてあったりする。