Windows Phone 8 のアプリ内課金をエミュレータで試す : (1)環境を作る

Windows Phone 8 SDK Advent Calendar Day 7 です。

Windows PhoneにLINEのスタンプがない理由の一つであるアプリ内課金でありますが、Windows Phone 8でようやくサポートされました。今回はこのアプリ内課金をローカルで試してみたいと思います。

アプリ内課金のフローとしては、下図の通りです。(Windows Phone 8 のアプリ内購入からの引用)

  • ストアにアプリと、アプリ内製品を登録します。(A,B)
  • アプリはアプリ内課金を行おうとした時に、ストアからアプリ一覧を取得します。(C)
  • 課金を実行(D)すると、ライセンス一覧を取得して課金が通ったものの一覧を取得できます。(E)
  • 課金によってコンテンツがサーバーから配信される場合はレシート情報を受信(F)してサーバーに送って(G)、ダウンロード(H)します。

iOS では、サーバーがレシート情報を照合する際、Appleのサーバーにレシートを送って正規性を照合するのですが、Windows Phoneでは署名を検証して行います。各開発者で実装の手間が増えますが、検証サービスに処理が集中してフローが失敗するということが起こりづらいのが利点でしょう。

このページではアプリ内課金のテストの方法として、「コンポーネントを分割しておいてちゃんと単体テストを書いてテストする」ということと「ベータ版配布を使って配布して確認する」という方法(ベータ配布のときは有料に見えるけど実は課金されない仕組みらしいです)、そして「エミュレータでテストする」の3つの方法が挙がっています。

今回はさっくり試すために「エミュレータでテストする」というのをやってみますが、これがまた結構泥臭かった…。設定するところまでで力尽きてしまいました。

IISASP.NET 4.5をインストール

このテストをするためにはローカルにストアのモックサービスを立てる必要があります。ASP.NET 4.5 の動くIISを立てます。Windowsの役割の追加から「インターネットインフォメーションサービス」の「Web管理ツール」の「IIS管理コンソール」と「World Wide Webサービス」「アプリケーション開発機能」の「ASP.NET 4.5」をチェックしてOKを押します。

次に、Web Platform Installer から Web Deployment Tool を入れます。

IISにモックサービスを登録する

まず、「C:\IapcatalogMockService\CatalogServiceMock」というディレクトリを作成し、 IIS_IUSRS に書き込み権限を与えます。

次にIISマネージャを開き、Webサイトの追加をします。

「サイト名」に「IAPCatalogMockService」として、物理パスを先ほど作成した「C:\IapcatalogMockService\CatalogServiceMock」としておきます。

80番ポートでかぶるのですが、これはDefault Web Sitesのほうを無効にします。

そして、ストアのモックサービスをWindows Phone Mock In-App Catalog Service Source Code sample in C# for Visual Studio 2012からダウンロードしてきて、ダウンロードしてきたzipの中にあるzipを展開してパッケージをデプロイするのですが、このパッケージには問題がありパスがちゃんと合わないため、修正したものをこちらにあげておきました。*1

ダウンロードしたパッケージを展開し、管理権限付きのコマンドプロンプトでこのフォルダに移動して CatalogServiceMockDeploymentPackage.deploy.cmd /Y を実行します。

すると、http://localhost/v8/help を叩くとAPI一覧の画面を見ることができます。

内部IPアドレスを調べてファイヤウォールの許可ルールを作成する

Windows Phone 8 エミュレータは、内部通信用のネットワークポートを持っていますが、このポートの通信は初期状態だとWindowsファイヤウォールでふさがっているので、ここぞとばかりに開放します。

まず、コマンドプロンプトで ipconfig を実行して、 Ethernet adapter vEthernet (Internal Ethernet Port Windows Phone Emulator Internal Switch)のIPアドレスを調べます。(以下、ここでは内部IPと呼びます)

次に、Windowsファイヤウォールに規則の追加で「TCPの」「すべてのポート*2」を「ローカル側の内部IP」を「全通過」するルールを作ります。






Windows Phone Emulator のイメージを書き換えて、ストアの通信をモックサービスに向ける

今回一番黒い部分です。

まず、Hyper-Vマネージャを開いて、すべてのエミュレータを削除します。

次に、「C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Emulation\Images」をエクスプローラーで開き、作業するエミュレータの読み取り専用フラグを解除します。僕の環境では最初から外れていました。

次に、このVHDをダブルクリックでで開きます。一気に4つほどドライブがマウントされます。

ここでマウントされたドライブの中から、Windows\System32\drivers\etc\hosts を探して、管理者権限のあるテキストエディタで開きます。内部IPをmarketplaceedgeservice.windowsphone.comに向けるエントリを追加して保存します。

(IPアドレス) marketplaceedgeservice.windowsphone.com

保存したら、コンピュータでマウントされたドライブを選んでリボンから「取り外し」します。

アプリ内課金アイテムを設定する

「C:\IapcatalogMockService\CatalogServiceMock\IapcatalogMockService」にある「iapcatalog.xml」というXMLがアプリ内課金アイテムの定義ファイルになってます。必要に応じてこれを編集します。

プロジェクトのプロダクトIDを変える

プロジェクトのプロダクトIDを「ee29a261-80d0-4bdf-89bd-28b1ebbc8bd3」に変更します。

通るかどうかやってみる

ひとまず、こんなコード書いてやってみました。

using Microsoft.Phone.Controls;
using System;
using System.Diagnostics;
using Windows.ApplicationModel.Store;

namespace IAPTest
{
    public partial class MainPage : PhoneApplicationPage
    {
        // コンストラクター
        public MainPage()
        {
            InitializeComponent();
            ListingTest();
        }

        private async void ListingTest()
        {
            var list = await CurrentApp.LoadListingInformationByProductIdsAsync(
                new string[] {"Test1", "Test2"});

            foreach (var item in list.ProductListings.Values)
            {
                Debug.WriteLine(item.Name);
            }
        }
    }
}

これで、デバッグウィンドウにアプリ内課金アイテムの名前が出力されます。

実際の課金処理については次回に続きます...

*1:IAPCatalogMockServicePackage.pubxmlのDesktopBuildPackageLocationを環境に合わせて書き換えて、DeployIisAppPathをIAPCatalogMockService/に変更しています。こうしないとルートがv8になってくれないのです。

*2:もちろん80だけでもいいです