private async Task <PurchaseResult> GetPurchaseResult(BillingResult billingResult, IList <Purchase> purchases) { var purchaseResult = new PurchaseResult(); if (billingResult.ResponseCode == BillingResponseCode.Ok && purchases != null) { purchaseResult.PurchaseState = Plugin.XFInAppBilling.PurchaseState.Purchased; if (purchases?.Count > 0) { var purchaseResults = await GetPurchasesAsync(purchases); purchaseResult = purchaseResults?.OrderByDescending(p => p.ExpirationDate).Last(); } } else if (billingResult.ResponseCode == BillingResponseCode.UserCancelled) { purchaseResult.PurchaseState = Plugin.XFInAppBilling.PurchaseState.Cancelled; } else if (billingResult.ResponseCode == BillingResponseCode.ItemAlreadyOwned) { purchaseResult.PurchaseState = Plugin.XFInAppBilling.PurchaseState.AlreadyOwned; } else { purchaseResult.PurchaseState = Plugin.XFInAppBilling.PurchaseState.Failed; } return(purchaseResult); }
/// <summary> /// Get All Purchases /// </summary> /// <param name="itemType">not used for UWP</param> /// <returns></returns> public async Task <List <PurchaseResult> > GetPurchasesAsync(ItemType itemType = ItemType.InAppPurchase, IInAppBillingVerifyPurchase verifyPurchase = null, string verifyOnlyProductId = null) { if (context == null) { context = StoreContext.GetDefault(); } var PurchaseHistoryResult = new List <PurchaseResult>(); StoreAppLicense appLicense = await context.GetAppLicenseAsync(); if (appLicense?.AddOnLicenses?.Count > 0) { foreach (var addOnLicense in appLicense.AddOnLicenses) { StoreLicense license = addOnLicense.Value; var purchaseHistory = new PurchaseResult(); purchaseHistory.Sku = license.InAppOfferToken; //UWP SkuStoreId is different than Product ID, InAppOfferToken is the product ID purchaseHistory.PurchaseToken = license.SkuStoreId; purchaseHistory.ExpirationDate = license.ExpirationDate; if (!license.IsActive) { purchaseHistory.PurchaseState = PurchaseState.Cancelled; } else { purchaseHistory.PurchaseState = PurchaseState.Purchased; } PurchaseHistoryResult.Add(purchaseHistory); } } // The customer does not have a license to the subscription. return(PurchaseHistoryResult); }
/// <summary> /// GetPurchases handler /// </summary> /// <param name="purchases"></param> /// <returns></returns> private async Task <List <PurchaseResult> > GetPurchasesAsync(IList <Purchase> purchases) { var purchaseResults = new List <PurchaseResult>(); if (purchases?.Count > 0) { foreach (var purchase in purchases) { var purchaseResult = new PurchaseResult(); Plugin.XFInAppBilling.PurchaseState purchaseState; switch (purchase.PurchaseState) { case Android.BillingClient.Api.PurchaseState.Pending: purchaseState = Plugin.XFInAppBilling.PurchaseState.Pending; break; case Android.BillingClient.Api.PurchaseState.Purchased: // Acknowledge the purchase if it hasn't already been acknowledged. if (await NotifyFullFillmentAsync(purchase)) { purchaseState = Plugin.XFInAppBilling.PurchaseState.Purchased; } else { purchaseState = Plugin.XFInAppBilling.PurchaseState.NotAknowledged; } break; case Android.BillingClient.Api.PurchaseState.Unspecified: purchaseState = Plugin.XFInAppBilling.PurchaseState.Unspecified; break; default: purchaseState = Plugin.XFInAppBilling.PurchaseState.Unspecified; break; } purchaseResult.Sku = purchase.Sku; purchaseResult.PurchaseToken = purchase.PurchaseToken; purchaseResult.PurchaseState = purchaseState; if (purchase.PurchaseTime > 0) { purchaseResult.PurchaseDate = DateTimeOffset.FromUnixTimeMilliseconds(purchase.PurchaseTime).DateTime; } purchaseResult.DeveloperPayload = purchase.DeveloperPayload; purchaseResult.IsAcknowledged = purchase.IsAcknowledged; purchaseResult.IsAutoRenewing = purchase.IsAutoRenewing; purchaseResult.OrderId = purchase.OrderId; purchaseResults.Add(purchaseResult); } } return(purchaseResults); }
/// <summary> /// Does a purchase on BillingClient /// </summary> /// <param name="productId">Sku of Product or Subscription to purchase</param> /// <param name="itemType">subscription or iap product</param> /// <param name="payload">developer payload to verify</param> /// <param name="verifyPurchase">not used, only for IOS</param> /// <returns></returns> public async Task <PurchaseResult> PurchaseAsync(string productId, ItemType itemType = ItemType.InAppPurchase, string payload = null, IInAppBillingVerifyPurchase verifyPurchase = null) { var purchaseResult = new PurchaseResult(); var productIds = new List <string> { productId }; await GetProductsAsync(productIds, itemType); if (ProductToPurcase != null) { purchaseResult = await DoPurchaseAsync(ProductToPurcase); } return(purchaseResult); }
/// <summary> /// Gets all the purchased products for current user and app /// </summary> /// <param name="itemType">not used for UWP</param> /// <returns></returns> public async Task <List <PurchaseResult> > GetPurchaseHistoryAsync(ItemType itemType = ItemType.InAppPurchase) { if (context == null) { context = StoreContext.GetDefault(); // If your app is a desktop app that uses the Desktop Bridge, you // may need additional code to configure the StoreContext object. // For more info, see https://aka.ms/storecontext-for-desktop. } // Specify the kinds of add-ons to retrieve. string[] productKinds = { "Durable", "Subscription" }; var filterList = new List <string>(productKinds); StoreProductQueryResult queryResult = await context.GetUserCollectionAsync(filterList); if (queryResult.ExtendedError != null) { // The user may be offline or there might be some other server failure. throw new Exception(queryResult.ExtendedError.Message, queryResult.ExtendedError.InnerException); } var purchaseHistoryResult = new List <PurchaseResult>(); if (queryResult?.Products?.Count > 0) { foreach (KeyValuePair <string, StoreProduct> item in queryResult.Products) { StoreProduct product = item.Value; var purchaseHistory = new PurchaseResult(); purchaseHistory.Sku = product.InAppOfferToken; purchaseHistory.PurchaseToken = null; purchaseHistory.DeveloperPayload = product.Skus?[0].CustomDeveloperData; purchaseHistoryResult.Add(purchaseHistory); // Use members of the product object to access info for the product... } } return(purchaseHistoryResult); }
/// <summary> /// Purchase History Response Handler /// </summary> /// <param name="billingResult"></param> /// <param name="purchases"></param> public void OnPurchaseHistoryResponse(BillingResult billingResult, IList <PurchaseHistoryRecord> purchases) { try { PurchaseHistoryResult = new List <PurchaseResult>(); if (billingResult.ResponseCode == BillingResponseCode.Ok || billingResult.ResponseCode == BillingResponseCode.ItemAlreadyOwned) { if (purchases?.Count > 0) { foreach (var purchase in purchases) { var purchaseHistory = new PurchaseResult { Sku = purchase.Sku, PurchaseToken = purchase.PurchaseToken }; if (purchase.PurchaseTime > 0) { purchaseHistory.PurchaseDate = DateTimeOffset.FromUnixTimeMilliseconds(purchase.PurchaseTime).DateTime; } purchaseHistory.DeveloperPayload = purchase.DeveloperPayload; PurchaseHistoryResult.Add(purchaseHistory); } } _tcsPurchaseHistory?.TrySetResult(PurchaseHistoryResult); } else { var errorCode = GetErrorCode(billingResult.ResponseCode); _tcsPurchaseHistory?.TrySetException(errorCode); } } catch (Exception ex) { _tcsPurchaseHistory?.TrySetException(ex); } }
public async void OnConsumeResponse(BillingResult billingResult, String purchaseToken) { try { PurchaseResult purchaseResult = await GetPurchaseResult(billingResult, null); var errorCode = GetErrorCode(billingResult.ResponseCode); if (errorCode != null) //No error { _tcsConsume?.TrySetException(errorCode); } else { _tcsConsume?.TrySetResult(purchaseResult); } } catch (Exception ex) { _tcsConsume?.TrySetException(ex); } }
/// <summary> /// Purchase Handler /// </summary> /// <param name="billingResult"></param> /// <param name="purchases"></param> public async void OnPurchasesUpdated(BillingResult billingResult, IList <Purchase> purchases) { try { PurchaseResult purchaseResult = await GetPurchaseResult(billingResult, purchases); var errorCode = GetErrorCode(billingResult.ResponseCode); if (errorCode != null) //No error { _tcsPurchase?.TrySetException(errorCode); } else { _tcsPurchase?.TrySetResult(purchaseResult); } } catch (Exception ex) { _tcsPurchase?.TrySetException(ex); } }
/// <summary> /// Purchase a specific product or subscription /// </summary> /// <param name="productId">Sku or ID of product</param> /// <param name="itemType">Type of product being requested</param> /// <param name="payload">Developer specific payload</param> /// <param name="verifyPurchase">Interface to verify purchase</param> /// <returns></returns> public async Task <PurchaseResult> PurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null) { var p = await PurchaseAsync(productId); var reference = new DateTime(2001, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); var purchase = new PurchaseResult { PurchaseDate = reference.AddSeconds(p.TransactionDate.SecondsSinceReferenceDate), OrderId = p.TransactionIdentifier, Sku = p.Payment?.ProductIdentifier ?? string.Empty, PurchaseState = p.GetPurchaseState(), PurchaseToken = p.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None) ?? string.Empty }; if (verifyPurchase == null) { return(purchase); } var validated = await ValidateReceipt(verifyPurchase, purchase.Sku, purchase.OrderId); return(validated ? purchase : null); }
public Task <bool> FinishTransaction(PurchaseResult purchase) { throw new NotImplementedException(); }
public Task <bool> FinishTransaction(PurchaseResult purchase) => FinishTransaction(purchase?.OrderId);