Windows Phone中In-App Purchase應用內購買

>>>  技術話題—商業文明的嶄新時代  >>> 簡體     傳統

前言

      應用內購買(In-App Purchase)對于開發者來說絕對是一個非常重要的功能,它提供了一個便捷的入口供用戶來購買付費。在IAP盛行之前的游戲運營商一般都是通過接入第三方支付入口來收費。之前做過的一個安卓手機游戲服務器(Asp.Net),他們采用的付費方式有兩種,一個是接入支付寶的接口,讓用戶可以通過支付寶來付費。還有一種是通過手機運營商來付費,先由用戶把錢付給運營商,運營商通過你注冊的服務器的API告知該用戶已付費。在Windows Phone 8中就不用担心第三方付費服務器的問題了,微軟為我們提供了一個付費的功能,也就是之前提到的IAP,付費的整個過程都是由微軟的交易平臺(Microsoft Commerce Platform)來提供支持的,通過Windows.ApplicationModel.Store命名空間下的API可以非常容易的實現IAP的功能,省去了很多接入第三方付費接口的調試時間。下面這張圖介紹了創建和購買虛擬物品的流程。

      a/b:開發者通過Dev Center注冊自己的付費App和所有虛擬物品信息。如果商品要從服務器下載,那么你需要自己提供這個服務器。

      c/d:開發者拉取Store上注冊的虛擬物品并展示在App內,由用戶來點擊購買。

      e/f:微軟交易平臺告知你的App用戶付費成功,并獲取電子收據。

      g/h:通過微軟交易平臺提供的收據作為憑證,從你的服務器下載虛擬物品。并告知交易平臺該商品已經成功分發。

      整個過程還是非常簡單清晰的,需要注意的是如果你的游戲非常的輕量,比如是個單機游戲,那么虛擬商品就不需要服務器的支持,電子收據這步可以省略掉。大型的手機游戲一般都會有后端服務器的支持。電子收據為我們從服務器下載插件時提供了有效的憑證。下面我們就先省略掉注冊應用和虛擬物品這兩個步驟,做一個簡單客戶端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將其展示在商品頁面上,供用戶選擇購買。

復制代碼
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。

復制代碼
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商品已經分發,整個購買過程結束。

復制代碼
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之旅吧。

 


作者: dgwutao
出處: http://www.cnblogs.com/ghostwutao/

關于作者:
從事微軟平臺解決方案的設計與實現。主要專注于Windows Phone應用開發。
新浪微博: @A-xel
E-mail:dgwutao#gmail.com

本文版權歸作者所有,歡迎轉載,且在文章頁面明顯位置給出原文連接。

 


dgwutao 2014-07-10 10:59:48

[新一篇] Windows Phone XNA創建簡單局域網游戲

[舊一篇] 【cocos2d-x 手游研發----怪物智能AI】
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表