コード例 #1
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">Interface to verify purchase</param>
        /// <returns></returns>
        public async override Task <InAppBillingPurchase> PurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null)
        {
            Console.WriteLine($"PurchaseAsync1() - productId: { productId }");

            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)
            {
                Console.WriteLine($"PurchaseAsync1() - verifyPurchase is null - return");

                return(purchase);
            }

            var validated = await ValidateReceipt(verifyPurchase, purchase.ProductId, purchase.Id);

            Console.WriteLine($"PurchaseAsync1() - validated: { validated }");

            return(validated ? purchase : null);
        }
コード例 #2
0
        //inapp:{Context.PackageName}:{productSku}

        /// <summary>
        /// Consume a purchase with a purchase token.
        /// </summary>
        /// <param name="productId">Id or Sku of product</param>
        /// <param name="purchaseToken">Original Purchase Token</param>
        /// <returns>If consumed successful</returns>
        public override Task <InAppBillingPurchase> ConsumePurchaseAsync(string productId, string purchaseToken)
        {
            if (serviceConnection?.Service == null)
            {
                throw new InAppBillingPurchaseException(PurchaseError.ServiceUnavailable, "You are not connected to the Google Play App store.");
            }

            var response = serviceConnection.Service.ConsumePurchase(3, Context.PackageName, purchaseToken);
            var result   = ParseConsumeResult(response);

            if (!result)
            {
                return(null);
            }

            var purchase = new InAppBillingPurchase
            {
                Id                 = string.Empty,
                PurchaseToken      = purchaseToken,
                State              = PurchaseState.Purchased,
                ConsumptionState   = ConsumptionState.Consumed,
                AutoRenewing       = false,
                Payload            = string.Empty,
                ProductId          = productId,
                TransactionDateUtc = DateTime.UtcNow
            };

            return(Task.FromResult(purchase));
        }
コード例 #3
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="verifyPurchase">Interface to verify purchase</param>
        /// <param name="obfuscatedAccountId">Specifies an optional obfuscated string that is uniquely associated with the user's account in your app.</param>
        /// <param name="obfuscatedProfileId">Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.</param>
        /// <returns></returns>
        public async override Task <InAppBillingPurchase> PurchaseAsync(string productId, ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null, string obfuscatedAccountId = null, string obfuscatedProfileId = 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(),
#if __IOS__ || __TVOS__
                PurchaseToken = p.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None) ?? string.Empty
#endif
            };

            if (verifyPurchase == null)
            {
                return(purchase);
            }

            var validated = await ValidateReceipt(verifyPurchase, purchase.ProductId, purchase.Id);

            return(validated ? purchase : null);
        }
コード例 #4
0
        public static InAppBillingPurchase ToIABPurchase(this Purchase purchase)
        {
            var finalPurchase = new InAppBillingPurchase
            {
                AutoRenewing     = purchase.IsAutoRenewing,
                ConsumptionState = ConsumptionState.NoYetConsumed,
                Id                  = purchase.OrderId,
                IsAcknowledged      = purchase.IsAcknowledged,
                Payload             = purchase.DeveloperPayload,
                ProductId           = purchase.Sku,
                PurchaseToken       = purchase.PurchaseToken,
                TransactionDateUtc  = DateTimeOffset.FromUnixTimeMilliseconds(purchase.PurchaseTime).DateTime,
                ObfuscatedAccountId = purchase.AccountIdentifiers?.ObfuscatedAccountId,
                ObfuscatedProfileId = purchase.AccountIdentifiers?.ObfuscatedProfileId
            };

            finalPurchase.State = purchase.PurchaseState switch
            {
                Android.BillingClient.Api.PurchaseState.Pending => PurchaseState.PaymentPending,
                Android.BillingClient.Api.PurchaseState.Purchased => PurchaseState.Purchased,
                _ => PurchaseState.Unknown
            };
            return(finalPurchase);
        }
    }
コード例 #5
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">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);

            var purchase = new InAppBillingPurchase
            {
                TransactionDateUtc = reference.AddSeconds(p.TransactionDate.SecondsSinceReferenceDate),
                Id        = p.TransactionIdentifier,
                ProductId = p.Payment?.ProductIdentifier ?? string.Empty,
                State     = p.GetPurchaseState()
            };

            if (verifyPurchase == null)
            {
                return(purchase);
            }

            // 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);
            string receipt    = receiptUrl.GetBase64EncodedString(NSDataBase64EncodingOptions.None);

            var validated = await verifyPurchase.VerifyPurchase(receipt, string.Empty);


            return(validated ? purchase : null);
        }
コード例 #6
0
        /// <summary>
        /// Read purchase data out of the UWP Receipt XML
        /// </summary>
        /// <param name="xml">Receipt XML</param>
        /// <param name="status">Status of the purchase</param>
        /// <returns>A list of purchases, the user has done</returns>
        public static IEnumerable <InAppBillingPurchase> ToInAppBillingPurchase(this string xml, ProductPurchaseStatus status)
        {
            var purchases = new List <InAppBillingPurchase>();

            var xmlDoc = new XmlDocument();

            try
            {
                xmlDoc.LoadXml(xml);
            }
            catch
            {
                //Invalid XML, we haven't finished this transaction yet.
            }

            // Iterate through all ProductReceipt elements
            var xmlProductReceipts = xmlDoc.GetElementsByTagName("ProductReceipt");

            for (var i = 0; i < xmlProductReceipts.Count; i++)
            {
                var xmlProductReceipt = xmlProductReceipts[i];

                // Create new InAppBillingPurchase with values from the xml element
                var purchase = new InAppBillingPurchase()
                {
                    Id = xmlProductReceipt.Attributes["Id"].Value,
                    TransactionDateUtc = Convert.ToDateTime(xmlProductReceipt.Attributes["PurchaseDate"].Value),
                    ProductId          = xmlProductReceipt.Attributes["ProductId"].Value,
                    AutoRenewing       = false // Not supported by UWP yet
                };
                purchase.PurchaseToken = purchase.Id;
                // Map native UWP status to PurchaseState
                switch (status)
                {
                case ProductPurchaseStatus.AlreadyPurchased:
                case ProductPurchaseStatus.Succeeded:
                    purchase.State = PurchaseState.Purchased;
                    break;

                case ProductPurchaseStatus.NotFulfilled:
                    purchase.State = PurchaseState.Deferred;
                    break;

                case ProductPurchaseStatus.NotPurchased:
                    purchase.State = PurchaseState.Canceled;
                    break;

                default:
                    purchase.State = PurchaseState.Unknown;
                    break;
                }

                // Add to list of purchases
                purchases.Add(purchase);
            }

            return(purchases);
        }
コード例 #7
0
        public async override Task <InAppBillingPurchase> PurchaseAsync(string productId, ItemType itemType, string payload, IInAppBillingVerifyPurchase verifyPurchase = null)
        {
            string mspid = await GetMSProductIDForPID(productId);

            if (mspid == null)
            {
                throw new InAppBillingPurchaseException(PurchaseError.InvalidProduct);
            }


            StorePurchaseResult result = await storeContext.RequestPurchaseAsync(mspid);

            if (result.ExtendedError != null)
            {
                Debug.WriteLine("Extended Error:" + result.ExtendedError.ToString() + " Result: " + result.Status.ToString());
                throw new InAppBillingPurchaseException(PurchaseError.GeneralError, result.ExtendedError);
            }
            else
            {
                switch (result.Status)
                {
                case StorePurchaseStatus.AlreadyPurchased:
                    throw new InAppBillingPurchaseException(PurchaseError.AlreadyOwned);

                case StorePurchaseStatus.Succeeded:
                    var purchase = new InAppBillingPurchase()
                    {
                        Id            = productId,
                        ProductId     = productId,
                        AutoRenewing  = false,                                // Not supported by UWP yet
                        State         = PurchaseState.Purchased,
                        PurchaseToken = productId
                    };
                    return(purchase);

                case StorePurchaseStatus.NotPurchased:
                    throw new InAppBillingPurchaseException(PurchaseError.UserCancelled);

                case StorePurchaseStatus.NetworkError:
                    throw new InAppBillingPurchaseException(PurchaseError.ServiceUnavailable);

                case StorePurchaseStatus.ServerError:
                    throw new InAppBillingPurchaseException(PurchaseError.GeneralError);

                default:
                    Debug.WriteLine("Product was not purchased due to an unknown error.");
                    throw new InAppBillingPurchaseException(PurchaseError.GeneralError);
                }
            }
            return(null);
        }
コード例 #8
0
        //inapp:{Context.PackageName}:{productSku}

        /// <summary>
        /// Consume a purchase with a purchase token.
        /// </summary>
        /// <param name="productId">Id or Sku of product</param>
        /// <param name="purchaseToken">Original Purchase Token</param>
        /// <returns>If consumed successful</returns>
        public Task<InAppBillingPurchase> ConsumePurchaseAsync(string productId, string purchaseToken)
        {
            var response = serviceConnection.Service.ConsumePurchase(3, Context.PackageName, purchaseToken);
            var result = ParseConsumeResult(response);
            if (!result)
                return null;

            var purchase = new InAppBillingPurchase
            {
                Id = string.Empty,
                PurchaseToken = purchaseToken,
                State = PurchaseState.Purchased,
                AutoRenewing = false,
                Payload = string.Empty,
                ProductId = productId,
                TransactionDateUtc = DateTime.UtcNow
            };

            return Task.FromResult(purchase);
        }
コード例 #9
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">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()
            };

            if (verifyPurchase == null)
            {
                return(purchase);
            }

            var validated = await ValidateReceipt(verifyPurchase, purchase.ProductId, purchase.Id);

            return(validated ? purchase : null);
        }
コード例 #10
0
        public static InAppBillingPurchase ToIABPurchase(this SKPaymentTransaction transaction)
        {
            var p = transaction.OriginalTransaction;

            if (p == null)
            {
                p = transaction;
            }

            if (p == null)
            {
                return(null);
            }

            var newP = new InAppBillingPurchase
            {
                TransactionDateUtc = NSDateToDateTimeUtc(p.TransactionDate),
                Id        = p.TransactionIdentifier,
                ProductId = p.Payment?.ProductIdentifier ?? string.Empty,
                State     = p.GetPurchaseState()
            };

            return(newP);
        }
コード例 #11
0
 public override Task <bool> FinishTransaction(InAppBillingPurchase purchase) =>
 FinishTransaction(purchase?.Id);
コード例 #12
0
 public virtual Task <bool> FinishTransaction(InAppBillingPurchase purchase) => Task.FromResult(true);