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.
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 planning to use subscription (auto renew) type of in-app purchase. My idea is to allow one subscription per device. (i.e.) if someone purchase the subscription on iPhone, he shouldn't be able to use same subscription on iPad. Instead I want to force user to new subscription for other device. But from in-app purchase what i understood is that, if user subscribe for a particular item, if he tries to purchase the same thing again, app store allows to user to restore already purchased item.
As per my current setup, all the downloads will happen from a separate server and I am going to keep all the receipts and content in that server. In order to implement this particular thing, what should I do in my application? Could someone help me on this?
Also if I want to limit download of data from server using in-app purchase for only 3 device? Beyond 3 I want user to make payment via in-app purchase again? How will I do this?
Thanks
Apple's In-App Purchase Guidelines state that you must support restoring subscriptions to all of a user's devices (see page 7).
Also consider if your content is episodic (such as a TV show or magazine) because that's a requirement for using auto-renewing subscriptions. For things like time-limited access to a certain feature, like voice guidance in a navigation app, you'd need to use non-renewing subscriptions.
We want to sell digital content through subscription model in our app. Is it possible to support a subscription bundle? Let's say content in question is magazine subscription for $0.99 a month. Is it possible to support a bundle of subscription such that user can subscribe to any three magazine by buying a bundle for let's say $1.99? Or is it possible to support eat-all-you-can model - $3.99 for subscribing to all magazines in our app?
According to the official documents from Apple, yes you can. What you need to do is design your iAP store and items according to Apple's requirements.
Getting Started with In App Purchase
on iPhone OS (Version 2.0)
...
Subscriptions
Subscriptions and subscription
renewals to content or services can be
offered to customers for purchase. You
can offer customers the opportunity to
renew their content or service
subscriptions using In App Purchase,
but be sure to define a reasonable
renewal frequency to avoid bothering
users with unwelcome reminders. Be
aware that you are responsible for
both tracking subscription expirations
and for renewal billing; the App Store
does not monitor subscription duration
and does not offer an automatic
billing mechanism. Be sure to indicate
when an item is a subscription when
entering its product information into
iTunes Connect.
Both of these features are supported, they are called consumable and non-consumable in-app purchases.
IN BUILT_IN MODEL
If i purchase feature through Non-consumable for on application,if i delete it,
If i purchase it again,will apple remember my user_id to purchase it as free?
IN SERVER MODEL?
suppose the app uses server model, may the server use apple to remember that user?
any help please?with explaination?
If your user purchases an item and then loads your app onto another device and purchases the same item, it will not charge the user for the purchase. The answers to your questions are in the docs here:
http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction/Introduction.html
In particular, on the chapter on making a purchase the docs say:
If the user attempts to purchase a
nonconsumable item they have already
purchased, your application receives a
regular transaction for that item, not
a restore transaction. However, the
user is not charged again for that
product. Your application should treat
these transactions identically to
those of the original transaction.