'Microsoft Store API : Unable to get License Information of all addons
private async Task<bool> CheckIfUserHasSubscriptionAsync()
{
StoreAppLicense appLicense = await storeContext.GetAppLicenseAsync();
// Check if the customer has the rights to the subscription.
foreach (var addOnLicense in appLicense.AddOnLicenses)
{
StoreLicense license = addOnLicense.Value;
if (license.SkuStoreId.StartsWith(subscriptionStoreId))
{
if (license.IsActive)
{
// The expiration date is available in the license.ExpirationDate property.
return true;
}
}
}
// The customer does not have a license to the subscription.
return false;
}
Above is small code from MSDN Docs that would read Addon License Infomation. I have purchased two addons, One of Consumable Type and another of Subscription Type. When i query store it only returns Subscription Type addon information. The loop goes in only once. why? Is there another way to get list of all addons that a user owns ? Or am I doing something wrong here ?
Regards
Updated on 15-3-2022
Adding screenshot of addons I as a user Owns.
-
Updated on 24-3-2022
Hi Roy, To refresh, I now have 3 addons purchased.
1 of type Consumable and
2 of type subscription, out of which one subscription has trial period.
Once again I would like to bring to notice that loop foreach (var addOnLicense in appLicense.AddOnLicenses) only retrieves subscription type of addon details. (Is this bug ?)
Information obtained is as below, but it has no details like,
is FreeSubscriptionWithTrailPeriod is in Trial Period ?
appLicense.ExtendedJsonData
{
"productAddOns":[
{
"devOfferId":"",
"inAppOfferToken":"FreeSubscriptionWithTrailPeriod",
"productId":"9-P-S-Z-Z-6K",
"productType":"Durable",
"skuId":"0020",
"skuType":"Full",
"expiration":"2022-04-03 00:00:00",
"isActive":true
},
{
"devOfferId":"",
"inAppOfferToken":"FreeChirpSubscriptionForTest",
"productId":"9_Q-X-1-K-X-",
"productType":"Durable",
"skuId":"0020",
"skuType":"Full",
"expiration":"2022-04-15 00:00:00",
"isActive":true
}
],
"productId":"9-T9-Z-6-7-Z",
"skuId":"0010",
"isActive":true,
"isTrial":false,
"isTrialOwnedByThisUser":false,
"isDiscLicense":false,
"expiration":"9999-12-31 00:00:00",
"trialTimeRemaining":"10675199.02:48:05.477581"
}
Going further I tried your suggestion on GetUserCollectionAsync() method. Here i get following output taken from
(StoreProduct) product.ExtendedJsonData
So the question drills down to how to interpret this data. to find details like is it in trial period? When Trial expires or when subscription expires ?
I am listing some of import items only
"ProductId": "9-P-S-Z-Z-6K",
"Properties": {
"PackageFamilyName": null,
"InAppOfferToken": "FreeSubscriptionWithTrailPeriod"
},
"ProductKind": "Durable",
"DisplaySkuAvailabilities": [
{
"Sku": {
"LocalizedProperties": [
{
"SkuDescription": "Coding Games.",
"SkuTitle": "Players: Testing Free with Trial Period",
"SkuButtonTitle": "",
"SkuDisplayRank": [],
"LegalText": {
"Copyright": "",
"CopyrightUri": "",
"PrivacyPolicy": "",
"PrivacyPolicyUri": "https:....",
"Tou": "",
"TouUri": ""
},
"Language": "en"
}
],
"Properties": {
"CustomDeveloperData": "MaxPlayers=2\r\nMaxLevel=5",
"FulfillmentType": null,
"BundledSkus": null,
"IsRepurchasable": true,
"SkuDisplayRank": 0,
"IsTrial": false
},
"SkuId": "0020",
"RecurrencePolicy": null,
"CollectionData": {
"acquiredDate": "2022-03-24T11:38:55.3972654+00:00",
"autoRenew": true,
"additionalIds": [],
"devOfferId": "",
"effectiveBeneficiaries": [],
"endDate": "2022-04-03T00:00:00+00:00",
"externalReferences": [],
"fulfillmentData": [],
"inAppOfferToken": "FreeSubscriptionWithTrailPeriod",
"isCacheable": true,
"isTrial": true,
"itemId": "edb3c746efff41f0a85e126c67854f4d",
"localTicketReference": "0",
"modifiedDate": "2022-03-24T11:38:55.3985601+00:00",
"musicTracksInfo": [],
"orderId": "cc19857a-56f4-479d-8f42-c216375abd7d",
"orderLineItemId": "0c797e10-83d9-4ab2-a7b8-2fd2b1d502c1",
"ownershipType": "OwnedByBeneficiary",
"productFamily": "",
"productId": "9NP3S4Z1ZD6K",
"productKind": "Durable",
"productTitleId": "-129071",
"purchasedCountry": "IN",
"quantity": 1,
"recurrenceId": "mdr:310574664085794:aeac68161e404372931218beff5a10d1:cc19857a-56f4-479d-8f42-c216375abd7d",
"skuId": "0020",
"skuType": "Full",
"sharingSource": "None",
"startDate": "2022-03-24T00:00:00+00:00",
"status": "Active",
"tags": [],
"transactionId": "cc19857a-56f4-479d-8f42-c216375abd7d"
}
},
"Availabilities": [
{
"Actions": [
"License"
],
"AvailabilityId": "9-9-4-K-V-7D",
"Conditions": {
"EndDate": "9998-12-30T00:00:00.0000000Z"
},
"OrderManagementData": {
"Price": {
"CurrencyCode": "USD",
"ListPrice": 0,
"MSRP": 0
}
},
"DisplayRank": 0
}
]
}
Few more questions arises like, DisplaySkuAvailabilities is an array or collection, so when to expect more then one sku ?
Regards
Solution 1:[1]
Update:
Try this:
string[] productKinds = { "Durable", "Consumable", "UnmanagedConsumable" };
List<String> filterList = new List<string>(productKinds);
workingProgressRing.IsActive = true;
StoreProductQueryResult queryResult = await context.GetUserCollectionAsync(filterList);
For more information, please check: Get product info for apps and add-ons
Old:
There are two types of consumable add-ons
Developer-managed consumable. For this type of consumable, you are responsible for keeping track of the user's balance of items that the add-on represents, and for reporting the purchase of the add-on as fulfilled to the Store after the user has consumed all of the items. The user cannot purchase the add-on again until your app has reported the previous add-on purchase as fulfilled.
Store-managed consumable. For this type of consumable, the Store keeps track of the user's balance of items that the add-on represents. When the user consumes any items, you are responsible for reporting those items as fulfilled to the Store, and the Store updates the user's balance. The user can purchase the add-on as many times as they want (they do not need to consume the items first). Your app can query the Store for the current balance for the user at any time.
If you are using Store-managed consumable, you could check the remaining balance for the consumable add-on using StoreContext.GetConsumableBalanceRemainingAsync() Method. Like this:
string addOnStoreId = "YourID";
StoreConsumableResult result = await context.GetConsumableBalanceRemainingAsync(addOnStoreId);
switch (result.Status)
{
case StoreConsumableStatus.Succeeded:
textBlock.Text = "Remaining balance: " + result.BalanceRemaining;
break;
case StoreConsumableStatus.NetworkError:
textBlock.Text = "Could not retrieve balance due to a network error. " +
"ExtendedError: " + extendedError;
break;
case StoreConsumableStatus.ServerError:
textBlock.Text = "Could not retrieve balance due to a server error. " +
"ExtendedError: " + extendedError;
break;
default:
textBlock.Text = "Could not retrieve balance due to an unknown error. " +
"ExtendedError: " + extendedError;
break;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

