I tried to use SubscriptionManager.
The following is the code.
Dictionary<string, string> introductory_info_dict = m_AppleExtensions.GetIntroductoryPriceDictionary();
foreach (var item in controller.products.all)
{
if (item.availableToPurchase)
{
Debug.Log(string.Join(" - ",
new[]
{
item.metadata.localizedTitle,
item.transactionID,
item.receipt
}));
if (item.receipt != null)
{
if (item.definition.type == ProductType.Subscription)
{
if (checkIfProductIsAvailableForSubscriptionManager(item.receipt)) {
string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId];
subscriptionManager = new SubscriptionManager(item, intro_json);
SubscriptionInfo info = subscriptionManager.getSubscriptionInfo();
Debug.Log("product id is: " + info.getProductId());
I referred to IAPDemo.cs.
This code works fine in iOS device, but an exception is occurred in Android device.
Here is the exception.
I tried to use m_GooglePlayStoreExtensions.GetProductJSONDictionary() instead of m_AppleExtensions.GetIntroductoryPriceDictionary(), but it didnât work neither.
Can I use SubscriptionManager in Android device?
If so, how should I fix my code?
Unity version is 2018.4.15f1.
IAP version is 1.23.1.
Here is the entire function.
The exception occurs on the line 33, âSubscriptionInfo info = subscriptionManager.getSubscriptionInfo();â
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
m_AppleExtensions = extensions.GetExtension<IAppleExtensions> ();
m_AppleExtensions.RegisterPurchaseDeferredListener(OnDeferred);
Debug.Log("OnInitialized: PASS");
storeController = controller;
storeExtensionProvider = extensions;
m_GooglePlayStoreExtensions = extensions.GetExtension<IGooglePlayStoreExtensions>();
Dictionary<string, string> introductory_info_dict = m_AppleExtensions.GetIntroductoryPriceDictionary();
foreach (var item in controller.products.all)
{
if (item.availableToPurchase)
{
Debug.Log(string.Join(" - ",
new[]
{
item.metadata.localizedTitle,
item.transactionID,
item.receipt
}));
if (item.receipt != null)
{
if (item.definition.type == ProductType.Subscription)
{
if (checkIfProductIsAvailableForSubscriptionManager(item.receipt)) {
string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId];
subscriptionManager = new SubscriptionManager(item, intro_json);
SubscriptionInfo info = subscriptionManager.getSubscriptionInfo();
Debug.Log("product id is: " + info.getProductId());
Debug.Log("purchase date is: " + info.getPurchaseDate());
Debug.Log("subscription next billing date is: " + info.getExpireDate());
Debug.Log("is subscribed? " + info.isSubscribed().ToString());
Debug.Log("is expired? " + info.isExpired().ToString());
Debug.Log("is cancelled? " + info.isCancelled());
Debug.Log("product is in free trial peroid? " + info.isFreeTrial());
Debug.Log("product is auto renewing? " + info.isAutoRenewing());
Debug.Log("subscription remaining valid time until next billing date is: " + info.getRemainingTime());
Debug.Log("is this product in introductory price period? " + info.isIntroductoryPricePeriod());
Debug.Log("the product introductory localized price is: " + info.getIntroductoryPrice());
Debug.Log("the product introductory price period is: " + info.getIntroductoryPricePeriod());
Debug.Log("the number of product introductory price period cycles is: " + info.getIntroductoryPricePeriodCycles());
if (Result.True == info.isSubscribed())
{
if (Result.True == info.isCancelled())
{
Debug.Log( "Subscription Canceled" );
}
else
{
}
}
else if (Result.True == info.isExpired())
{
Debug.Log( "Subscription Expired" );
}
}
else {
Debug.Log("This product is not available for SubscriptionManager class, only products that are purchase by 1.19+ SDK can use this class.");
}
}
else
{
Debug.Log("the product is not a subscription product");
}
}
else
{
Debug.Log("the product should have a valid receipt");
}
}
}
}
Thanks, @SamOYUnity3D but this is VERY critical as its technically broken for all subscriptions on Android. Is there a work-around or a repo that we can use until release?
Thanks @SamOYUnity3D . Weâre already doing that but it just avoids the crash. We have no info about the subscription status so we have to auto-assume that itâs still active if it fails to parse.
Is the plugin being deprecated? aka, we should find alternative ways of fixing this?
We have addressed this issue before and it has been fixed in IAP 1.22.1 and later. Since you mentioned that you still encounter this issue in the latest IAP version, I think we need further investigation. I would appreciate it if you can provide steps to reproduce.
OK sure. Letâs start by making sure we have the correct versions.
The Package manager says Version 2.0.6 which is the latest version available. The Changelog.md says [1.23.1] - 2019-11-18. If the bug has been resolved at the end of January, do we have that fix or not?
I see. I think this is a new issue. We couldnât reproduce this issue in the latest version, it will be helpful if you can provide it. Also, could you attach the device log here for investigation? Thanks.
Got it, it does indeed look like the same issue that we fixed, and no longer reproduced for us as the time. What product type is this receipt for? Are you checking to make sure itâs a Subscription receipt first?
Agreed with Jeff. I can reproduce this issue if I donât use âif (item.definition.type == ProductType.Subscription)â to check whether the product is a subscription product.
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
m_AppleExtensions = extensions.GetExtension<IAppleExtensions> ();
storeController = controller;
storeExtensionProvider = extensions;
m_GooglePlayStoreExtensions = extensions.GetExtension<IGooglePlayStoreExtensions>();
Dictionary<string, string> introductory_info_dict = m_AppleExtensions.GetIntroductoryPriceDictionary();
foreach (var item in controller.products.all)
{
if (item.availableToPurchase)
{
if (item.receipt != null)
{
if (item.definition.type == ProductType.Subscription)//Please use this to make sure it's a subscription receipt first.
{
if (checkIfProductIsAvailableForSubscriptionManager(item.receipt)) {
string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId];
subscriptionManager = new SubscriptionManager(item, intro_json);
SubscriptionInfo info = subscriptionManager.getSubscriptionInfo();
}
else {
}
}
else
{
Debug.Log("the product is not a subscription product");
}
}
else
{
Debug.Log("the product should have a valid receipt");
}
}
}
}
Please provide the device logs that confirms. They will contain the Debug.Log information. Does this happen for all your subscriptions, and all your users? Your test users need to download the game via Google Play, AFTER opting into the test program from a browser on the device.