I made an app and released it onto the App Store costing $2.99 AUD.
I now want to make it free and block some features for a premium upgrade(In App Purchase) My problem is that I want the users who have already purchased the paid version get an update to the premium version of the free app.
I was wondering if there is a way to verify the user has purchased the in app purchase before on launch of the app and if it comes back saying they have purchased, they get the extra features and if not, they don;t
Is there any way to check or verify purchases??
Thanks
The way to do this is to to check the original application version from the receipt. There is a receipt field called original_application_version. This is the version of the app that was originally purchased. You can check the receipt to see if the original version is from when it was a paid download, and flag that this user is "premium".
Whether you want to do this locally or server side is up to you.
Note that download receipts are not present in Sandbox, but should be in production. So you'll have a receipt even if no in-app purchases have been made. If for some reason there isn't a receipt present on the device, you should have a restore purchases button that will return a receipt where you can check the original application version.
Related
I'm creating a Mac app that has a non-renewing subscription as an in-app purchase. I want to sync this data to the cloud for the following reasons:
I want the user to be able to use the app on all their Macs
The in-app purchase enables a widget, so that widget needs to access this data.
By Apple's documentation the restoration of non-renewing subscriptions has to be handled by the app by some kind of registration / cloud sync.
So I decided to implement a CloudKit sync to store the following data:
Which IAP product did the user purchase (currently only one value, but might change in the future)
When did the purchase occur.
Here's what I'm doing now when a user makes an in-app purchase:
I validate the receipt
If I find any IAP data, I sync that to CloudKit
I use a function to fetch the purchase data from CloudKit for the said widget
Question 1: As far as I can tell all the in-app purchases are contained in the receipt file, even after removing and restoring it. I could be using this, however the documentation clearly says I shouldn't. Even the forums are not certain about it... What do you think?
Question 2: While testing the app with multiple sandbox users I noticed that no matter which sandbox user I use to make the purchase, the currently logged in iCloud account (my personal account) gets the receipt data synced to CloudKit. Why isn't the purchaser (App Store) user getting the data to their private cloud database? How can I test that everything works fine? Do I have to log out of my iCloud account to make this work?
Thank you for your time :)
Question 1: Using the App Receipt to restore non-renewable subscriptions
From Apple's Documentation:
Apple's documentation on whether an in-app purchase of a non-renewing subscription remains in the receipt has contradictory answers:
Yes (retrieved 2016-05-11):
Table 1-2 Comparison of subscription types
Subscription type Auto-renewable Non-renewing Free
Users can buy Multiple times Multiple times Once
Appears in the receipt Always Always Always
Synced across devices By the system By your app By the system
Restored By the system By your app By the system
No (retrieved 2016-05-11):
The in-app purchase receipt for a consumable product or non-renewing subscription is added to the receipt when the purchase is made. It is kept in the receipt until your app finishes that transaction. After that point, it is removed from the receipt the next time the receipt is updated—for example, when the user makes another purchase or if your app explicitly refreshes the receipt.
From Apple's Developer Forums:
In a thread reporting the temporary (now fixed) loss of non-renewable subscriptions from the app receipt, an Apple Developer Technical Support engineer said:
I've queried the iTunes Production Support engineer who made the change - The "fix" to provide the history of non-renewing subscriptions in the application receipt is permanent. My interpretation is that permament means that if we make a change, we'll announce the change at a Developer Conference and announce the function to be deprecated for a period of time.
With regards to using iCloud as a means to restore non-renewing subscriptions, I've heard from my App Review contact - an application "can use iCloud to track the non-renewing subscriptions (NRS) but it can’t force the user to login prior to making the purchase. It has to be optional - that can can alert the user that iCloud is required to access the NRS content from their other iOS devices - and providing a way to register later, if users wish to have access to this content at a later time."
Source: https://forums.developer.apple.com/thread/22345#79067
You could attempt refreshing the app receipt to restore the non-renewable subscriptions, but it has broken before, the documentation isn't clear, and there have been past reports of App Review rejecting applications that try this method.
Question 2:
CloudKit always uses the current iCloud account under Settings > iCloud.
App Store purchases use the Apple ID configured in Settings > iTunes & App Store.
The user may be signed into the same Apple ID for both iCloud & iTunes, but there is no guarantee. These are two entirely separate settings.
We are three guys, who have made a free game for iPhone, which has been available on the App Store for almost a year.
The app is a board game, where you create a user or login using your Facebook credentials. You are able to log out of the game and log back in with another account.
Now we have updated the app with the ability to upgrade the user to a premium user. Allowing personal and global game statistics.
But Apple is giving us a headache in the approval process, and refuses to accept our In-App Purchase. First they would not approve it, as it had no restore button. Then when we told them, a restore button was not required, as it was a consumable purchase, they now demand we change it to a non-consumable and add the restore button.
Consider this scenario if purchase was non-consumable.
User logs in.
User upgrades account to premium
User logs out.
User logs in with a different account.
User restores the previous purchase.
This would allow you to upgrade two accounts to premium, but with just one purchase.
Apple's argument is, that our users need to be able to restore purchases, if a new device is setup, or a device is restored.
But that is not the way it works. Users upgrade their accounts to premium accounts. Now when they buy a new device or restores an existing device, they just log in with their existing game account, and the upgrade will be available, because we on the server-side has marked the account as a premium account.
So my question is basically. Were we totally wrong, when we choose to use a consumable instead of a non-consumable. And if so, how should a non-consumable be implemented in order to be (potentially) purchased more than once with different game accounts on the same device?
And secondly, if we are correct about the usage of a consumable in-app purchase, what should we say to convince Apple, that we are on the right path?
If your premium account is something that your users have to buy only once then Apple is definitely right to ask you to switch to non-consumable in-app.
The scenario you described is quite possible (i had to face it too) but if you add server-side verification of in-app receipts before unlocking the premium feature (saving all transactions associated to a user) you have the chance to verify that the purchase is new or restored checking the fields original_transaction_id and original_purchase_date in the receipt data. This way you can see if the user restoring the purchase is the same that originally bought it (maybe checking its facebook user id).
Anyway, experience showed me that the chance of this happening is not really high and i wouldn't recommend implementing this check (although server side validation is almost always a must ;-) )
According to the 'Restoring Transactions' section of the In-App Purchase Programming Guide:
If your application supports product types that must be restorable, you must include an interface that allows users to restore these purchases.
If your app contains non-consumable purchase, and if you don't include a restore button apple will not approve your app.
This has been made necessary by apple after June 2012.
So to answer your question: No, it seems that you must use restoreCompletedTransactions.
Hope it helps you.
I am developing a application in which i have 10 items setup for in-app purchase, and also i am giving an option to restore the purchases he made, if user changes his device or may be any possible case.
I want to ask that, if user taps on "restore transactions" button from my application,then Store kit is going to return all the purchases id from his Apple id(that he purchased from other apps also) or it will return only of my application.
From the Test Account it returns only of my application purchases ids,But if i try with my apple id, but its giving me error: "This is not a Test User account.",I guess i cannot test restoreCompletedTransactions in debug mode.
So i wanted to know how its going to return the purchases id if the app is released.
Can any one help me..
Thanx...
It returns only the purchased products that belong to your application both in the sandbox mode and production mode.
I submitted an iPhone app to the store that got approved, but some things with the inApp purchasing weren't working. The consequence is that the users that tried to install the inApp purchases were charged, and Apple has recorded that they already purchased the additional feature. I have fixed the issue, and I use NSUserDefaults to track whether or not a user has purchased the feature. The problem is the users that have already paid for it. Is there a way to check through Apple whether or not the feature has already been paid for?
Thanks.
See the Restoring Transactions section of the In-App Purchase guide. Specifically:
Store Kit provides built-in functionality to restore transactions for
non-consumable products, auto-renewable subscriptions and free
subscriptions. To restore transactions, your application calls the
payment queue’s restoreCompletedTransactions method. The payment queue
sends a request to the App Store to restore the transctions. In
return, the App Store generates a new restore transaction for each
transaction that was previously completed.
If it is a consumable product (it shouldn't be) then I don't think there is a way to do it via Apple.
The current version of an application in the App Store is free and has very limited functionality. An In-App Purchase unlocks everything else.
I have decided to remove the In-App Purchase and just make the application cost the same price as the In-App Purchase did. But if I make the update now, then those users who have the free version but who have not yet paid for the In-App Purchase will get a free update into the full version.
I have removed all traces of my singleton class, PurchaseManager, from the application, so that at this point, when I build/run it, all of the features are unlocked. At this point, how can I make sure that the free-version users don't just ride an update into the full version?
Maybe there's a way to test whether the app is obtained through an update or through a purchase? That way, if it's through an update, I will see if it's the free version w/o the IAP and then force the user to purchase the IAP to continue playing.
Any ideas?
There was a user default that was guaranteed to be set in the first version. If the objectForKey: returned nil, then it was never set which means the first version was never run. In that case, I set YES to the user default for whether the In-App Purchase was purchased.
The above ran only once, which guaranteed that users of the demo continued to use the demo until they bought the In-App Purchase (priced the same as the second version of the game), and that users of the full version from v1.0 had the full version as planned.
Not that easy. Push out a minor update your current app and record the device ids of all those who got the in-app activated.
post a blog on your site asking users to send in their device ids and emails for re-imbursing the cost of the in-app purchase. You can cross verify this from the collected device ids.
I know this is painful. Most people who first released their apps on Cydia and then officially on app store did this. For example, snapture.