Hi I’ve been going in circles for a while on this, basically trying to get Subscription Manager to detect if an Auto-renewable Subscription is currently active but will not auto-renew. I think I have tried every combination in the sandbox but nothing is working.
From the docs: • isAutoRenewing() This returns a result to indicate whether this Product is auto-renewable.
To me, “IsAutoRenewing” and “Is Auto-renewable” are not necessarily the same thing. Is this indicating if the product is an Auto-renewable type? Or is it indicating the status of the renewing subscription, ie if it will renew on expiry. In the docs it also says this: “Non-renewable Products in the Apple store return a Result. Unsupported value” which suggest that it does actually returning if the subscription is currently set to renew. However this is never returned to be true (at least in sandbox mode). Even when the sandbox subscription is renewing a random amount of times.
• isCancelled() - Returns a Result enum to indicate whether this Product has been cancelled. A cancelled subscription means the Product is currently subscribed, but will not renew on the next billing date.
This sound like what I’m look for instead of isAutoRenewing but if that’s the case what is the point of isAutoRenewing()?
• isSubscribed() and isExpired()
Could it be possible I have to ignore the above and check if isSubscribed()= false and isExpired()=true? This I haven’t yet tried but it seems very strange to have to do that given the other two options…
Please what is the elusive combination I need to check?
You would wan to test, as you are. However, you mention you want “to detect if an Auto-renewable Subscription is currently active but will not auto-renew”, I’m not clear on how that would be possible? You mean if the renew attempts to withdraw from their bank, but there isn’t sufficient funds, for example?
Its a pretty common situation in the AppStore like this:
User purchases a 1yr Auto renewable subscription. Halfway through the year they decide to cancel the subscription so it doesn’t auto renew when it expires. But since they already paid for the rest of the year the receipt should show that it’s not expired and will not renew but it’s still valid.
It would appear that is the purpose of these two methods isCancelled() and isAutorenewable() but they don’t seem to work?
Ok so this is with the Apple App store not the GooglePlay store. I’m not finding in the sandbox mode that it ever returns that Autorenew is cancelled or turned off. As I understand, the Apple App Store during testing will renew the subscription a random amount of times between 0 and 6 before expiring. Even on the last time before it expires the subscription manager returns Autorenewable.true && isSubscribed.true && isCancelled.false && isExpired.false, in other words it’s not giving any indication that it is about to stop renewing.
If this is because I am in sandbox mode then that means this situation cannot be tested before going live, so I could really use a definitive explanation of the subscription manager use. And maybe isAutorenewable() could probably be renamed willAutoRenewOnExpiryDate() if that’s actually what it does?
Yes ok that seems like the right field. So I take it from your response that it is not implemented in the UnityIAP Subscription Manager Class or the IPurchaseReceipt Class?
It seems like this should be included as it’s pretty fundamental to subscriptions. It’s also very confusing because SubscriptionInfo.isCancelled() seems like it should cover that condition.
So does SubscriptionInfo.isCancelled() work in release then?
Right now in Testflight and Sandbox mode the cancellation date from IPurchaseReceipt is always Cancellation Date: 0001-01-01 12:00:00 AM even for older sandbox purchases that have expired (perhaps Apple is somehow making the sandbox auto-renew expire without cancelling it).
Additionally Subscription Manager never returns isCancelled.true or isExpired.true because when the sandbox subscription is not renewed, controller.products.all → item.receipt becomes null immediately and subscription manager doesn’t run. Is this the expected behaviour?
Could you provide a device log or screenshot with a cancellation date like "0001-01-01 12:00:00 AM "?
Additionally Subscription Manager never returns isCancelled.true or isExpired.true because when the sandbox subscription is not renewed, controller.products.all → item.receipt becomes null immediately and subscription manager doesn’t run. Is this the expected behaviour?
Yes, I did a similar test before and the results are the same as yours.
So regarding the above, you’re saying the expected behaviour is that SubscriptionInfo.isCancelled() and SubscriptionInfo.isExpired() methods will never ever return anything besides false? I must be missing something, why do they exist?
Here are the debug logs from PurchaseProcessingResult. You can see the subscription renews 6 times automatically and then stops, but there is never a cancellation date.
I am also finding this issue. On my initial implementation of our Restore Purchases feature, I noticed when testing that our app would flood the database with new entries for all previous transactions (which works out to be a lot since I’ve been using the same Apple test account for almost a year now). Initially I implemented a system that just checked whether we had already restored the product and then stopped further posts to the database, but as we move towards implementing purchasable, non-consumable and consumable items (up to this point we only had subscriptions), this “solution” will no longer be appropriate. I don’t even think it was appropriate to begin with.
As far as I can see, in Sandbox mode, when IAppleExtensions.RestoreTransactions gets called, it is calling ProcessPurchase with every single previous transaction, and there is nothing filtering out expired transactions. This is further shown when we reach our process which uses SubscriptionManager to check isSubscribed, isExpired and isCancelled. In this process we would assume that it would return isSubscribed = false and isExpired = true for an expired transaction, but it seems that it instead returns isSubscribed = true.
I believe in our SubscriptionManager process we can check the current time against the result of getExpireDate, and then filter out expired transactions. I’ll experiment with this and return with what I find, but it would be simpler if the above isSubscribed and isExpired worked, so hopefully this may give you guys at Unity a bit more idea of what’s happening?
Currently on: 2019.2.17f1, UnityIAP 2.0.6 (package manager)
EDIT: I missed something there, I now see that isExpired and isCancelled returning false every time is expected behaviour. However, I would expect UnityIAP to not call ProcessPurchase on transactions that have had their expiry date elapsed. Is there any particular reason this isn’t the case?
We don’t explicitly call ProcessPurchase, that is done by the store API. We are a pass-through service only, and don’t have control over this behavior.
Huh, I was under the impression that ProcessPurchase was a callback triggered by UnityIAP after it receives purchase data from the store. Good to know, appreciate it.