Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Android UnityPurchasing Initialize FormatException

Discussion in 'Unity IAP' started by jrucktenwald, Apr 16, 2021.

  1. jrucktenwald

    jrucktenwald

    Joined:
    Mar 15, 2018
    Posts:
    12
    Unity 2020.3.0f1
    Unity IAP 2.2.2

    Hello!

    We have recently done some upgrading:
    Unity 2018.4.24.f1 --> 2020.3.0f1
    In App Purchasing 2.1.0 --> 2.2.2

    The problem that we are seeing is that when Android mobile devices are set to either the French or Swedish language we are seeing an exception that causing the initialization of UnityPurchasing to never return. We are calling UnityPurchasing.Initialize, but neither OnInitialized nor OnInitializedFailed is ever called. This is the exception that we are getting in the logs:

    Code (Boo):
    1. 04-16 01:12:43.675 23551 23670 E Unity   : FormatException: Input string was not in a correct format.
    2. 04-16 01:12:43.675 23551 23670 E Unity   :   at System.Number.StringToNumber (System.String str, System.Globalization.NumberStyles options, System.Number+NumberBuffer& number, System.Globalization.NumberFormatInfo info, System.Boolean parseDecimal) [0x00000] in <00000000000000000000000000000000>:0
    3. 04-16 01:12:43.675 23551 23670 E Unity   :   at System.Number.ParseDecimal (System.String value, System.Globalization.NumberStyles options, System.Globalization.NumberFormatInfo numfmt) [0x00000] in <00000000000000000000000000000000>:0
    4. 04-16 01:12:43.675 23551 23670 E Unity   :   at UnityEngine.Purchasing.JSONSerializer.DeserializeMetadata (System.Collections.Generic.Dictionary`2[TKey,TValue] data) [0x00000] in <00000000000000000000000000000000>:0
    5. 04-16 01:12:43.675 23551 23670 E Unity   :   at UnityEngine.Purchasing.JSONSerializer.DeserializeProductDescriptions (System.String json) [0x00000] in <00000000000000000000000000000000>:0
    6. 04-16 01:12:43.675 23551 23670 E Unity   :   at UnityEngine.Purchasing.NativeJSONStore.OnProductsRetrieved (System.String json) [0x00000] in <00000000000000000000000000000000>:0
    7. 04-16 01:12:43.675 23551 23670 E Unity   :   at System.Action.Invoke () [0x00000] in <00000000000000

    Here is the creation of our ConfigurationBuilder:

    ConfigurationBuilder configurationBuilder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());


    It doesn't seem to matter if we add all our products or just one, it never triggers the callback. If we don't add any products or add an invalid IAP code to the builder then it successfully calls OnInitializationFailed with a
    NoProductsAvailable failure reason. We have also tried reverting Unity IAP to version 2.1.0 that we were on previously, but we are getting the same result.

    I doubt this matters, but small note our iap codes have decimal points in them (e.g. iap.product.2)

    I'm out of ideas for what else to try so any help is greatly appreciated. Thanks in advance.
     
  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    @jrucktenwald Can you try a test product without the dots like "gold50"? I doubt that is the issue, but something to rule out. We will check the locales you mention also.
     
  3. jrucktenwald

    jrucktenwald

    Joined:
    Mar 15, 2018
    Posts:
    12
    @JeffDUnity3D Thanks for the response. This morning I added a dummy test product to our Google Play console "testproduct8" and only added that product to the ConfigurationBuilder, but received the same result of no response from the UnityPurchasing.Initialize() with the same error log as found in the original post.
     
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Got it, thanks for checking. We will follow up
     
  5. bmabrams8

    bmabrams8

    Joined:
    Apr 19, 2021
    Posts:
    1
    HI @JeffDUnity3D just following up here on behalf of jrucktenwald on the above. We're in a bit of a bind here so any info is greatly appreciated. Thank you for all the support!
     
  6. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Once we are able to test, we will schedule it into a future release. I might expect 3-4 weeks minimum, to properly set expectations. Are you able to test with the latest version of IAP 3.0.2?
     
  7. jrucktenwald

    jrucktenwald

    Joined:
    Mar 15, 2018
    Posts:
    12
    Hey @JeffDUnity3D so we have tried to update to 3.0.2, but without changing any other client or server code our Apple sandbox account test purchases are no longer getting recognized as sandbox purchases. Apple's verification endpoint is no longer returning a 21007 which it has always done. Instead we're getting back a 21002, which means that it thinks the data is malformed.

    I'm currently trying to track down how the `PurchaseEventArgs` from the IStoreListener ProcessPurchase are different in 3.0.2 than they were in 2.1.0. I haven't seen any documentation about needing to make changes here, but if you know of any that would be greatly appreciated.
     
  8. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    It's working here for me. Can you elaborate "no longer getting recognized", you mean you are charged actual $? What if you create another Sandbox account?
     
  9. jrucktenwald

    jrucktenwald

    Joined:
    Mar 15, 2018
    Posts:
    12
    Code (CSharp):
    1.  
    2. public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    3. {
    4.     UnityPurchaseReceipt purchaseReceipt = LitJson.JsonMapper.ToObject<UnityPurchaseReceipt>(args.purchasedProduct.receipt);
    5.     var data = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(purchaseReceipt.Payload));
    6.     // send data to our server for server-side validation
    7. }
    8.  
    This is basically how we're getting the payload and passing it along to our server. Then our server takes the data field and sends it along to https://buy.itunes.apple.com/verifyReceipt

    Before the upgrade this endpoint would return a response with a status of 21007 indicating that it was a purchase from a sandbox/test environment, which would then prompt us to call the https://sandbox.itunes.apple.com/verifyReceipt version of the endpoint. Now status 21007 is no longer returned, it's returning a 21002 status from the first endpoint which according to apple indicates "The data in the receipt-data property was malformed or the service experienced a temporary issue".

    So I was trying to track down what the difference is between the purchaseReceipt.Payload between the different versions.

    EDIT: Just wanted to add that this is happening for all our sandbox accounts.
     
    Last edited: Apr 21, 2021
    nicholasr likes this.
  10. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
  11. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
  12. jrucktenwald

    jrucktenwald

    Joined:
    Mar 15, 2018
    Posts:
    12
    @JeffDUnity3D

    So here are some results that I got from testing today.

    Code (CSharp):
    1. public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    2. {
    3.     Debug.Log($"args.purchasedProduct.receipt={args.purchasedProduct.receipt}");
    4. }
    On our iOS builds here are the print statements that we are getting with the different IAP versions. I have added `....` where I trimmed out the long tokens and I added the 'xxxx' in the TransactionIDs. I'm not sure where it's coming from at this point, but it looks like the Payload strings are different between the 2 versions. Maybe it's an initialization setting that we need? Or the reason that we were getting the JSON string back was because we had something that was hanging onto an old version that got wiped out when we upgraded? Either way, any information that you might have for us is much appreciated.


    Unity IAP 2.2.2
    --------------------
    Code (JavaScript):
    1. args.purchasedProduct.receipt={
    2.     "Store":"AppleAppStore",
    3.     "TransactionID":"1000000xxxxxxxx9",
    4.  
    5.     "Payload": "{
    6.    \"signature\" = \"A2/reuvV0 ..... 0dNVCI7Cn0=\";
    7.    \"environment\" = \"Sandbox\";
    8.    \"pod\" = \"100\";
    9.    \"signing-status\" = \"0\";
    10.    }"
    11. }

    Unity IAP 3.0.2
    --------------------
    Code (JavaScript):
    1. args.purchasedProduct.receipt={
    2.     "Store":"AppleAppStore",
    3.     "TransactionID":"1000000xxxxxxxx4",
    4.  
    5.     "Payload": "MIIWhgYJK ..... HRt80yA=="
    6. }
    7.  
     
  13. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, we are still checking
     
    jrucktenwald likes this.
  14. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Your 2.2.2 receipt format looks like iOS6 format. The 2.2.2 listing suggests it contains JSON-text, NOT base64 encoded JSON. Have you modified your local copy of UnityPurchasing.m. As mentioned, we already base64 encode the Payload unconditionally. You are calling LitJson.JsonMapper (not familiar with that component) followed by Convert.ToBase64String. We are not planning any changes at this time.
     
  15. jrucktenwald

    jrucktenwald

    Joined:
    Mar 15, 2018
    Posts:
    12
    To the best of my knowledge UnityPurchasing.m wasn't modified but there were a number of developers that are no longer with us that may have had a hand in it. I will look deeper into that possibility.

    Something like that is what I was afraid of when I said "maybe the reason that we were getting the JSON string back was because we had something that was hanging onto an old version that got wiped out when we upgraded" in my previous post. I appreciate you following up and I will report back when I have any other information. Thanks.
     
  16. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    By old version I assumed you meant an older version of IAP, but we checked that.
     
  17. jrucktenwald

    jrucktenwald

    Joined:
    Mar 15, 2018
    Posts:
    12
    Yeah sorry, I wasn't completely clear. I was referring to something that was forcing us to be getting back and old version of the receipt data from the PurchaseEventArgs. At the time I didn't realize that was an iOS6 version of the receipt data, but that sheds much more light onto the situation.
     
  18. jrucktenwald

    jrucktenwald

    Joined:
    Mar 15, 2018
    Posts:
    12
    @JeffDUnity3D

    Well, once you pointed that out it didn't take too long to locate the issue. I have verified that one of our developers did in fact modify the UnityPurchasing.m file. Your help and patience has been greatly appreciated. We will now be diligently working towards getting this resolved and updated to be using the proper receipt formatting. Thank you again.
     
    nicholasr likes this.