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);
        }
Exemple #2
0
        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));
        }
Exemple #3
0
 /// <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));
 }
Exemple #4
0
 public override Task <InAppBillingPurchase> UpgradePurchasedSubscriptionAsync(string newProductId, string oldProductId, string purchaseTokenOfOriginalSubscription, int prorationMode = 1, IInAppBillingVerifyPurchase verifyPurchase = null)
 {
     throw new NotImplementedException("UWP not supported.");
 }
Exemple #5
0
 public Task <PurchaseResult> ConsumePurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null)
 {
     throw new NotImplementedException();
 }
Exemple #6
0
        /// <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
                });
            }
        }
Exemple #7
0
        /// <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);
        }
Exemple #14
0
 /// <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.");
 }
Exemple #15
0
 /// <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;
        }
Exemple #18
0
        /// <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()
            });
        }
Exemple #21
0
 /// <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()));
        }
Exemple #23
0
        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));
        }
Exemple #24
0
 /// <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);
Exemple #25
0
        /// <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);
        }
Exemple #26
0
 /// <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);
Exemple #27
0
 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;

        }
Exemple #29
0
        /// <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
            };
        }