Windows Phone 8 内购FAQ

尽管MSDN里有一篇很好的关于Windows Phone 8内购的文章,我们这里还是收到很多内购相关的问题。这篇博客旨在为了补充MSDN文章中没有涵盖的一些细节。

我们听到很多有关于Windows Runtime和Windows Phone Runtime互相共享代码的事情。而且,的确内购部分是相互共享的。事实上,我们在MSDN上看到的有关于Windows Phone的文章数远远大于Windows Store。而且,由于很多API是Windows 8中独有的,例如 CurrentAppSimulator,ProductLicense.ExpirationDate等等,所以我们在阅读这些文章的时候要多加注意。

这篇博客主要是适用于Windows Phone的内购,不过,Windows 8 Store App和Windows Phone Store App在内购方面的流程还是很相似的。

MSDN相关文章:

  1. In-app purchase for Windows Phone 8 https://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206949(v=vs.105).aspx
  2. In-App Purchase API overview for Windows Phone 8 https://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206950(v=vs.105).aspx
  3. In-app purchase testing for Windows Phone 8 https://msdn.microsoft.com/en-us/library/windowsphone/develop/jj681689(v=vs.105).aspx
  4. Mock In-App Purchase Library https://code.msdn.microsoft.com/wpapps/Mock-In-App-Purchase-33080f0c
  5. In-app product properties https://msdn.microsoft.com/en-us/library/windowsphone/help/jj206721(v=vs.105).aspx
  6. In-app product description https://msdn.microsoft.com/en-us/library/windowsphone/help/jj206720(v=vs.105).aspx
  7. Beta testing your app and in-app products https://msdn.microsoft.com/en-us/library/windowsphone/help/jj215598(v=vs.105).aspx
  8. In-app purchase receipt verification https://code.msdn.microsoft.com/wpapps/In-app-purchase-receipt-c3e0bce4
  9. How to Set Up In-App Purchasing for Your Windows Phone App (VisualStudioMagazine.com)https://visualstudiomagazine.com/Articles/2013/07/01/In-App-Purchasing-for-Windows-Phone-8.aspx?Page=1

需要注意的是,”<Signature>”节点只会出现在我们从Store中购买的公开发行的App内购中。意思也就是说,若是一个Beta版的App,或者是在调试中的设备,这段节点是没有办法显示出来的。这样做虽然对于调试非常不利,但是直接上收据验证的过程是完全在服务器端完成的,我们仅仅需要保证完整的收据可以发送到服务器端就可以了。

作为一个Windows设备的开发者,千万不要漏掉In-app purchase receipt verification 这篇文章。这篇文章很好的讲解了如何验证交易成功与否。也曾经有很多人来问,哪里能申请到内购所需要的公钥 "IapReceiptProduction.cer" 。事实上,这个公钥正是随着实例代码发布的。

测试

唯一的可以测试 In-app purchase testing for Windows Phone 8的方案是创建我们自己的模拟事件。可以参考以下代码: Mock In-App Purchase Library,通过此篇文章描述,我们可以创建一个Beta版的App。不过Beta版本仅仅只能模拟交易,并不会真正的付费完成交易,正如上文提到的,是不会有收据的签名存在的。

如何判断购买是否成功

In-app purchase for Windows Phone 8这篇文章提供了一个很好的关于内购方面的解说。

Step E) Enumerate licenses这一段中:

“When you app launches, is resumed, or following a purchase, you use the in-app purchase APIs to enumerate all licenses this user has for products in your app. Using this information, you can determine whether the user already has the products they licensed, or whether fulfillment of some products is still required.”

抑或我们可以使用CurrentApp.RequestProductPurchaseAsync来判断是不是购买成功,但是这个仅仅只能使用在当场交易中。这里,我们应该调用API来枚举所有的授权,再判断是否已经购买过。

  1: public async Task<List<string>> GetOwnedItems()
  2:  
  3: {
  4:  
  5: List<string> items = new List<string>();
  6:  
  7: ListingInformation li = await CurrentApp.LoadListingInformationAsync();
  8:  
  9: foreach (string key in li.ProductListings.Keys)
  10:  
  11: {
  12:  
  13: if (CurrentApp.LicenseInformation.ProductLicenses[key].IsActive && StoreItems.ContainsKey(key))
  14:  
  15: items.Add(StoreItems[key]);
  16:  
  17: }
  18:  
  19: return items;
  20:  
  21: } 

关于可消耗的内购

Windows Phone Store和Windows Store里的内购有两种类型,一种是可消耗性的,一种是永久性的。对于永久性的购买,一经购买,在我们枚举授权的时候,”IsActive==True”就会一直存在。但是对于可消耗性的购买,例如游戏中的金币,我们就需要调用CurrentApp.ReportProductFulfillment method去判断了。

关于收据

我们这里有一些MSDN官方文档中没有的测试:

通过调用CurrentGetProductReceiptAsync,我们可以得到一段从微软服务器上发送来的XML代码来证明已经购买。一段典型的XML代码如下所示:

  1: <?xml version="1.0"?>
  2:  
  3: <Receipt Version="1.0" CertificateId="A656B9B1B3AA509EEA30222E6D5E7DBDA9822DCD" xmlns="https://schemas.microsoft.com/windows/2012/store/receipt">
  4:  
  5: <ProductReceipt PurchasePrice="$20.89" PurchaseDate="2012-11-30T21:32:07.096Z" Id="2f9c5c8f-3e1d-4fc7-a871-ac58f7e78053" AppId="3ec6cd9a-ca82-4d38-bfdf-ecafdb35a738" ProductId="Test" ProductType="Consumable" PublisherDeviceId="Test" MicrosoftProductId="59ef70aa-7099-4679-889e-f21919bfd2c6" />
  6:  
  7: <Signature xmlns="https://www.w3.org/2000/09/xmldsig#">
  8:  
  9: <SignedInfo>
  10:  
  11: <CanonicalizationMethod Algorithm="https://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
  12:  
  13: <SignatureMethod Algorithm="https://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
  14:  
  15: <Reference URI="">
  16:  
  17: <Transforms>
  18:  
  19: <Transform Algorithm="https://www.w3.org/2000/09/xmldsig#enveloped-signature" />
  20:  
  21: </Transforms>
  22:  
  23: <DigestMethod Algorithm="https://www.w3.org/2001/04/xmlenc#sha256" />
  24:  
  25: <DigestValue>FyFb1HGm+yeOIjt18M6TPD4Qzeu469vwDbQs7w72mdA=</DigestValue>
  26:  
  27: </Reference>
  28:  
  29: </SignedInfo> <SignatureValue>noct5CYBtRwBxVxkUeZIzeDyruLGVBqBMuFuBytpouPLACnQ5dbzdRvWX4XN67IUo0J2FW8DoYcMbf3sAS+PeKKV8SLnU+l8K1hWEbbbugHZezStTzwwkYcZuCTnAk7BYO0aiZWuXm9GiZGT9iyXsYtU1/u87L+llnVibU/m7gV8tD3vG0tVkjzV20C8666mHUsY/jxeq3ed7YY9CT0SDrh5PeL4ESaopBLcncHo/e6lcjyoKbO3e6YuIpsi8DVueeKNhpTlwa5yc0O3qzc5SGnT4Kbhj9NBEXf15/oTaLlg7lJhnQZ0mY+yR8vc4D0SkqD6e5Uc4u64hnu+g3Hphg==</SignatureValue>
  30:  
  31: </Signature>
  32:  
  33: </Receipt>

需要注意的是,”<Signature>”节点只会出现在我们从Store中购买的公开发行的App内购中。意思也就是说,若是一个Beta版的App,或者是在调试中的设备,这段节点是没有办法显示出来的。这样做虽然对于调试非常不利,但是直接上收据验证的过程是完全在服务器端完成的,我们仅仅需要保证完整的收据可以发送到服务器端就可以了。

作为一个Windows设备的开发者,千万不要漏掉In-app purchase receipt verification 这篇文章。这篇文章很好的讲解了如何验证交易成功与否。也曾经有很多人来问,哪里能申请到内购所需要的公钥 "IapReceiptProduction.cer" 。事实上,这个公钥正是随着实例代码发布的。

测试

唯一的可以测试 In-app purchase testing for Windows Phone 8的方案是创建我们自己的模拟事件。可以参考以下代码: Mock In-App Purchase Library ,通过此篇文章描述,我们可以创建一个Beta版的App。不过Beta版本仅仅只能模拟交易,并不会真正的付费完成交易,正如上文提到的,是不会有收据的签名存在的。