Version: 2017.2
Android アプリ内課金 (IAP) ストアにおける、ストア間を横断してプロダクトをインストールする場合の問題
ユニバーサル Windows プラットフォーム

iOS & Mac App Store

拡張機能

アプリ レシートを読む

アプリストアのレシート はデバイスのローカルストレージに保管されており、以下のようにして読むことができます。

var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
string receipt = builder.Configure<IAppleConfiguration>().appReceipt;

支払い制限の確認

アプリ内課金はデバイスの設定で制限されている場合があります。以下のようにして、確認できます。

var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
bool canMakePayments = builder.Configure<IAppleConfiguration>().canMakePayments;

トランザクションの復元

Apple のプラットフォーム上では、前回のトランザクションを取得するには、リストアするかどうかのボタンを表示して、ユーザーからパスワードを入力してもらわなくてはなりません。トランザクションの復元中、IStoreListenerProcessPurchase は、ユーザーがすでに所有しているアイテムすべてに実行されます。

/// <summary>
/// OnInitialized の IStoreListener 実装
/// </summary>
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
    extensions.GetExtension<IAppleExtensions> ().RestoreTransactions (result => {
        if (result) {
            // なにかがリストアされたというわけではありません
            // 単に復元の処理が終了したということです
        } else {
            // 復元失敗
        }
    });
}

App Store のレシートのリフレッシュ

Apple はサーバーから App Store の新しいレシートを取得する方法 SKReceiptRefreshRequest を提供しています。これは通常、ローカルストレージに現在レシートがキャッシュされていない場合に使用されます。

この方法にはパスワードが必要だということに気を付けてください。

Unity IAP では以下のようにこのメソッドを使用します。

/// <summary>
/// OnInitialized の IStoreListener 実装
/// </summary>
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
    extensions.GetExtension<IAppleExtensions> ().RefreshAppReceipt (receipt => {
        // リクエストが成功したら、このハンドラーが呼び出されます
        // レシートは最新の App Store レシート
        Console.WriteLine(receipt);
    },
    () => {
        // リクエストが失敗したら、このハンドラーが呼び出されます。
        // 例えば、ネットワークが使用不可であったり、
        // ユーザーが誤ったパスワードを入力した場合など。
    });
}

Ask to Buy (承認と購入のリクエスト)

iOS 8 introduced a new parental control feature; Ask to Buy

Ask to Buy は子供が課金を行う前に親の許可を求める機能です。この機能を使うと Unity IAP は以下のようにリスナーを登録することでアプリが通知を受け取ることができるようになります。

/// <summary>
/// This will be called when Unity IAP has finished initialising.
/// </summary>
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
    extensions.GetExtension<IAppleExtensions>().RegisterPurchaseDeferredListener(product => {
        Console.WriteLine(product.definition.id);
    });
}

親が購入を許可したら通常イベントの ProcessPurchase、却下したら通常イベントの OnPurchaseFailed が呼び出されます。

テスト

Apple ストアでテストをするには ITunes Connect でテストアカウントを作成し、そのテストアカウントで iTunes に接続しなければいけません。

iOS デバイスや Mac でストアからサインアウトして、アプリを起動し、課金やリストアを行うときにどのアカウントでログインするかを求められます。

NoProductsAvailable が原因で初期化に失敗したときは以下の内容を確認してください。

  • iTunes Connect で作成したプロダクト ID が Unity IAP のプロダクト ID と一致しているかどうか。
  • アプリ内課金の設定が iTunes Connect で有効になっているかどうか。
  • プロダクトが iTunes Connect で販売可能な状態になっているかどうか。
  • iTunes Connect で作成したプロダクトが購入可能になるまで数時間かかることがあります。
  • iTunes Connect の最新のデベロッパ契約に同意して、有効な振込先の情報を記入しているかどうか。

Mac App Store

Unity のビルド設定で Mac のスタンドアロン用に Mac App Store validation にチェックを入れておく必要があります。

アプリをビルドしたら、info.plist のバンドル ID とバージョン設定を更新する必要があります。.app ファイル上で右クリックして パッケージの内容を表示 を選択し、info.plist ファイルの CFBundleIdentifier の値をアプリのバンドル ID へと変更します。

そして署名をした後に、パッケージとアプリをインストールします。そのための操作は Mac OSX 上のターミナルで行います。

codesign -f --deep -s "3rd Party Mac Developer Application: " your.app/Contents/Plugins/unitypurchasing.bundle
codesign -f --deep -s "3rd Party Mac Developer Application: " your.app
productbuild --component your.app /Applications --sign "3rd Party Mac Developer Installer: " your.pkg

バンドルに署名するには、Contents.meta ファイルが存在する場合、まずこれを削除する必要があります。your.app/Contents/Plugins/unitypurchasing.bundle/Contents.meta

正しくパッケージをインストールするには、新しく作成したパッケージを実行する前にパッケージ化していない .app ファイルを削除しておく必要があります。

そして、アプリケーション フォルダーからアプリを起動します。初回は iTunes アカウントの詳細を入力するよう求められるので、iTunes Connect で作成したテストアカウントでログインします。これでテストアカウントがサンドボックス環境で課金を行うことができます。

Android アプリ内課金 (IAP) ストアにおける、ストア間を横断してプロダクトをインストールする場合の問題
ユニバーサル Windows プラットフォーム