I created an app which is a paid app. Now I want to make it free so more user can download the app and use in app purchase to limit some features. But some user already paid to buy my app. How can I implement in app purchase for new user at the same time keep full feature access to old user?
If you connect to your server for registering user info, you can always create an API which executes on app launch to verify that user is full access user or not.
But I am afraid your case is not the above one.
In that case you would require to sync your data (some encrypted key in this context) with iCloud and when application is launched you can verify the type of user.
Using data in iCloud is more safer as compared to keychain as it covers device format scenario. But definitely not foolproof.
Other solution can be using Apple Purchase Receipt to verify the version of previous purchase. But this is only supported since iOS7.
Checkout some opensource libs to understand the parsing of receipts:
https://github.com/rmaddy/VerifyStoreReceiptiOS
So combining multiple strategies is the only answer for your question.
You can do this by reading the App Store receipt. The receipt contains the version number and date of the original purchase.
There are two main caveats: first, this only works on iOS 7 and above. Secondly, Apple don't include code for parsing the receipt (so it's not too easy for users to hack I understand). There are, however, onen source libraries, though using a common one will be less secure.
There are no perfect solutions to this scenario.
Suggestion 1:
Roll out one last paid update. In this update, use keychain to store those IAP flags. Then in the free version, check for these flags in keychain. This will work even if app was deleted and reinstalled with the free version later. But it will not work if the device is being reset completely whether due to some iOS version updates or user's unless a backup and restore also is involved.
Suggestion 2:
Not quite a suggestion. But I have seen similar apps on AppStore have just rollout free version. Then app incurred bad reviews from those previous users!
This is a simple example, but if you're working with a database on a server (not on the phone itself), can't you use a boolean for each feature you plan on selling, and just set that boolean to true for all users currently in the database. This is assuming true means they've bought the feature, and false means they haven't bought it.
You could run this query once after releasing your updated app, and then every user after that would have a default value of false for these features you're selling.
Related
For an app that is yet to be first-released, it is easy to figure out how to detect first-launch: look for absence of a "wasLaunched" Bool, or a version number, in the UserDefaults. And then set its value. This is asked-and-answered in several places on StackOverflow.
But... I am updating an already-existing app that did not save any UserDefaults info (of any kind) in its first version. Is there any way to detect, on launch of the new version, that a previous version has existed and run? I can't think of one, but that doesn't prove much.
This is important because the new version charges money for some features that used to be free. I would prefer that earlier users not be suddenly faced with loss of fuctionality.
This was also previously asked (Detecting the first launch of an app with previous versions) but all the answers missed the point of the app already existing.
Note that writing to UserDefaults is not foolproof either. If a user deletes the app before re-installing or upgrading, the UserDefaults will vanish. However, that's an edge case I would be OK with ignoring.
Based on your answer to the first few questions in the comments, the question you posted really should be rewritten to something like:
I currently have a free app. In the next update I wish to make some of the currently free functionality into paid functionality using in-app purchases. However, I don't wish for any existing users of the app to have to pay for the functionality they have been using already. Only new users of the app starting with this update should have to pay for the in-app purchase. How can implement my updated app so that downloaders of the previous version of the app do not have to pay?
Given this, your question has nothing to do with any sort of "first launch" detections. Your need is to see if the user "purchased" (or downloaded) the previous version of your app.
This can be accomplished by performing receipt validation. Once you obtain and verify the receipt, you can inspect the receipt and obtain an original purchase date and original purchase version. If that version is a version prior to adding the paid in-app purchase, treat the user as if they have made the in-app purchase already and show them the paid functionality of your app. Otherwise, check the receipt to see if it includes data on the in-app purchase and give user access as appropriate.
I am planning to make an app on iOS. The app will be free. This app will work without the internet. The app should not be able to query my database if the subscription is not paid.
However the app will still receive "notification" or RSS links even without subscription. The subscription will be monthly minimum.
I did some research but some people are saying it is not possible and some are saying this has been changed by apple and it is now possible.
Edit
I would like to add that the app will be as much secured as possible. I will have an SQLCypher database inside - so the key will be stored there too (hidden).
Here is the problem that someone told me: The user can use the app only if it paid the monthly/annual subscription, so the key has to be revocable. It seems not compatible with that because the app will have the database deciphered with the key. And if it is deciphered one day, then it will be deciphered next month too.
Why exactly people tell you is not possible?
The only problem I see from what you write is if the free version of your app doesn't do anything. As a general note Apple doesn't allow "demo" versions (even if that concept is not always clear or enforced consistently): a free app must do something not trivial (and of course lots more if the customers pay).
We have a paid iOS application in the AppStore currently. We are planning to convert it to a free application with in-app purchases. We would want to make the in-app purchases free to the users who have already paid for the application in the previous version. I think this can be done via App Receipt Validation. But will the receipt get updated once the application is converted from paid to free and will the purchase details get lost?
If you convert your app from paid to free, you are still able to inspect the receipt and see which version was originally downloaded and act accordingly.
When we did this in one of our titles, we implemented a three tier system:
We bumped the version of the save file. Any time we promoted from a save file with version <= X (where X is the last one that was on the premium version) we would award the appropriate IAPs (in our case we gave them a coin doubler, an ad disabler and a chunk of coins). You should use this simple mechanism for the majority of the users because receipt checking can require an internet connection, and your users might not be online the first time they boot after an update.
We had a 'restore IAP' button. You need this anyway on iOS if you have any non-consumable IAPs, but we additionally added a check of the App Store receipt which lets you discover whether or not the user originally paid for the game. Here's the tutorial we based our code on, we chose the easy way, but you might need to weigh that up against piracy concerns.
Our reimbursement system also checks a file that we host, which can give out extra coins/doubler unlocks/ad removers. If the receipt checking failed (we supported pre-iOS 7 so we couldn't rely on receipt checking APIs) then we could reimburse users that way if they contacted us. This is a good idea anyway, with luck you'll have a lot more users after you go free, which means more people who will discover some progress-losing bug in your app - it's good to be able to give them stuff in return.
Edit: I'd also recommend keeping track of the user's category in the save file. So, you might have 'free' users who have never paid anything, 'paid' users who downloaded for free but have bought some IAPs, 'premium' users who bought your app when it was paid, and 'premium+' users who bought your app when it was paid AND have since bought IAPs. Even if you don't need this info immediately, it's worth tracking for analytics and so that you can reward your old premium customers with free content in the future if you decide to do so.
I have an app in the iTunes store that has full functionality. I attempted to release a Free version which contains half of the functionality, and contains a link to the full version if the user tries to use the other functions.
Apple rejected the app on the basis that rather than having two apps, I ought to have the main app released for free and have the extra functions unlockable using in-app purchasing.
That's fine; I can do this. The only problem is that since I released the full version initially, some people have already paid for and downloaded the full version. When I update this app so that it is free, it will be restricted by default. Those users that have paid for the full version will have lost the functionality they've paid for.
I don't really want to release a second version of the app since I intend on continuing to update the app and managing two release streams would be unwieldy.
Is it possible to somehow offer for free the in-app purchase to those users that have already bought the full version of my app when I update the app to the new (free, in-app supported) version?
Edit: An (unpreferred) alternative would be a way of refunding the purchases to the original buyers, along with a note explaining why. Any ideas how?
What I'd do is add a already paid option within the application itself, and then allow users to enter a license code, or email address depending what you prefer, Which you can automatically issue from their contact details if you have them or ask them to contact you if you don't, which most will as they have paid.
Now as far as the licensing and the verification of these codes you could setup a cheap VPS which verify s the code and only activates with codes that you have entered on the server, meaning you won't fall victim of Keygeners.
Just my 2 cents.
If your app doesn't currently have a username/password registration, I would suggest releasing an update to the paid app that explains to your users on an initial popup view something like:
Thank you for supporting our app. Due to changes in Apple's policies, we will be converting this app into a free app with in-app upgrades. Since you already purchased the full app, you will be awarded all features! Please input an [email_address or username] so that we can provide a painless transition.
If your app has a user login mechanism already in place (username/password), then just store those details and have the user log in later in the "free" app to unlock all of the features.
Obviously, both of these suggestions require a backend for validation, but shouldn't be too difficult to create that.
This is tricky due to section 3.3.3 of the license agreement and Attachment 2. I'm not a lawyer so I'll save my interpretation but, read them.
Another option would be to make the free version a new, different app and leave the original one in the store but unavailable. Then you can still publish updates to it but new users won't see it. Apple would probably allow this considering you are still only presenting one app to new users. The downsides are (1) you have to maintain two versions and (2) you have to start over in terms of reviews etc.
I currently have a paid app in the store. Apple have not allowed a 'lite' version to be submitted as well, so I have no choice but to update the current paid version to a freemium (with in app purchase) model. I have the problem of not loosing functionality for v1 users that have purchased the app the first time round.
Is there any way to determine if an application have been updated from a previously installed version so I can unlock the paid parts of the app?
Two similar questions (from a few months ago):
Transition an existing paid for app to free version with In App Purchase
iPhone + upgrade existing paid application on app store to free application with In App purchase + what about the customers who have already purchased the paid application
There is now an Apple-approved way to do this on both iOS and macOS. The originally downloaded version of the app can be obtained from the receipt using the info key Original Purchased Version. You can then decide whether to unlock features if that version predates the switch to IAP.
For instance, once you have retrieved the receipt info:
NSArray *versionsSoldWithoutIAP = #[#"1.0", #"1.1", #"1.2", #"1.3"];
NSString *originalPurchasedVersion = [receiptInfoDict objectForKey:#"Original Purchased Version"];
for (NSString *version in versionsSoldWithoutIAP) {
if ([version isEqualToString:originalPurchasedVersion]) {
// user paid for the currently installed version
}
}
For more info see the WWDC 13 video Using Receipts to Protect Your Digital Sales. At 5:40 the presenter comments: "I think the most exciting thing that's in the receipt this year, especially for you guys if you have a paid app in the store is that we've included information in the receipt that's going to let you do a transition from being a paid app to being a free app with in-app purchases without leaving behind all the customers that have already paid for your app."
With iOS7, iOS app can verify app store receipt, which contains app download date.
By using this donwload date, you could determine if a customer is previously purchased or not
First, I just want to say I personally think the freemium model is great. It has worked out very well for many developers. People love to download free apps, and will do it on a whim, but pay much more attention to an app before spending $0.99 (Which is due to the effect of free - for more info on that, check out Dan Ariely's book Predictably Irrational)
For more info on freemium, google it - There have been tons of articles written about the success of it.
Ok, back to the actual question:
Theres a couple ways you can handle a situtation like this, although the unfortunate matter here is none of them are fool proof.
The best solution would probably be for your users to have accounts. Without knowing the specifics of your app, I can't say whether or not user accounts are appropiate for your app. User accounts stored on your server have many additional benefits, including user management, and tracking what purchases a user has made. This will allow users who delete the app, and then re-install it, or get a new device, to maintain their purchased content. Furher, whenever you use in-app purchase, you should validate the purchase on your own server (or with Apple), which a server based user manegment system can all do. If your totally in over your head with creating your own user management server, check out Parse. Its dead simple to create an amazing backend server (for basically free)
iCloud Key/Value type of system. I'm not very familiar with how this would work - so I'll move on.
Another, not nearly as fool proof solution (but much quicker/easier to implement) is to use NSUserDefaults. You can store an object when the user makes a purchase, or with the date a user installs your app. Then if you issue an update converting your app to freemium. Then in the new update, check which purchases the user has made or the date they installed it, and react accordingly. For info on how to do that with NSUserDefaults, check out my answer to another question on implementing that: NSUserDefaults and app versions.
But this solution does present the following pitfalls:
If the user deletes your app, the NSUserDefaults are lost forever
If the user didn't install the update setting up the NSUserDefault system, but then installed the update with the new freemium model, the app would treat them as if they hadn't purchased the content.
In summery, this is a difficult question, with not a lot of easy/perfect options.
Anyway,
Hope that helped!
I'm dealing with the same thing and came up with the following idea: Create the freemium version under a new name and app ID. Keep the existing paid app in the app store, but raise the price to something absurd and clearly state in the description that the app is there to maintain support for existing users and that new users should try the freemium version instead.
Existing paid users won't lose support for their existing app and can delete and install any time it without re-purchasing.
You won't have to keep updating the old paid app, either. Just keep it in the app store.
The downside is that existing paid users will not be able to migrate smoothly to the freemium version to get any extra features you add in the future without re-paying for what they already have.
Still trying to decide if this will work for me but it could be a good option for others. Comments appreciated.
I've been thinking about this problem for some time now. I have a substantial amount of customers that paid for my (in App Store terms) high-price niche-App and I'd hate having to tell them to re-purchase as I plan to migrate to an In-App Purchase model.
The idea I came up with (and I'll ask Apple support whether it's legal) is to phase out the current paid App but ship a last update for it that allows "unlocking" the In-App purchases of the new App based on the In-App model. I was thinking about a challenge response scheme:
User has installed paid App on his device
User installs new In-App App and opens it. The new App detects the paid version and offers to unlock the In-App purchases (on this device only of course and as long as the App isn't deleted)
The new App generates a nonce, signs it and calls the old App with it via an URL Scheme
The old App decrypts the nonce, adds +1 one to it and signs it again. Calls back to the new App via URL scheme
The new App validates the nonce and unlocks the features
The scheme can be easily implemented using a pre-shared key. It's of course a weakness on jail-broken devices, but then every App storing In-App receipts has those problems.
You can check the 'original_application_version' of the receipt. All iOS downloaded from the appStore have a receipt even if it is a free app.
TPInAppReceipt is a simple swift library that can help you with this.
import TPInAppReceipt
do {
/// Initialize receipt
let receipt = try InAppReceipt.localReceipt()
let originalAppVersion = receipt.originalAppVersion
let buildSoldWithoutIAP = 22
let originalAppVersionInt = Int(originalAppVersion) ?? 23
if originalAppVersionInt <= buildSoldWithoutIAP {
// unlock all features
UserDefaults.standard.set(true, forKey: "isPaid")
}
} catch {
print(error)
}
Note: The receipt.originalAppVersion returned is the build number as at the time the user first purchased the app from the appSore. Also, the receipt won't be available in the sandbox environment until you purchase or restore an inAppPurchase first.