Task <List <Purchase> > GetPurchasesAsync(string itemType, IInAppBillingVerifyPurchase verifyPurchase, string verifyOnlyProductId = null) { var getPurchasesTask = Task.Run(async() => { string continuationToken = string.Empty; var purchases = new List <Purchase>(); do { Bundle ownedItems = serviceConnection.Service.GetPurchases(3, Context.PackageName, itemType, null); var response = GetResponseCodeFromBundle(ownedItems); if (response != 0) { break; } if (!ValidOwnedItems(ownedItems)) { Console.WriteLine("Invalid purchases"); return(purchases); } var items = ownedItems.GetStringArrayList(RESPONSE_IAP_PURCHASE_ITEM_LIST); var dataList = ownedItems.GetStringArrayList(RESPONSE_IAP_PURCHASE_DATA_LIST); var signatures = ownedItems.GetStringArrayList(RESPONSE_IAP_DATA_SIGNATURE_LIST); for (int i = 0; i < items.Count; i++) { string data = dataList[i]; string sign = signatures[i]; var purchase = JsonConvert.DeserializeObject <Purchase>(data); if (verifyPurchase == null || (verifyOnlyProductId != null && !verifyOnlyProductId.Equals(purchase.ProductId))) { purchases.Add(purchase); } else if (await verifyPurchase.VerifyPurchase(data, sign, purchase.ProductId, purchase.OrderId)) { purchases.Add(purchase); } } continuationToken = ownedItems.GetString(RESPONSE_IAP_CONTINUATION_TOKEN); } while (!string.IsNullOrWhiteSpace(continuationToken)); return(purchases); }); return(getPurchasesTask); }
Task <bool> ValidateReceipt(IInAppBillingVerifyPurchase verifyPurchase, string productId, string transactionId) { if (verifyPurchase == null) { return(Task.FromResult(true)); } // Get the receipt data for (server-side) validation. // See: https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Introduction.html#//apple_ref/doc/uid/TP40010573 var receiptUrl = NSData.FromUrl(NSBundle.MainBundle.AppStoreReceiptUrl); var receipt = receiptUrl.GetBase64EncodedString(NSDataBase64EncodingOptions.None); return(verifyPurchase.VerifyPurchase(receipt, string.Empty, productId, transactionId)); }
/// <summary> /// Get all current purchases for a specific product type. If you use verification and it fails for some purchase, it's not contained in the result. /// </summary> /// <param name="itemType">Type of product</param> /// <param name="verifyPurchase">Verify purchase implementation</param> /// <returns>The current purchases</returns> public async Task <IEnumerable <InAppBillingPurchase> > GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null) { return(await GetPurchasesAsync(itemType, verifyPurchase, null)); }
public override Task <InAppBillingPurchase> UpgradePurchasedSubscriptionAsync(string newProductId, string oldProductId, string purchaseTokenOfOriginalSubscription, int prorationMode = 1, IInAppBillingVerifyPurchase verifyPurchase = null) { throw new NotImplementedException("UWP not supported."); }
public Task <PurchaseResult> ConsumePurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null) { throw new NotImplementedException(); }
/// <summary> /// Purchase iap or sub /// </summary> /// <param name="productId">iap or sub sku to be purchased</param> /// <param name="itemType">not required for amazon</param> /// <param name="payload">not used for amazon</param> /// <param name="verifyPurchase">not used for amazon</param> /// <returns></returns> public async Task <PurchaseResult> PurchaseAsync(string productId, ItemType itemType = ItemType.InAppPurchase, string payload = null, IInAppBillingVerifyPurchase verifyPurchase = null) { if (await CheckIfUserHasActiveSubscriptionAsync(productId)) { return new PurchaseResult() { PurchaseState = PurchaseState.Purchased, Sku = productId } } ; if (context == null) { context = AmazonIapV2Impl.Instance; } //bool userOwnsSubscription = await CheckIfUserHasSubscriptionAsync(subscriptionStoreId); //if (userOwnsSubscription) //{ // Settings.IsSubscribed = true; // // Unlock all the subscription add-on features here. // return true; //} // Construct object passed to operation as input //await Task.Delay(TimeSpan.FromMilliseconds(1));an.FromMilliseconds(1)); var taskCompletionSource = new TaskCompletionSource <PurchaseResult>(); try { SkuInput request = new SkuInput(); // Set input value request.Sku = productId; // Call synchronous operation with input object string requestId = context.Purchase(request).RequestId; // Get return value PurchaseResponseDelegator delegator = null; delegator = new PurchaseResponseDelegator(async response => { await Task.Run(() => { if (response.RequestId == requestId) { var result = GetPurchaseEventHandler(response); var sucess = taskCompletionSource.TrySetResult(result); //await Task.Delay(TimeSpan.FromMilliseconds(1)); context.RemovePurchaseResponseListener(delegator.responseDelegate); } }); }); // Register for an event context.AddPurchaseResponseListener(delegator.responseDelegate); return(await taskCompletionSource.Task); } catch (Exception) { return(new PurchaseResult() { PurchaseState = PurchaseState.Failed, Sku = productId }); } }
/// <summary> /// Consume a purchase /// </summary> /// <param name="productId">Id/Sku of the product</param> /// <param name="payload">Developer specific payload of original purchase</param> /// <param name="itemType">Type of product being consumed.</param> /// <param name="verifyPurchase">Verify Purchase implementation</param> /// <returns>If consumed successful</returns> /// <exception cref="InAppBillingPurchaseException">If an error occures during processing</exception> public async override Task <InAppBillingPurchase> ConsumePurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null) { var items = await CurrentAppMock.GetAvailableConsumables(InTestingMode); var consumable = items.FirstOrDefault(i => i.ProductId == productId); if (consumable == null) { throw new InAppBillingPurchaseException(PurchaseError.ItemUnavailable); } var result = await CurrentAppMock.ReportConsumableFulfillmentAsync(InTestingMode, productId, consumable.TransactionId); switch (result) { case FulfillmentResult.ServerError: throw new InAppBillingPurchaseException(PurchaseError.GeneralError); case FulfillmentResult.NothingToFulfill: throw new InAppBillingPurchaseException(PurchaseError.ItemUnavailable); case FulfillmentResult.PurchasePending: case FulfillmentResult.PurchaseReverted: throw new InAppBillingPurchaseException(PurchaseError.GeneralError); case FulfillmentResult.Succeeded: return(new InAppBillingPurchase { AutoRenewing = false, Id = consumable.TransactionId.ToString(), Payload = payload, ProductId = consumable.ProductId, PurchaseToken = consumable.TransactionId.ToString(), State = PurchaseState.Purchased, TransactionDateUtc = DateTime.UtcNow }); default: return(null); } }
protected async override Task <IEnumerable <InAppBillingPurchase> > GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase, string verifyOnlyProductId) { var purchases = await RestoreAsync(); if (purchases == null) { return(null); } var comparer = new InAppBillingPurchaseComparer(); var converted = purchases .Where(p => p != null) .Select(p2 => p2.ToIABPurchase()) .Distinct(comparer); var validPurchases = new List <InAppBillingPurchase>(); foreach (var purchase in converted) { if ((verifyOnlyProductId != null && !verifyOnlyProductId.Equals(purchase.ProductId)) || await ValidateReceipt(verifyPurchase, purchase.ProductId, purchase.Id)) { validPurchases.Add(purchase); } } return(validPurchases.Any() ? validPurchases : null); }
/// <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 override Task <InAppBillingPurchase> 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 InAppBillingPurchase { TransactionDateUtc = reference.AddSeconds(p.TransactionDate.SecondsSinceReferenceDate), Id = p.TransactionIdentifier, ProductId = p.Payment?.ProductIdentifier ?? string.Empty, State = p.GetPurchaseState(), PurchaseToken = p.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None) ?? string.Empty }; if (verifyPurchase == null) { return(purchase); } var validated = await ValidateReceipt(verifyPurchase, purchase.ProductId, purchase.Id); return(validated ? purchase : null); }
/// <summary> /// Consume a purchase /// </summary> /// <param name="productId">Id/Sku of the product</param> /// <param name="payload">Developer specific payload of original purchase</param> /// <param name="itemType">Type of product being consumed.</param> /// <param name="verifyPurchase">Verify Purchase implementation</param> /// <returns>If consumed successful</returns> public async override Task <InAppBillingPurchase> ConsumePurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase) { if (serviceConnection?.Service == null) { throw new InAppBillingPurchaseException(PurchaseError.ServiceUnavailable, "You are not connected to the Google Play App store."); } if (payload == null) { throw new ArgumentNullException(nameof(payload), "Payload can not be null"); } var purchases = await GetPurchasesAsync(itemType, verifyPurchase); var purchase = purchases.FirstOrDefault(p => p.ProductId == productId && p.Payload == payload && p.ConsumptionState == ConsumptionState.NoYetConsumed); if (purchase == null) { purchase = purchases.FirstOrDefault(p => p.ProductId == productId && p.Payload == payload); } if (purchase == null) { Console.WriteLine("Unable to find a purchase with matching product id and payload"); return(null); } var response = serviceConnection.Service.ConsumePurchase(3, Context.PackageName, purchase.PurchaseToken); var result = ParseConsumeResult(response); if (!result) { return(null); } return(purchase); }
async Task <Purchase> PurchaseAsync(string productSku, string itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase, JavaList <string> oldSkus = null) { lock (purchaseLocker) { if (tcsPurchase != null && !tcsPurchase.Task.IsCompleted) { return(null); } Bundle buyIntentBundle = null; if (oldSkus == null) { buyIntentBundle = serviceConnection.Service.GetBuyIntent(3, Context.PackageName, productSku, itemType, payload); } else { buyIntentBundle = serviceConnection.Service.GetBuyIntentToReplaceSkus(5, Context.PackageName, oldSkus, productSku, itemType, payload); } var response = GetResponseCodeFromBundle(buyIntentBundle); switch (response) { case 0: //OK to purchase break; case 1: //User Cancelled, should try again throw new InAppBillingPurchaseException(PurchaseError.UserCancelled); case 2: //Network connection is down throw new InAppBillingPurchaseException(PurchaseError.ServiceUnavailable); case 3: //Billing Unavailable throw new InAppBillingPurchaseException(PurchaseError.BillingUnavailable); case 4: //Item Unavailable throw new InAppBillingPurchaseException(PurchaseError.ItemUnavailable); case 5: //Developer Error throw new InAppBillingPurchaseException(PurchaseError.DeveloperError); case 6: //Generic Error throw new InAppBillingPurchaseException(PurchaseError.GeneralError); case 7: //already purchased throw new InAppBillingPurchaseException(PurchaseError.AlreadyOwned); } var pendingIntent = buyIntentBundle.GetParcelable(RESPONSE_BUY_INTENT) as PendingIntent; if (pendingIntent == null) { throw new InAppBillingPurchaseException(PurchaseError.GeneralError); } tcsPurchase = new TaskCompletionSource <PurchaseResponse>(); Context.StartIntentSenderForResult(pendingIntent.IntentSender, PURCHASE_REQUEST_CODE, new Intent(), 0, 0, 0); } var result = await tcsPurchase.Task; if (result == null) { return(null); } var data = result.PurchaseData; var sign = result.DataSignature; //for some reason the data didn't come back if (string.IsNullOrWhiteSpace(data)) { var purchases = await GetPurchasesAsync(itemType, verifyPurchase); return(purchases.FirstOrDefault(p => p.ProductId == productSku && payload.Equals(p.DeveloperPayload ?? string.Empty))); } var purchase = JsonConvert.DeserializeObject <Purchase>(data); if (verifyPurchase == null || await verifyPurchase.VerifyPurchase(data, sign, productSku, purchase.OrderId)) { if (purchase.ProductId == productSku && payload.Equals(purchase.DeveloperPayload ?? string.Empty)) { return(purchase); } } return(null); }
/// <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 (can not be null)</param> /// <param name="verifyPurchase">Interface to verify purchase</param> /// <returns></returns> public async override Task <InAppBillingPurchase> PurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null) { if (payload == null) { throw new ArgumentNullException(nameof(payload), "Payload can not be null"); } if (serviceConnection?.Service == null) { throw new InAppBillingPurchaseException(PurchaseError.ServiceUnavailable, "You are not connected to the Google Play App store."); } Purchase purchase = null; switch (itemType) { case ItemType.InAppPurchase: purchase = await PurchaseAsync(productId, ITEM_TYPE_INAPP, payload, verifyPurchase); break; case ItemType.Subscription: var activeSubscriptions = await GetPurchasesAsync(itemType, verifyPurchase); var oldSubscriptions = activeSubscriptions.Select(p => p.ProductId).ToList(); oldSubscriptions.Remove(productId); purchase = await PurchaseAsync(productId, ITEM_TYPE_SUBSCRIPTION, payload, verifyPurchase, new JavaList <string>(oldSubscriptions)); break; } if (purchase == null) { return(null); } var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return(new InAppBillingPurchase { TransactionDateUtc = epoch + TimeSpan.FromMilliseconds(purchase.PurchaseTime), Id = purchase.OrderId, AutoRenewing = purchase.AutoRenewing, PurchaseToken = purchase.PurchaseToken, State = itemType == ItemType.InAppPurchase ? purchase.State : purchase.SubscriptionState, ConsumptionState = purchase.ConsumedState, ProductId = purchase.ProductId, Payload = purchase.DeveloperPayload ?? string.Empty }); }
/// <summary> /// Get all current purhcase for a specifiy product type. /// </summary> /// <param name="itemType">Type of product</param> /// <param name="verifyPurchase">Interface to verify purchase</param> /// <returns>The current purchases</returns> public async override Task <IEnumerable <InAppBillingPurchase> > GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null) { if (serviceConnection?.Service == null) { throw new InAppBillingPurchaseException(PurchaseError.ServiceUnavailable, "You are not connected to the Google Play App store."); } List <Purchase> purchases = null; switch (itemType) { case ItemType.InAppPurchase: purchases = await GetPurchasesAsync(ITEM_TYPE_INAPP, verifyPurchase); break; case ItemType.Subscription: purchases = await GetPurchasesAsync(ITEM_TYPE_SUBSCRIPTION, verifyPurchase); break; } if (purchases == null) { return(null); } var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var results = purchases.Select(p => new InAppBillingPurchase { TransactionDateUtc = epoch + TimeSpan.FromMilliseconds(p.PurchaseTime), Id = p.OrderId, ProductId = p.ProductId, AutoRenewing = p.AutoRenewing, PurchaseToken = p.PurchaseToken, State = itemType == ItemType.InAppPurchase ? p.State : p.SubscriptionState, ConsumptionState = p.ConsumedState, Payload = p.DeveloperPayload ?? string.Empty }); return(results); }
/// <summary> /// (Android specific) Upgrade/Downagrade a previously purchased subscription /// </summary> /// <param name="oldProductId">Sku or ID of product that needs to be upgraded</param> /// <param name="newProductId">Sku or ID of product that will replace the old one</param> /// <param name="payload">Developer specific payload (can not be null)</param> /// <param name="verifyPurchase">Verify Purchase implementation</param> /// <returns>Purchase details</returns> public async override Task <InAppBillingPurchase> UpgradePurchasedSubscriptionAsync(string oldProductId, string newProductId, string payload, IInAppBillingVerifyPurchase verifyPurchase = null) { throw new NotImplementedException("iOS not supported. Apple store manages upgrades natively when subscriptions of the same group are purchased."); }
/// <summary> /// (Android specific) Upgrade/Downagrade a previously purchased subscription /// </summary> /// <param name="oldProductId">Sku or ID of product that needs to be upgraded</param> /// <param name="newProductId">Sku or ID of product that will replace the old one</param> /// <param name="payload">Developer specific payload (can not be null)</param> /// <param name="verifyPurchase">Verify Purchase implementation</param> /// <returns>Purchase details</returns> public abstract Task <InAppBillingPurchase> UpgradePurchasedSubscriptionAsync(string oldProductId, string newProductId, string payload, IInAppBillingVerifyPurchase verifyPurchase = null, bool prorate = true);
async Task<Purchase> PurchaseAsync(string productSku, string itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase) { if (tcsPurchase != null && !tcsPurchase.Task.IsCompleted) return null; Bundle buyIntentBundle = serviceConnection.Service.GetBuyIntent(3, Context.PackageName, productSku, itemType, payload); var response = GetResponseCodeFromBundle(buyIntentBundle); switch(response) { case 0: //OK to purchase break; case 1: //User Cancelled, should try again break; case 3: //Billing Unavailable throw new InAppBillingPurchaseException(PurchaseError.BillingUnavailable); case 4: //Item Unavailable throw new InAppBillingPurchaseException(PurchaseError.ItemUnavailable); case 5: //Developer Error throw new InAppBillingPurchaseException(PurchaseError.DeveloperError); case 6: //Generic Error throw new InAppBillingPurchaseException(PurchaseError.GeneralError); case 7: var purchases = await GetPurchasesAsync(itemType, verifyPurchase); var purchase = purchases.FirstOrDefault(p => p.ProductId == productSku && p.DeveloperPayload == payload); return purchase; //already purchased } tcsPurchase = new TaskCompletionSource<PurchaseResponse>(); var pendingIntent = buyIntentBundle.GetParcelable(RESPONSE_BUY_INTENT) as PendingIntent; if (pendingIntent != null) Context.StartIntentSenderForResult(pendingIntent.IntentSender, PURCHASE_REQUEST_CODE, new Intent(), 0, 0, 0); var result = await tcsPurchase.Task; if (result == null) return null; var data = result.PurchaseData; var sign = result.DataSignature; //for some reason the data didn't come back if (string.IsNullOrWhiteSpace(data)) { var purchases = await GetPurchasesAsync(itemType, verifyPurchase); var purchase = purchases.FirstOrDefault(p => p.ProductId == productSku && p.DeveloperPayload == payload); return purchase; } if (verifyPurchase == null || await verifyPurchase.VerifyPurchase(data, sign)) { var purchase = JsonConvert.DeserializeObject<Purchase>(data); if (purchase.ProductId == productSku && purchase.DeveloperPayload == payload) return purchase; } return null; }
/// <summary> /// Consume a purchase /// </summary> /// <param name="productId">Id/Sku of the product</param> /// <param name="payload">Developer specific payload of original purchase</param> /// <param name="itemType">Type of product being consumed.</param> /// <param name="verifyPurchase">Verify Purchase implementation</param> /// <returns>If consumed successful</returns> public async Task<InAppBillingPurchase> ConsumePurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase) { var purchases = await GetPurchasesAsync(itemType, verifyPurchase); var purchase = purchases.FirstOrDefault(p => p.ProductId == productId && p.Payload == payload); if(purchase == null) { Console.WriteLine("Unable to find a purchase with matching product id and payload"); return null; } var response = serviceConnection.Service.ConsumePurchase(3, Context.PackageName, purchase.PurchaseToken); var result = ParseConsumeResult(response); if (!result) return null; return purchase; }
/// <summary> /// Get all current purhcase for a specifiy product type. /// </summary> /// <param name="itemType">Type of product</param> /// <param name="verifyPurchase">Interface to verify purchase</param> /// <returns>The current purchases</returns> public async override Task <IEnumerable <InAppBillingPurchase> > GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null) { var purchases = await RestoreAsync(); var converted = purchases .Where(p => p != null) .Select(p2 => p2.ToIABPurchase()); //try to validate purchases var valid = await ValidateReceipt(verifyPurchase, string.Empty, string.Empty); return(valid ? converted : null); }
/// <summary> /// Consume a purchase /// </summary> /// <param name="productId">Id/Sku of the product</param> /// <param name="payload">Developer specific payload of original purchase</param> /// <param name="itemType">Type of product being consumed.</param> /// <param name="verifyPurchase">Verify Purchase implementation</param> /// <returns>If consumed successful</returns> /// <exception cref="InAppBillingPurchaseException">If an error occures during processing</exception> public override Task <InAppBillingPurchase> ConsumePurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null) => null;
/// <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 <InAppBillingPurchase> 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); return(new InAppBillingPurchase { TransactionDateUtc = reference.AddSeconds(p.TransactionDate.SecondsSinceReferenceDate), Id = p.TransactionIdentifier, ProductId = p.Payment?.ProductIdentifier ?? string.Empty, State = p.GetPurchaseState() }); }
/// <summary> /// (Android specific) Upgrade/Downagrade a previously purchased subscription /// </summary> /// <param name="oldProductId">Sku or ID of product that needs to be upgraded</param> /// <param name="newProductId">Sku or ID of product that will replace the old one</param> /// <param name="payload">Developer specific payload (can not be null)</param> /// <param name="verifyPurchase">Verify Purchase implementation</param> /// <returns>Purchase details</returns> public async override Task <InAppBillingPurchase> UpgradePurchasedSubscriptionAsync(string oldProductId, string newProductId, string payload, IInAppBillingVerifyPurchase verifyPurchase = null, bool prorate = true) { throw new NotImplementedException("UWP not supported. Windows store can't manage subscriptions upgrades."); }
/// <summary> /// Get all current purhcase for a specifiy product type. /// </summary> /// <param name="itemType">Type of product</param> /// <param name="verifyPurchase">Interface to verify purchase</param> /// <returns>The current purchases</returns> public async Task <IEnumerable <InAppBillingPurchase> > GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null) { var purchases = await RestoreAsync(); return(purchases.Where(p => p != null).Select(p => p.ToIABPurchase())); }
protected async override Task <IEnumerable <InAppBillingPurchase> > GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase, string verifyOnlyProductId) { // Get list of product receipts from store or simulator var xmlReceipt = await CurrentAppMock.GetAppReceiptAsync(InTestingMode); // Transform it to list of InAppBillingPurchase return(xmlReceipt.ToInAppBillingPurchase(ProductPurchaseStatus.AlreadyPurchased)); }
/// <summary> /// Get all current purhcase for a specifiy product type. /// </summary> /// <param name="itemType">Type of product</param> /// <param name="verifyPurchase">Verify purchase implementation</param> /// <returns>The current purchases</returns> public abstract Task <IEnumerable <InAppBillingPurchase> > GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null);
/// <summary> /// returns all purchases /// </summary> /// <param name="itemType">not used for Amazon</param> /// <param name="verifyPurchase">Not Used for Amazon</param> /// <param name="verifyOnlyProductId">Not Used for Amazon</param> /// <returns></returns> public async Task <List <PurchaseResult> > GetPurchasesAsync(ItemType itemType = ItemType.InAppPurchase, IInAppBillingVerifyPurchase verifyPurchase = null, string verifyOnlyProductId = null) { var purchaseHistoryResult = new List <PurchaseResult>(); var purchaseReceipts = await GetPurchaseReceipts(); if (purchaseReceipts?.Count > 0) { foreach (var purchase in purchaseReceipts) { var purchaseHistory = new PurchaseResult { Sku = purchase.Sku, PurchaseToken = purchase.ReceiptId }; if (purchase.PurchaseDate > 0) { purchaseHistory.PurchaseDate = DateTimeOffset.FromUnixTimeSeconds(purchase.PurchaseDate).DateTime; } purchaseHistory.DeveloperPayload = null; if (purchase.CancelDate > 0) { purchaseHistory.ExpirationDate = DateTimeOffset.FromUnixTimeSeconds(purchase.CancelDate).DateTime; purchaseHistory.PurchaseState = PurchaseState.Cancelled; } else { purchaseHistory.PurchaseState = PurchaseState.Purchased; } purchaseHistoryResult.Add(purchaseHistory); } } return(purchaseHistoryResult); }
/// <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">Verify Purchase implementation</param> /// <returns>Purchase details</returns> /// <exception cref="InAppBillingPurchaseException">If an error occures during processing</exception> public abstract Task <InAppBillingPurchase> PurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null);
public Task <bool> VerifyPreviousPurchaseAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase, string productId) { throw new NotImplementedException(); }
/// <summary> /// Get all current purhcase for a specifiy product type. /// </summary> /// <param name="itemType">Type of product</param> /// <param name="verifyPurchase">Interface to verify purchase</param> /// <returns>The current purchases</returns> public async Task<IEnumerable<InAppBillingPurchase>> GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null) { List<Purchase> purchases = null; switch (itemType) { case ItemType.InAppPurchase: purchases = await GetPurchasesAsync(ITEM_TYPE_INAPP, verifyPurchase); break; case ItemType.Subscription: purchases = await GetPurchasesAsync(ITEM_TYPE_SUBSCRIPTION, verifyPurchase); break; } if (purchases == null) return null; var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var results = purchases.Select(p => new InAppBillingPurchase { TransactionDateUtc = epoch + TimeSpan.FromMilliseconds(p.PurchaseTime), Id = p.OrderId, ProductId = p.ProductId, AutoRenewing = p.AutoRenewing, PurchaseToken = p.PurchaseToken, State = p.State, Payload = p.DeveloperPayload }); return results; }
/// <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">Verify purchase implementation</param> /// <returns></returns> /// <exception cref="InAppBillingPurchaseException">If an error occurs during processing</exception> public async override Task <InAppBillingPurchase> PurchaseAsync(string productId, ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null) { // Get purchase result from store or simulator var purchaseResult = await CurrentAppMock.RequestProductPurchaseAsync(InTestingMode, productId); if (purchaseResult == null) { return(null); } if (string.IsNullOrWhiteSpace(purchaseResult.ReceiptXml)) { return(null); } // Transform it to InAppBillingPurchase return(purchaseResult.ReceiptXml.ToInAppBillingPurchase(purchaseResult.Status).FirstOrDefault()); }
/// <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<InAppBillingPurchase> PurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null) { Purchase purchase = null; switch (itemType) { case ItemType.InAppPurchase: purchase = await PurchaseAsync(productId, ITEM_TYPE_INAPP, payload, verifyPurchase); break; case ItemType.Subscription: purchase = await PurchaseAsync(productId, ITEM_TYPE_SUBSCRIPTION, payload, verifyPurchase); break; } if (purchase == null) return null; var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return new InAppBillingPurchase { TransactionDateUtc = epoch + TimeSpan.FromMilliseconds(purchase.PurchaseTime), Id = purchase.OrderId, AutoRenewing = purchase.AutoRenewing, PurchaseToken = purchase.PurchaseToken, State = purchase.State, ProductId = purchase.ProductId, Payload = purchase.DeveloperPayload }; }