I am using Unity IAP to ship my games on MAC with subscription-based monetization model. And everything worked fine until recently. On my latest build, I’ve launched testflight to test subscriptions and that everything works correctly (I always do that before publishing to prod) and used “Test subscription”. After that it did apply, but after Test Sub auto-cancel (like all test subs do after few minutes), my code still sees this subscription as active.
The most confusing thing is that it works as intended if I create new subscription in store but bugs out with my old ones. But this way users with already purchased subscriptions will lose their money, and I am not going to do that.
My code is:
private bool IsSubscribedInStore(IAPSubscription subscription)
{
var prod = _storeController.products.WithID(subscription.GetId());
if (prod is { receipt: not null })
{
SubscriptionManager sm = new SubscriptionManager(prod, null);
try
{
var info = sm.getSubscriptionInfo();
return info.isSubscribed() is Result.True;
}
catch
{
}
}
return false;
}
Does anyone have any ideas or at least knows how can I force unity to clear SubscriptionManager cache in runtime on users pc?
Just in case you use the same pattern with other service calls, I wouldn’t call this production-ready! In this case it works since you just assume “not subscribed” if the player is offline for instance. However, even in that case you will want to let the player know of his (or the service’s) offline state rather than letting him think his subscription ended or something. You can make some very angry customers this way.
So if you use the same pattern with other code, that could explain the behaviour.
Thanks for the reply.
I’ve done lots of tests and came to the conclusion that the problem lies in isSubscribed() giving me a result of True when it should be False.
Also, if the problem was in the try-catch voiding any exceptions, then this code would be returning false (no subscription) when there is one. Which is the exact opposite of my problem: code returning true when it should be false
Hi @FSFixer33 !
According to our main dev, the issue stems from isSubscribed always returning True on Google, likely because the subscription cancellation event is not received.
Without validating the expiration date, the system cannot detect when a subscription has expired. A complete overhaul of this class is planned, as there is already a ticket for its rework.
Local receipt validation for subscriptions is unreliable. As a real solution you would need to do server side receipt validation, which allows checking the subscription state and expiration dates with Google.
Hi @FSFixer33 !
Regarding a workaround, this is suggestion from our main dev:
Consider using the GetPurchaseState method from IGooglePlayStoreExtensions for more accurate subscription validation. This method retrieves the current state of a purchase directly from Google Play, which can help differentiate between active and canceled subscriptions.
Incorporating this method into your validation logic alongside an expiration date check, could provide a more robust solution until the complete rework of the subscription validation class is implemented.
There is a problem with this solution: in my case, I have a problem with subscriptions on Mac (Apple Store), not google. And there is no GetPurchaseState in Apple extensions AFAIK.