應用內購買(In-App Purchase)對於開發者來講絕對是一個很是重要的功能,它提供了一個便捷的入口供用戶來購買付費。在IAP盛行以前的遊戲運營商通常都是經過接入第三方支付入口來收費。以前作過的一個安卓手機遊戲服務器(Asp.Net),他們採用的付費方式有兩種,一個是接入支付寶的接口,讓用戶能夠經過支付寶來付費。還有一種是經過手機運營商來付費,先由用戶把錢付給運營商,運營商經過你註冊的服務器的API告知該用戶已付費。在Windows Phone 8中就不用擔憂第三方付費服務器的問題了,微軟爲咱們提供了一個付費的功能,也就是以前提到的IAP,付費的整個過程都是由微軟的交易平臺(Microsoft Commerce Platform)來提供支持的,經過Windows.ApplicationModel.Store命名空間下的API能夠很是容易的實現IAP的功能,省去了不少接入第三方付費接口的調試時間。下面這張圖介紹了建立和購買虛擬物品的流程。web
a/b:開發者經過Dev Center註冊本身的付費App和全部虛擬物品信息。若是商品要從服務器下載,那麼你須要本身提供這個服務器。windows
c/d:開發者拉取Store上註冊的虛擬物品並展現在App內,由用戶來點擊購買。後端
e/f:微軟交易平臺告知你的App用戶付費成功,並獲取電子收據。服務器
g/h:經過微軟交易平臺提供的收據做爲憑證,從你的服務器下載虛擬物品。並告知交易平臺該商品已經成功分發。app
整個過程仍是很是簡單清晰的,須要注意的是若是你的遊戲很是的輕量,好比是個單機遊戲,那麼虛擬商品就不須要服務器的支持,電子收據這步能夠省略掉。大型的手機遊戲通常都會有後端服務器的支持。電子收據爲咱們從服務器下載插件時提供了有效的憑證。下面咱們就先省略掉註冊應用和虛擬物品這兩個步驟,作一個簡單客戶端IAP的例子。異步
private async void LoadListingInformationAsync() { try { // Query the Windows Phone Store for the in-app products defined for the currently-running app. var listingInformation = await CurrentApp.LoadListingInformationAsync(); foreach (var v in listingInformation.ProductListings) { Products.Add(new ProductViewModel() { Title = v.Value.Name, ProductId = v.Value.ProductId, ImageUri = v.Value.ImageUri }); } } catch { // An exception is expected to be raised by CurrentApp.LoadListingInformationAsync()
//when it is not called from an app installed from the Windows Phone Store. } }
上面這段代碼就是異步的從Store中獲取咱們事先註冊好的虛擬物品集合。CurrentApp是一個很是重要的類,它包含了全部主要操做虛擬物品的方法。經過上面的方法獲取到虛擬物品的信息後,咱們就能夠對數據作進一步的處理,例子當中用一個ObservableCollection類型的集合Producets來保存數據,並經過databinding將其展現在商品頁面上,供用戶選擇購買。async
private async void PurchaseProduct(string productId) { try { // Kick off purchase; don't ask for a receipt when it returns await CurrentApp.RequestProductPurchaseAsync(productId, false); // Now that purchase is done, give the user the goods they paid for // (DoFulfillment is defined later) //DoFulfillment(); } catch (Exception ex) { // When the user does not complete the purchase (e.g. cancels or navigates back from the Purchase Page),
// an exception with an HRESULT of E_FAIL is expected. } }
當用戶肯定要購買某項虛擬物品的時候經過調用RequestProductPurchaseAsync方法來開啓用戶付費的過程,這個方法須要兩個參數,一個是以前獲取到的虛擬物品的id,另外一個是bool類型的參數,表明在付費成功後是否要返回購買虛擬物品的電子收據,電子收據是一個xml格式的信息。若是用戶沒有完成付費操做,好比取消或者經過back鍵返回等,都會觸發一個錯誤類型爲E_FALL的Exception。this
public void DoFulfillment() { var productLicenses = CurrentApp.LicenseInformation.ProductLicenses; DistributeProduct(productLicenses); } private void DistributeProduct(IReadOnlyDictionary<string, ProductLicense> productLicenses) { var bagOfSilver = new Regex(@"Bag\.Silver\.(\d+)"); foreach (ProductLicense license in productLicenses.Values) { if (license.IsConsumable && license.IsActive) { var m = bagOfSilver.Matches(license.ProductId); if ((m.Count == 2) && (m[1].Success)) { m_silverCount += int.Parse(m[1].Value); CurrentApp.ReportProductFulfillment(license.ProductId); } } } }
當用戶付費成功後咱們就能夠在App裏面將虛擬物品分發給用戶,經過CurrentApp.LicenseInformation.ProductLicenses獲取到用戶購買的虛擬物品的受權license,ProductLicenses是一個IDictionary類型的集合,能夠經過TryGetValue方法獲取到某個商品的受權。IsConsumable屬性表明商品能夠進行消費,IsActive屬性表明這個license是有效的。若是license有效,咱們就能夠把虛擬物品分發給用戶了。最後還要調用ReportProductFulfillment方法告訴Store商品已經分發,整個購買過程結束。spa
public async Task<bool> LoadLevelAsync(string levelProductId) { var license = CurrentApp.LicenseInformation.ProductLicenses[levelProductId]; if (!license.IsActive) { // User doesn't own this level return false; } if (!IsLevelDownloaded(levelProductId)) { var receiptXml = await CurrentApp.GetProductReceiptAsync(levelProductId); await DownloadLevelAsync(receiptXml); } // TODO: Load the level return true; } private async Task DownloadLevelAsync(string receiptXml) { var webReq = (HttpWebRequest)WebRequest.Create(sc_DownloadUrl); webReq.Method = "POST"; AddStringToWebRequestStream(webReq, receiptXml); WebResponse response = await webReq.GetResponseAsync(); // TODO: Save the level to disk }
若是咱們的虛擬物品要從本身的服務器下載好比皮膚和主題文件,使用GetProductReceiptAsync方法獲取電子收據recipt。有了電子收據方便咱們的服務器對惡意的商品請求作出過濾,避免第三方經過不法手段獲取虛擬商品。插件
Windows Phone Store的IAP已經封裝成了一個很是方便的接口,若是你尚未註冊虛擬物品到Dev Center能夠先經過CurrentAppSimulator類來模擬整個過程。IAP絕對是一個有益於開發者的特性,能夠吸引更多的開發者來完善整個生態圈。那麼就開始你的IAP之旅吧。