Summary:
After upgrading Unity IAP from version 4 to 5, some Android builds encounter a java.lang.ClassNotFoundException for com.android.billingclient.api.PurchasesUpdatedListener at app startup. This occurs because ProGuard/R8 removes or obfuscates Google Play Billing Client classes when the billing library’s consumer ProGuard rules are not merged correctly. Adding explicit keep rules for com.android.billingclient.api classes in the project’s ProGuard configuration resolves the issue and restores expected in-app purchase behaviour.
Symptoms:
- After updating to Unity IAP v5.3.1, the Android app throws java.lang.ClassNotFoundException: com.android.billingclient.api.PurchasesUpdatedListener on startup.
- The issue does not occur with Unity IAP v4.15.1 and appears only after the upgrade.
- The problem is resolved temporarily by manually adding ProGuard rules, but there is uncertainty about whether this is the correct or recommended fix.
Cause:
The issue is caused by ProGuard/R8 stripping or obfuscating Google Play Billing Client classes when building with Unity IAP v5.3.1. In this version, Unity IAP uses Gradle dependency injection for com.android.billingclient:billing, which relies on the billing library’s consumer ProGuard rules being merged into the final build. In some Unity build configurations, these consumer rules are not merged correctly, so the com.android.billingclient.api classes are removed, leading to ClassNotFoundException at runtime.
Resolution:
Add explicit keep rules for the Google Play Billing Client classes to the project’s ProGuard configuration. For example, include the following lines in the ProGuard file used by the Unity Android build:
-keep class com.android.billingclient.api.** { *; }
-keep interface com.android.billingclient.api.* { *; }
These rules prevent ProGuard/R8 from stripping or obfuscating the billing client classes, ensuring that com.android.billingclient.api.PurchasesUpdatedListener and related types remain available at runtime. This workaround aligns with recommended practice while documentation is being updated to cover this scenario.