/// <summary> /// Requests that the specified Purchasable be purchased on behalf of the current user. /// The IAP client service is responsible for identifying the user and requesting credentials as appropriate, /// as well as providing all of the UI for the purchase flow. When purchases are successful, a Product object /// is returned that describes the product that was purchased. /// </summary> /// <param name="product">The Purchasable object that describes the item to be purchased.</param> /// <returns>Returns true if the purchase was successful.</returns> public async Task <bool> RequestPurchaseAsync(Product product) { if (ReferenceEquals(product, null)) { throw new ArgumentNullException("product"); } var tcs = new TaskCompletionSource <bool>(); // Create the Purchasable object from the supplied product var sr = SecureRandom.GetInstance("SHA1PRNG"); // This is an ID that allows you to associate a successful purchase with // it's original request. The server does nothing with this string except // pass it back to you, so it only needs to be unique within this instance // of your app to allow you to pair responses with requests. var uniqueId = sr.NextLong().ToString("X"); JSONObject purchaseRequest = new JSONObject(); purchaseRequest.Put("uuid", uniqueId); purchaseRequest.Put("identifier", product.Identifier); var purchaseRequestJson = purchaseRequest.ToString(); byte[] keyBytes = new byte[16]; sr.NextBytes(keyBytes); var key = new SecretKeySpec(keyBytes, "AES"); byte[] ivBytes = new byte[16]; sr.NextBytes(ivBytes); var iv = new IvParameterSpec(ivBytes); Cipher cipher = Cipher.GetInstance("AES/CBC/PKCS5Padding", "BC"); cipher.Init(CipherMode.EncryptMode, key, iv); var payload = cipher.DoFinal(Encoding.UTF8.GetBytes(purchaseRequestJson)); cipher = Cipher.GetInstance("RSA/ECB/PKCS1Padding", "BC"); cipher.Init(CipherMode.EncryptMode, _publicKey); var encryptedKey = cipher.DoFinal(keyBytes); var purchasable = new Purchasable( product.Identifier, Convert.ToBase64String(encryptedKey, Base64FormattingOptions.None), Convert.ToBase64String(ivBytes, Base64FormattingOptions.None), Convert.ToBase64String(payload, Base64FormattingOptions.None)); var listener = new PurchaseListener(tcs, _publicKey, product, uniqueId); RequestPurchase(purchasable, listener); // No timeout for purchase as it shows a user dialog return(await tcs.Task); }
/// <summary> /// Requests that the specified Purchasable be purchased on behalf of the current user. /// The IAP client service is responsible for identifying the user and requesting credentials as appropriate, /// as well as providing all of the UI for the purchase flow. When purchases are successful, a Product object /// is returned that describes the product that was purchased. /// </summary> /// <param name="product">The Purchasable object that describes the item to be purchased.</param> /// <returns>Returns true if the purchase was successful.</returns> public async Task<bool> RequestPurchaseAsync(Product product) { if (ReferenceEquals(product, null)) throw new ArgumentNullException("product"); var tcs = new TaskCompletionSource<bool>(); // Create the Purchasable object from the supplied product var sr = SecureRandom.GetInstance("SHA1PRNG"); // This is an ID that allows you to associate a successful purchase with // it's original request. The server does nothing with this string except // pass it back to you, so it only needs to be unique within this instance // of your app to allow you to pair responses with requests. var uniqueId = sr.NextLong().ToString("X"); JSONObject purchaseRequest = new JSONObject(); purchaseRequest.Put("uuid", uniqueId); purchaseRequest.Put("identifier", product.Identifier); var purchaseRequestJson = purchaseRequest.ToString(); byte[] keyBytes = new byte[16]; sr.NextBytes(keyBytes); var key = new SecretKeySpec(keyBytes, "AES"); byte[] ivBytes = new byte[16]; sr.NextBytes(ivBytes); var iv = new IvParameterSpec(ivBytes); Cipher cipher = Cipher.GetInstance("AES/CBC/PKCS5Padding", "BC"); cipher.Init(CipherMode.EncryptMode, key, iv); var payload = cipher.DoFinal(Encoding.UTF8.GetBytes(purchaseRequestJson)); cipher = Cipher.GetInstance("RSA/ECB/PKCS1Padding", "BC"); cipher.Init(CipherMode.EncryptMode, _publicKey); var encryptedKey = cipher.DoFinal(keyBytes); var purchasable = new Purchasable( product.Identifier, Convert.ToBase64String(encryptedKey, Base64FormattingOptions.None), Convert.ToBase64String(ivBytes, Base64FormattingOptions.None), Convert.ToBase64String(payload, Base64FormattingOptions.None)); var listener = new PurchaseListener(tcs, _publicKey, product, uniqueId); RequestPurchase(purchasable, listener); // No timeout for purchase as it shows a user dialog return await tcs.Task; }