Subscribing to Multiple iOS Subscriptions - ios

I have a question about setting up auto-renewing subscriptions on iOS.
In my app, a user is able to be subscribed to multiple subscriptions at the same time. Is there a way to find out which subscriptions a user is currently subscribed to. In android is is as simple as loading the owned purchases from google via the billing processor. Is there an equivalent in iOS or do I need to do something else. Thanks.

You cannot determine on your own whether a user is subscribed or not. The only possibility for you to determine if a user is subscribed is to either validate preexisting receipts or restore purchases. I recommend you to watch the WWDC sessions regarding StoreKit at developers.apple.com, use Swifty StoreKit as it saves you some of the hazzle and read Apple's documentation.

After some research, I found the best way to do all InAppPurchasing was to use the library: SwiftyStoreKit. It makes everything a lot simpler and streamlines the whole process. It is well supported and well documented.
Here is the link to the github repository: https://github.com/bizz84/SwiftyStoreKit

Related

Offering an iOS Subscription Across Multiple Apps

Does anyone have experience implementing this in their apps? I wasn't able to find very much documentation on this topic. It looks like even RevenueCat hasn't implemented this yet. I did find a Google-cached page that contains a question asking whether they will support this. The response was that it's on their radar. But that page has since been removed leading me to believe they have abandoned this plan.
From the Apple documentation:
When providing auto-renewable subscription access across multiple
apps, you must authenticate the user in a way that can be correlated
across apps. Authenticating users via a login allows you to determine
if the user has access to the content. The login process should be
consistent across your apps.
But if you have this, what is the added value of this new subscriptions-across-apps feature? One could already implement subscriptions across apps this way. Is there some special identifier that links the subscriptions on Apple's side that allows users in app B to restore subscription purchased in app A?

Server-side validation of iOS and Android auto-renewable subscriptions using server-to-server notifications and Firebase Cloud Functions

I have successfully implemented subscription validation for Google Play, but I am struggling to understand the validation flow for iOS auto-renewable subscriptions and would like to ask for your help. Here is how high-level logic for Google Play:
New subscription validation
User purchases subscription in the app.
A SubscriptionRequest is created in my Firestore database, which includes the UserID and the token of the transaction.
A cloud function picks up that SubscriptionRequest and queries the relevant Google API using the token to get the subscription details. This is done using the googleapis Node.js libary.
The latest subscription details are saved in Firestore as a Subscription, including the token (as linkedPurchaseToken) and the UserID.
The expiry date of the subscription is evaluated and, if it is not expired, the User in Firebase is updated and the flag hasActiveSubscription is set accordingly (including Google Play identifier of the subscription, e.g. monthly_sub, or annual_sub, and the platform, in this case android).
Google Play Developer notifications
Notification is received via a Pub/Sub cloud function.
The corresponding subscription details will be fetched using the relevant Google API and the token from the notification.
If no Subscription with that token (as linkedPurchaseToken) exists in the database, we'll try to get find the existing Subscription in our database using the linkedPurchaseToken from the subscription details that were fetched in (2).
If still no Subscription can be found in the database, that obviously means that it's a new subscription, which will be handled exclusively via the New subscription validation process described above. The reason for this is that I am otherwise unable to link my UserID and the subscription.
If a Subscription is found, it is updated with the latest details.
The expiry date of the subscription is evaluated and, if it is not expired, the User in Firebase is updated and the flag hasActiveSubscription is set accordingly. [...]
This has been working exceptionally well and robust for quite some time.
As far as I can see the developerPayload, which could be used to pass on, e.g. the UserID, to determine who the subscription belongs to, is deprecated. (Source)
Do you think there is an easier way of doing this, possibly
only using Google Play Developer notifications?
I am receiving a notification at every step a subscription changes and I am simply updating my Subscription and hasActiveSubscription flag based on the expiry date. This is working well because I receive a notification at the moment the subscription expires (notification type SUBSCRIPTION_EXPIRED) and at any point the subscription gets extended, for example. (Source)
Is there anything missing in that validation logic or any potential risk?
These two questions so far are only to ensure I am not missing something essential. Again, from my experience this is working quite well.
All that is left for my app (based on Flutter, by the way) to be released on iOS is to implement the validation logic for iOS.
One thing that has made the google validation logic rather easy, is that there is the googleapis library, which essentially is giving me the model classes for all responses, such as the notifications or the subscription details. I have been unable to find something similar for Apple yet and I am not sure there is.
Is there any (official) library that is providing me with similar features as googleapis for Node.js?
For new subscriptions I am currently querying the verifyReceipt endpoint, which seems to be working well. However, Apple does not seem to say anywhere which fields need to be validated exactly, in order to provide users with access within the app. I am following the same logic, meaning: If I do receive a valid receipt from the endpoint and it is not expired, I grant access.
Is that logic sufficient for new subscriptions or am I missing something?
For Google so far I simply stored the subscription details that I received via querying the api, including the UserID and token. This is done mainly for laziness and because the document structure received is rather simple. The Apple responses are much more complex, so I am quite unsure about what to store (and poorly documented, if you ask me), so I am wondering:
Which details do I actually need, for both Google and Apple, especially if I rely on notifications for updating the subscription?
Regarding updates to the subscriptions, I am wondering how to work with server-to-server notifications from Apple.
When exactly are they being send and can I implement the same logic as described above for Android?
As I can't seem to find a good documentation or tutorial for this part:
Do you possibly know any good tutorials for these notifications?
Thank you very much for your support,
Matthias
It has been a while since i asked these questions and while technically the questions have not been answered, I would still like to share my solution with everyone.
The solution I have gone for is simply implementing RevenueCat, who focus on managing in app subscriptions for you, so that there is no need to worry about all those questions anymore.

iOS Auto Renewable Subscription minimum functionality and Free Trial outside of StoreKit

I'm implementing IAP for SaaS application. I nearly finished with Store Kit's integration, receipt validation and other development related stuff. But I still have 2 more questions regarding Apple's guidelines which I couldn't find answer to on the docs.
The first question: I read on few places on the web that my app should provide minimum functionality even if the user is not subscribed. I offer a SaaS app and I don't want the user to be able to use the app if he's not subscribed. I will allow him to purchase a subscription if he is not subscribed. Is it enough for minimum functionality? (I suspect that these minimum functionality restrictions are old and obsolete, as they sound absurd).
The second question: I want to offer the user a possibility to try the app for free without subscribing at all (Without Store Kit's Free Trial option), because I don't want make the user make a commitment to pay before he tried the app (Apple also doesn't provide a convenient way to cancel the subscription, which may cause abandon-users to be charged even if they don't use the app, which will cause bad reviews etc). So the question is, can I do this without risking my app to get rejected? Does apple allow such kind of Free Trial feature which is managed solely by my server?
Forgive me if this info is somewhere on Apple's docs, but I couldn't find anything related. Thanks!
Okay after sending a query to Apple (Which didn't help me much to understand) and submitting an app to the App Store, I may have an answer:
Apple do allow SaaS apps and did approved my SaaS app. I honestly don't know if they checked my app enough to tell if it is okay but it was approved.
My app implements the Free Trial mechanism without App Store's free trial option. It is clearly written on the registration view controller that the app offers 3 month of free usage without obligation, and then continues without popping and App Store free trial page or something. My app was approved so I guess it is actually okay and within Apple's guidelines.
Hope it'll somehow help someone.

Using undocumented fields in an App Store Receipt

OK I'm working on a app where the user purchases the app from the App Store, gets access to the app for a year, and then after the year has passed they are sent to an In-App Purchase screen where they can purchase a subscription for continued access.
(this is not the subscription model I'd implement if it were up to me, but the client insists that it follow this model)
In order for it to work, though, I need a reliable way to check when the app was purchased, in order to calculate when the first year of access ends. Following the suggestions in one of the answers in...
iOS App Purchase Date
...I've gotten the app receipt and I can find all the data fields that the documentation says there are, but there are also a few others including "original_purchase_date" (not the one in the IAP receipt array; the one for the app receipt itself). This would appear to be what I want. However this field is undocumented.
As far as I can tell, Apple security operates via a form of "Security Through Obscurity/Diversity", so it's been difficult to find further information about these undocumented data fields. My concern is that I might use the data from this field, and then discover that it was only there in sandbox mode and actual receipts don't have it. Worse, what if I reference that field and then Apple releases a new iOS update that completely discards that field from its implementation? Undocumented features are even less reliable than deprecated features, after all.
My question is this: is there a reliable source of information somewhere where I can find out what Apples intends regarding this field? Or better yet, is there another, safer way of achieving the system my client wants?
You have to implement it as a free app that requires a subscription IAP. Paying for an app cannot be its subscription cost.
Check rule 11.12 here: https://developer.apple.com/app-store/review/guidelines/#purchasing-currencies
Apps offering subscriptions must do so using IAP, Apple will share the
same 70/30 revenue split with developers for these purchases, as set
forth in the Program License Agreement
Implementing it the way your client wants will result in rejection.

How to restore non-renewing Apple subscriptions

The app I'm working on was recently rejected by Apple for containing an auto-renewable subscription. They recommended that we switch to non-renewing subscriptions for our content.
The one thing I can't quite wrap my brain round is how to restore a purchased subscription to a shared device. Apple recommends we don't use user login - something we would like to avoid ourselves. I did come across one solution where unique codes were used between the two devices - to validate a purchased subscription, through a server. But I believe that could be easily pirated, as in theory friends or employees within a company could share these unique codes with one another and avoid paying the subscription charge.
I can't really find much on Google about this, and was curious to know if anyone has been able to successfully implement a non-renewing subscription?
To paraphrase the advice we received from Apple when dealing with these issues:
Per the iTunes Connect Developer Guide:
...subscriptions must be provided on all devices associated with a
user. In App Purchase expects subscriptions to be delivered through an
external server that you will provide. You must provide infrastructure
to deliver subscriptions to multiple devices.
Apple consider user registration to be appropriate but won't allow you to make it obligatory. So registration must be optional and the user must be able to register at any time — including to allow them to share a subscription they've already bought between devices.
So it sounds like we may have received slightly different advice. Is it possible that Apple only told you not to require user login in general, separately from the requirement for distributing the subscription to all devices?

Resources