Hello I have Unity IAP setup and I can successfully buy a product. Using this method PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) I have info about that payment. How do I get Order Id Package name Product ID Purchase Token Price Amount Micros Price Currency Code Order Date They are in receipt that is JSON string with 4 Dictionaries in hierarchy inside. Is there some method in UnityEngine.Purchasing or some class that I can use to parse this PurchaseEventArgs or Receit?
All available information will be in the Product object in the purchase event argument. You will need to parse this information yourself.
This is how I manage to unwrap this confusing receipt of Google into useful data. Just send PurchaseEventArgs to this. Code (CSharp): public ReceiptData GetReceiptData(PurchaseEventArgs e) { ReceiptData data = new ReceiptData(); if (e != null) { //Main receipt root string receiptString = e.purchasedProduct.receipt; Debug.Log("receiptString " + receiptString); var receiptDict = (Dictionary<string, object>)MiniJson.JsonDecode(receiptString); Debug.Log("receiptDict COUNT" + receiptDict.Count); //Next level Paylod dict string payloadString = (string)receiptDict["Payload"]; Debug.Log("payloadString " + payloadString); var payloadDict = (Dictionary<string, object>)MiniJson.JsonDecode(payloadString); //Stuff from json object string jsonString = (string)payloadDict["json"]; Debug.Log("jsonString " + jsonString); var jsonDict = (Dictionary<string, object>)MiniJson.JsonDecode(jsonString); string orderIdString = (string)jsonDict["orderId"]; Debug.Log("orderIdString " + orderIdString); string packageNameString = (string)jsonDict["packageName"]; Debug.Log("packageNameString " + packageNameString); string productIdString = (string)jsonDict["productId"]; Debug.Log("productIdString " + productIdString); double orderDateDouble = Convert.ToDouble(jsonDict["purchaseTime"]); Debug.Log("orderDateDouble " + orderDateDouble); string purchaseTokenString = (string)jsonDict["purchaseToken"]; Debug.Log("purchaseTokenString " + purchaseTokenString); //Stuff from skuDetails object string skuDetailsString = (string)payloadDict["skuDetails"]; Debug.Log("skuDetailsString " + skuDetailsString); var skuDetailsDict = (Dictionary<string, object>)MiniJson.JsonDecode(skuDetailsString); long priceAmountMicrosLong = Convert.ToInt64(skuDetailsDict["price_amount_micros"]); Debug.Log("priceAmountMicrosLong " + priceAmountMicrosLong); string priceCurrencyCodeString = (string)skuDetailsDict["price_currency_code"]; Debug.Log("priceCurrencyCodeString " + priceCurrencyCodeString); //Creating UTC from Epox DateTime orderDateTemp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); orderDateTemp = orderDateTemp.AddMilliseconds(orderDateDouble); data.orderId = orderIdString; data.packageName = packageNameString; data.productId = productIdString; data.purchaseToken = purchaseTokenString; data.priceAmountMicros = priceAmountMicrosLong; data.priceCurrencyCode = priceCurrencyCodeString; data.orderDate = orderDateTemp; data.receipt = receiptString; Debug.Log("GetReceiptData succesfull"); } else { Debug.Log("PurchaseEventArgs is NULL"); } return data; } and this is the class for data Code (CSharp): public class ReceiptData { public string orderId; public string packageName; public string productId; public string purchaseToken; public long priceAmountMicros; public string priceCurrencyCode; public DateTime orderDate; public string receipt; } My question is: When you have made some purchase Pending using PurchaseProcessingResult.Pending, on next App launch (not on start) how do I find what product is in pending state so I can eventually mark it completed? Thanks ------- EDIT: Fixed casting on Objects. Must use Convert to be able cast not known types.
If it is in Pending, ProcessPurchase will fire immediately upon IAP initialization on app launch. And app launch is the same as app start, can you elaborate?
I call InitializePurchasing() when popup window pops up I guess it is done only the first time, because second time IsInitialized() will be true. I add products there and initialize Unity Purchasing if (IsInitialized()) { return; } var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); builder.AddProduct(availabileProducts[0], ProductType.Consumable); builder.AddProduct(availabileProducts[1], ProductType.Consumable); builder.AddProduct(availabileProducts[2], ProductType.Consumable); builder.AddProduct(availabileProducts[3], ProductType.Consumable); builder.AddProduct(availabileProducts[4], ProductType.Consumable); builder.AddProduct(availabileProducts[5], ProductType.Consumable); UnityPurchasing.Initialize(this, builder); Is this IAP Initialization moment that you are talking about? I had some products in pending and ProcessPurchase did not fire until I called BuyProductID(string productId). I just followed this tutorial https://unity3d.com/learn/tutorials/topics/ads-analytics/integrating-unity-iap-your-game The code is the same. I only added some switch case in OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) for actions on different fail reasons. Beside that, How is triggering ProcessPurchase(PurchaseEventArgs e) linked to product that is pending? If I have 6 consumable products and two of them are in pending, how does ProcessPurchase(PurchaseEventArgs e) help me see what product is pending? Do I need to pull out e.purchasedProduct.definition.id and if it is not called from manual buy then complete it
What popup window? You only want to initialize IAP once, at the beginning of your game and use a singleton pattern. Please refer to the IAP Sample project here https://forum.unity.com/threads/sample-iap-project.529555/
Thank you Jeff for all your answers. I don't want you to think that I am not grateful for your help. After all Google changes and restrictions, your answers (all the answers here to others and me) are only thing that I find useful in building Unity IAP system this far. I just don't get few things so I must ask them again. When I have TWO of the products in pending state, and I (or app start, whatever) initialize purchasing, ProcessPurchase will trigger automatically ONCE for first pending product? What about the second one? How will i put that second one in test_product so i can complete it?
If you have two products in Pending, you would get two ProcessPurchase events at initialization, one for each product.