Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

CrossPlatformValidator throws InvalidSignatureException

Discussion in 'Unity IAP' started by hippo_san, May 15, 2019.

  1. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    Hi, I saw there were a couple of threads about this topic but I didn't manage to find the right answer. My problem is when CrossPlatformValidator always throws an InvalidSignatureException when I'm buying an auto-renewable product from the store.

    Here is my code:
    Code (CSharp):
    1. PurchaseProcessingResult IStoreListener.ProcessPurchase (PurchaseEventArgs args) {
    2.     try {
    3.       var receipts = validator.Validate (args.purchasedProduct.receipt);
    4.     } catch (IAPSecurityException e) {
    5.         Debug.LogException(e);
    6.     }
    7.        return PurchaseProcessingResult.Complete;
    8.     }
    The error only happens on Android. Here is the log from logcat:
    05-15 10:20:21.562 17378 17446 E Unity : InvalidSignatureException: Exception of type 'UnityEngine.Purchasing.Security.InvalidSignatureException' was thrown.
    05-15 10:20:21.562 17378 17446 E Unity : at UnityEngine.Purchasing.Security.GooglePlayValidator.Validate (System.String receipt, System.String signature) [0x00000] in <filename unknown>:0
    05-15 10:20:21.562 17378 17446 E Unity : at UnityEngine.Purchasing.Security.CrossPlatformValidator.Validate (System.String unityIAPReceipt) [0x00000] in <filename unknown>:0
    05-15 10:20:21.562 17378 17446 E Unity : UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object)
    05-15 10:20:21.562 17378 17446 E Unity : UnityEngine.DebugLogHandler:LogException(Exception, Object)
    05-15 10:20:21.562 17378 17446 E Unity : UnityEngine.Logger:LogException(Exception, Object)
    05-15 10:20:21.562 17378 17446 E Unity : UnityEngine.Debug:LogException(Exception)

    I'm doing a sandbox test and the receipt looks correct. Here is the receipt json from logcat:
    {"Store":"GooglePlay","TransactionID":"GPA.3317-...","Payload":"{\"json\":\"{\\\"orderId\\\":...

    Environment:
    Unity 2017.4.20f2
    Unity IAP 1.22.0

    What could cause InvalidSignatureException? I also filed a report here https://analytics.cloud.unity3d.com/support/.
     
    Last edited: May 15, 2019
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,138
    Does it occur on all your purchases? An invalid signature would cause the exception.
     
  3. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    Yes, it occurs on all purchases on Android. What caused an invalid signature?
     
  4. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,138
    Can you test with Unity 2018.3 or above?
     
  5. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    Sadly testing with 2018.3 or above would involve too many changes, it's not an option. However I tried to run another project with the same setup, and everything is fine. So I suppose it's not related to Unity version.
     
  6. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,138
    Can you elaborate, "everything is fine", so you are not seeing the exception in another project? What is different?
     
  7. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    Yes, I didn't see any exceptions in another project. These two projects share the same Google Play RSA public key and code base. And this is exactly what I'm wondering about - why one works but not the other.
     
  8. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,138
    I tested with 2018,3 without issue. This the code I'm using. Did you remember to generate your Tangle files?

    Code (CSharp):
    1. #if UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX
    2.  
    3.         var validator = new CrossPlatformValidator(GooglePlayTangle.Data(),
    4.            AppleTangle.Data(), Application.identifier);
    5.  
    6.  
    7.         try
    8.         {
    9.             // On Google Play, result has a single product ID.
    10.             // On Apple stores, receipts contain multiple products.
    11.             var result = validator.Validate(args.purchasedProduct.receipt);
    12.             // For informational purposes, we list the receipt(s)
    13.             Debug.Log("Receipt is valid. Contents:");
    14.             foreach (IPurchaseReceipt productReceipt in result)
    15.             {
    16.                 MyDebug(productReceipt.productID);
    17.                 MyDebug(productReceipt.purchaseDate.ToString());
    18.                 MyDebug(productReceipt.transactionID);
    19.             }
    20.         }
    21.         catch (Exception e)
    22.         {
    23.             MyDebug("Invalid receipt, not unlocking content" + e.Message.ToString());
    24.             validPurchase = false;
    25.         }
    26.         #endif
     
  9. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    This is my code of making the validator which exactly like yours:
    Code (CSharp):
    1. validator = new CrossPlatformValidator (GooglePlayTangle.Data (), AppleTangle.Data (), Application.identifier);
    Is this code for generating Tangle files?
     
  10. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,138
  11. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    Unfortunately, this does not help either... I copied RSA public key from Services and APIs in Google Play Console, and pasted it to Receipt Validation Obfuscator, then pressed "Obfuscate Google Play License Key".

    I notice that there are a bunch of other errors print out after purchasing succeeded from the store (the green check icon shows), for example:
    05-16 10:50:01.370 22324 22460 D Unity : ? getMethodID("java.lang.Class", "forName", "(Ljava/lang/String;)Ljava/lang/Object;", static)
    05-16 10:50:01.370 22324 22460 D Unity : ! Class Class.forName(String);
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_INTERNAL_CALL_ExceptionOccurred()
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_DeleteLocalRef()
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_DeleteLocalRef()
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_INTERNAL_CALL_FromReflectedMethod()
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_INTERNAL_CALL_ExceptionOccurred()
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_DeleteLocalRef()
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_INTERNAL_CALL_NewStringUTF()
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_INTERNAL_CALL_ExceptionOccurred()
    05-16 10:50:01.370 22324 22460 D Unity : > AndroidJNI_CUSTOM_INTERNAL_CALL_CallStaticObjectMethod(0x2a4a, 0x6f8d6bac
    05-16 10:50:01.370 22324 22460 D Unity : > , 00000015
    05-16 10:50:01.370 22324 22460 D Unity : > )

    Don't know if it has something to do with this.
     
  12. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    Now it works! I opened Window - Services - In-app Purchasing, then I found a newer version was detected. After updating to the new version, it works. I wonder why it is not the case for the other project that I mentioned before. They are in the same Unity project, just different scenes.
     
  13. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,138
    Sorry I'm not clear, you said both "why it is not the case for the other project" followed by "They are in the same Unity project"
     
  14. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    Sorry what I meant is I have two scenes (although they use different App IDs so I treat it as two "projects"). It has no problem when building and running one of the two, but the other requires to update Unity IAP plugin to work. However after updating the plugin from Window - Services - In-app Purchasing, the version of the plugin did not change, but the purchasing works somehow.
     
  15. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,138
    Sorry I'm still not clear. What AppIDs are you referring to? If they are separate projects, you need to load each individually in Unity by opening a separate project. At any rate, you'll need to figure out what is different between the two projects. Look for any differences under Package Manager too. Are both projects created with the same version of Unity? Do they have different assets installed, etc.
     
  16. hippo_san

    hippo_san

    Joined:
    Oct 29, 2014
    Posts:
    18
    They are not different projects, just two different scenes. But the information, e.g. Bundle ID in Player Settings are configured differently for each of them. You can think I mixed two apps into one Unity project, and they share the same code base. I'm using Unity 2017.4.20, where can I find Package Manager?
     
  17. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,138
    You can't mix two apps in one project. Please show a screenshot. And for questions regarding Package Manager, please open a separate topic. Package Manager was introduced in Unity 2018.