Delivery of auto-renewing subscriptions for iOS - ios

I am finding that the renewal of an expired auto-renewing subscription is never being delivered while the application is active and running, but rather when the application is woken up from background or on launch.
In other words if you are using the app, and the subscription expires, it won't be delivered to the app (assuming it is auto-renewing and valid etc) while the user continues to use the app.
This behaviour does not seem to be documented by Apple, can anyone else with experience of this confirm or otherwise?
Obviously one can detect that the sub has expired and then offer the user the chance to check their subscription status and restoreCompletedTransactions which will pull in the new subscription - but I'm just wondering if we're doing something wrong, or if this behaviour is normal.
Thanks.

Yes. That's what I experienced as well.
Before I continue, please see the following posts on why you might want to stay away from auto-renewing subscriptions:
Marco Arment's piece on The limited world of auto-renewable subscriptions, and
The Comments on this SO Question: Auto-renewing subscription – Differences to non-renewing subscription
When your app becomes active, that does seem to trigger the App Store to send any new auto-renewing subscription receipts to your app. But you shouldn't rely on that. And, you don't have to restoreCompletedTransactions to get the latest receipts.
You can see another one of my answers for more detail on this subject.
What you should be doing (based on Apple's documentation and some experimentation) is storing receipts on your server. Then when you want to check if a person's subscription has been auto-renewed, follow Apples procedure for verifying one of those receipts with iTunes. Apple will respond with info about that receipt as well as the latest receipt in that subscription. If it's different than the one you sent, then you know an auto-renewal has occured.

Related

iOS Auto Renewable Subscriptions and Receipt Validation Clarifications

I was wondering if my approach regarding auto-renewable subscriptions is correct.
I have implemented an auto-renewable subscription in my app, it is the only IAP.
When the user launches the app, it performs receipt validation through Apple's servers. When I receive the response I check the expires_date_ms in latest_receipt_info to see if the user is subscribed or not. When I perform receipt validation I also add the exclude-old-transactions tag. I have also added a "Restore previous purchases" function to restore older receipts on the first app launch.
Is my approach correct or I am missing something? Also, do auto-renewable subscriptions auto-renew automatically or do I have to implement the feature by myself?
Thanks in advance for any help.
Regards.
Auto-renewable in-app subscriptions do renew automatically, you don't need to do anything for that. You just need to check if a subscriber has an active subscription when using your app. You can also activate the grace period in App Store Connect for your subscription, so your users will have access for additional 16 days if Apple could not renew the subscription. You can read more here https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/reducing_involuntary_subscriber_churn

Validate iOS auto-renewable subscriptions from multiple apps

I work for a game developing company which releases at least one game a month. For our true fans we want to start providing a subscription to our games, so they can play all our games (on any platform) without constantly having to buy them.
The idea for iOS is to use the in-app auto-renewable subscription. This results into a receipt which we store in our backend. The backend can validate this receipt and provide the apps with information about the subscription of the user.
This system will solve a lot of problems: You can take the subscription in 1 game, and play all the games as well, on any device you like.
But now we come to the problem: After a month the receipt is not valid anymore, and we need to check in the iTunes store to see if the user still has a valid subscription.
My first idea was to use the "latest_receipt_info" field, to get the latest receipt and validate this. But according the documentation this feature should only be used for iOS 6 receipts:
"Only returned for iOS 6 style transaction receipts for auto-renewable
subscriptions."
source:
https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-
Even though I can actually still use this field with my brandnew iOS 10 receipt, I don't think it's smart to use it since it's deprecated.
(another source telling you shouldn't use it anymore: https://forums.developer.apple.com/message/156580#156580)
The advised solution of apple is to implement a SKPaymentTransactionObserver in the app. This will retrieve the latest receipt when it's available, and send this to the backend. Even though this is far from ideal, this could work... however:
This means the app has to be active to retrieve the latest receipt. And in our case it's very well possible a user takes a subscription in app1, and after a couple of days downloads app2, 3 and 4, but never uses app1 again. So in this case the latest receipt will never be fetched (because only the observer of app1 can access the receipt)
To fix this problem we should be able to fetch the receipts from this subscription from any app in our subscription group. But according the documentation on the apple site (https://developer.apple.com/app-store/subscriptions/ ) you can only access a subscription from 1 app, and you have to do the multiple app thing yourself:
You can offer auto-renewable
subscriptions to access multiple apps in your portfolio. Each app must
be approved to use auto-renewable in-app purchases and must be
published under the same developer name on the App Store.
In iTunes Connect, you’ll need to set up separate and equivalent
auto-renewable in-app purchases in each app offered in the multi-app
subscription so that users can subscribe from any app. To avoid users
paying multiple times for the same offering, you are responsible for
verifying that they are subscribers in one of the apps before showing
any subscription options. To do this, consider maintaining an account
management system in which users create an account with your business
to sign in to each app.
So is there any way to do what we want, without forcing the user to go back to the app he used to purchase the subscription every month?
On the last WWDC we went to StoreKit labs and personally asked StoreKit evangelist about this. We were told that the 'latest_receipt_info' field return by iTunes validateReceipt endpoint is exactly what we are suppose to use in order to check if the subscription was renewed or not.
This is not going to be deprecated in the near future but they do have plans for adding some server-to-server communication that solve few of the problems we ran into:
Your server will be able to get notification from Apple regarding any subscription renewal, cancellation, downgrades etc.
In the latest_receipt_info returned by the validateReceipt endpoint few fields will be added, providing information like whether the subscription will be renewed after current one is expired, whether there was a problem charging the user's credit card etc.
Sources:
WWDC 2017 Session 303 - What's new in StoreKit
WWDC 2017 Session 305 - Advanced StoreKit

Does Non-Renewing subscription requires a restore button?

My app got rejected because of restore button on non-renewing in app purchase. Do i have to remove restore button ? If i have to do so then how user will restore his purchases.Please help.
Non-renewing subscriptions are consumable. Therefore they cannot be restored. A restore button therefore makes no sense. You also need some kind of authentication/login system for the user. (See below for detailed explanations.)
Sources:
consumable vs. non-consumable in app purchases
non-renewing subscriptions
Update from WWDC2017: In Session #303 App Store Engineer Pete Hare explains at 3:00 that a non-renewing-subscription can be seen as "a consumable product with an expiry date on it"
There has been some debates in the comments wether non-renewing subscriptions are consumable or not, so I want to say something about it. "Consumable" means that you can consume them multiple times. Like "30 minutes of talking" in a voice-over-IP telephony application. On the other hand, there are non-consumables that you can buy only once. Like when you unlock all levels in a game app. You buy it once, and when you reset the device and redownload the app, you should be able to restore the purchase, so that you don't have to pay twice to unlock all levels. Furthermore, if you don't tap the restore-button in this case but just buy the "unlock all levels" package again, it works, but you will not be charged by apple a second time. That's why it is called non-consumable. It's some kind of metapher. An apple is "consumable". Once it is consumed, it is gone. A chair is non-consumable. You have it as long as you don't destroy it or give it away.
So, it makes sense to regard a non-renewing subscription as non-consumable. If you buy it a second time, you shouldn't pay twice, you should just use the old subscription you already have. If you reset the device, you should be able to restore the subscription once you re-download the app. The restoration is just not done by Apple but by the app itself.
I still regard non-renewing subscriptions as consumable though. I use a simple definition of consumable vs. non-consumable: An in-app-purchase is consumable, when, from the point of view of the StoreKit API, it can be purchased multiple times in the same week by the same user. All consumable IAP-items cannot be restored through the StoreKit. All non-consumable IAP-items can be restored through the StoreKit.
So, the developer is himself responsible for restoring the in-app-purchase of a non-renewing subscription, right? No, sorry. How would the app restore the in-app-purchase of a non-renewing subscription? Suppose I have an iPod and I subscribe to 1 month of listening to the Foo-radio. Now I want to also listen to the Foo-Radio on my iPad. Soo, I install the Foo-App on my iPad and tap the "restore" button. Well... what is the "restore" button supposed to do? How can it know if I already have purchased a "Foo"-subscription or not, and how long it will still be valid? Answer: it can not. This approach does not work.
In order for a non-renewing subscription to work, you have to login the user first, to tie the subscription to some online account. Username/Password, Open-ID, Login via Gmail, Facebook, etc. all would work. Then, when the user purchases an n-r subscription you have to store the fact that he subscribed on some server and link it to his account on the server. You also have to prevent the user from buying the n-r subscription when he is not already logged in. Let's continue with my iPod/iPad-example above. I download the app on my iPad, I login with Facebook, and voila, I can use the "Foo"-subscription now. There is no need for a "restore" button, because the app should check at login-time which subscriptions the user has.
There will be some additional problems to deal with. (1) For example, nothing prevents the user from logging in into 200 devices. Here the problem is not a user with 200 devices, but a university with 1000 students where 180 students share the same account. (2) If the server crashes, some people will probably lose their subscriptions. Problem (1) can potentially lead to decreased income. Problem (2) can lead to angry and unhappy customers.
From Apple: "Non-renewable subscriptions. Subscriptions that don’t involve delivering episodic content. Examples include access to a database of historic photos or a collection of flight maps. It’s your app’s responsibility to make the subscription available on all of the user’s devices and to let users restore the purchase. This product type is often used when your users already have an account on your server that you can use to identify them when restoring content. Expiration and the duration of the subscription are also left to your app (or your server) to implement and enforce." [Italics and bold added] https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Products.html
Apple Reviewer's current-similar response about Non-Renewing Subscriptions "Your app offers Non-Renewing Subscriptions and this purchasability type must have its own restoring function - if you have removed it please re-implement it. Furthermore, your app must also offer a function, such as account creation, such that purchases can be tracked across all of a user's devices. Please implement a login feature as well as a restore mechanism prior to resubmitting your revised binary for review."

How do I verify IOS In-App Purchasing Receipts in Bulk?

I'm working on an iOS app that will use Apple's in-app purchasing framework to let the user create auto-renewing subscriptions.
I want my server to check periodically that none of the subscriptions have expired. Apple's Receipt Validation Programming Guide describes a verifyReceipt web service that appears to validate a single receipt.
However, if I want to bulk-verify my entire database every few days, is there a better way to do that than a storm of individual verifyReceipt calls?
You don't need to need to bulk-verify your entire database. A subscription is valid for a fixed duration. If the user cancels their subscription then this takes effect at the next renewal period, not immediately.
Apple customer service can refund a subscription if a user has a case (wrong product purchase is one example they give) but this would be a pretty low figure - and your app should also check for a valid subscription when it starts.
So you should only need to verify subscriptions that are known to be expiring "today".
To my knowledge there's no way to send multiple receipts in one bulk request to validate them in the iTunes servers... You have to send one by one. (Multiple requests)...
I don't know if how you are planing to solve this is the best approach. Apple has extended documentation on how to handle auto renewal subscriptions, most of the times you check the validity of the subscription in the app itself.
Check the in-app purchase documentation. It's a very good read if you plan to depend on in-app subscriptions for your business model:
https://developer.apple.com/library/ios/technotes/tn2259/_index.html

Refund the previously purchased non-renewing subscription, not the current one. Possible?

I'm implementing an iOS app with non-renewing subscription. Not much relevant information was available online; so I seek your guidance.
A use case which worries me the most is when a user purchased the subscription once and then immediately after purchase it again to extend the duration of service (see such scenario here). What if that user were to refund the first purchase, leaving the second one intact? Is this even possible in practice, or am I just too paranoid?
Assuming the above case is possible, my app will run into a problem because, as far as I know, verifyReceipt only returns the latest, good receipt (watch Managing Subscriptions with In-App Purchase in WWDC'12).
I find nowhere Apple provides relevant information about refunding policies.
(Auto-renewable subscription seems to rule out this case as a renewing action is taken care by iTunes automagically and it seems not possible to extend this type of subscription until iTunes allows it.)
verifyReceipt will not only return the latest good receipt, it will also tell you if the receipt you submitted for verification is good. So if you're concerned that a user may have cancelled* a transaction, then submit every receipt you're questioning.
*But what do you mean by "cancel" the first purchase? Do you mean when they tap "cancel" instead of "buy?" Well then the transaction won't go through and you won't even get a receipt.
Or do you mean when they request a refund? I don't know any other way they can cancel a purchase.
Edit:
If you're referring to refunds, there's no way for a developer to tell if a user has been issued a refund. The assumption is that Apple expects you to continue to deliver services to that user regardless of the fact that they received a refund. Your receipts will probably all verify correctly regardless of the status of a refund.

Resources