switching from auto-renewable to renewable subscription - ios

My client has an app in the App Store that uses the auto-renew subscription type. Upon resubmitting the app it was rejected because they claimed they don't have periodic content (even though they do... but this problem seems to be ubiquitous currently). I was wondering what the best approach is to deal with non-renewing subscriptions. Specifically issues dealing with:
Losing your device and restoring your subscription
Restoring your subscription to multiple devices (as mandated by Apple)
Preventing users from abusing the system.
What I came up with so far is the following:
When a user purchases a 1 month subscription this information is stored locally (say in NSUserDefaults). Also, a unique ID is generated and sent to my clients server. When the subscription ends users are asked whether they want to be directed to the purchase screen. If users wishes to save the subscription in case they need to restore they device, or in case they lose their device, they can opt to have the unique identifier sent to their email address (which they are prompted to enter, indicating that this information will not be used). The app has an place to enter this ID. It will retrieve the subscription information from the server and again store this in the NSUserDefaults. Each time a restore is done, a counter is increased. When it has reached say 5, the user can no longer restore. The same principle described above works in the case of sharing subscriptions over multiple devices. Does this seem like a reasonable solution (and one that Apple will accept)?
Thanks for your time!

Why don't you want to use Apple's restoreCompletedTransactions? It just provides you with information about ALL the previous purchases, on any device, at any time.
http://developer.apple.com/library/mac/#documentation/StoreKit/Reference/SKPaymentQueue_Class/Reference/Reference.html#//apple_ref/occ/instm/SKPaymentQueue/restoreCompletedTransactions

Related

Prevent iOS in app purchase being shared between devices

I intend my app to gain access to my server after the in-app purchase is complete. This access requires real work, and data & traffic ($$).
A typical client might own anywhere up to a couple of hundred devices (and I assume on one account, for their simplicity).
Thus I only get the one payment across many, many devices interacting with the server.
I'm not trying to be stingy - but can I prevent multiple devices sharing the same purchase (in my case server access)?
Or do I implement another method for selling access?
You'll have to implement another method. Apple's guide explicitly states that:
Users can restore products that they previously purchased—for example, to bring content they’ve already paid for onto their new phone.
If the same iTunes account is associated with more than one device then Apple requires any purchases to be available on all those devices.
#Tommy is correct - regarding non-consumable IAPs. However, you could implement a non-recurring subscription in-app purchase instead and give each device a unique identifier. When the user attempts to access the server, you could see if that identifier is in your database (if the user has purchased the IAP), and determine whether or not they need to purchase a subscription. Even though you may not want a subscription-based service, you could probably make a membership for a very long period of time like 10 years (it's not required to be selected in iTunes Connect) and handle it that way. Only issue is that you need to figure out a way to give each device a unique ID that won't change.
Further to the #Tommy answer, in the February 3, 2014 version of Apple's Getting Started with In-App Purchase on iOS and OS X it says:
There are a handful of important guidelines to keep in mind as you design your application:
- You must make your In-App Purchase items available to all of the devices registered to a user
and
Users view the items they purchase as theirs to keep and permanent. Therefore be sure
purchased items are available in all instances of your app running on all the devices the user
owns, even after your app is deleted from a device, reinstalled, or downloaded to a new device.
and
For Non-Renewing Subscriptions, [blah, blah, blah]..
Additionally, your application must include a mechanism to deliver the purchased Non-
Renewing Subscription In App Purchase to all iOS devices owned by a single user.
Looks like there is no way to restrict items to a single device :(

iOS App rejected due to wrong purchase type

I am stuck with one of the in-app purchase rejection issue in my app and need some help on this.
What this in-app for?
In our app we have options for user to become premium user. A user can become premium user to enjoy some benefits and it is tied to time. There are two in-app products which defines them
One month premium service.
One year premium service.
Since these are time based service, user expects these service should be made available for that user once he/she purchase the product for the specified time, from all his/her other devices. In order to track whether the user is premium service user or not, once the purchase is done, the app writes a entry in server about premium service. So when user uses other device and logs in, he/she can enjoy the premium service without any issues. For this reason I created the above mentioned products as "consumable", thinking that it is controlled by our server there will be no issues. But apple came back with rejection and asked me to change the products to "non-renewing subscription".
Here is what apple says about this
We found that the Purchasability Type for one or more of your In App Purchase products was inappropriately set, which is not in compliance with the App Store Review Guidelines.
"Premium account service for 1 month and 1 year" IAPs are set to Consumable.
However, based on product functionality, it would be more appropriate to use the Non-Renewable Subscription In App Purchase type because the service offered by your application requires the user to make an advance payment to access the content or receive the service.
The Purchasability type cannot be changed once an In App Purchase product has been created. Therefore, you will need to create a new In App Purchase product with the correct Purchasability Type. To create a new In App Purchase in iTunes Connect, go to Manage Your In App Purchases, select your app, and click "Create New". The current product will show in iTunes Connect as "Rejected".
Non-Renewable Subscription content must be made available to all iOS devices owned by a single user, as indicated in Guideline 11.6 of the App Store Review Guidelines:
11.6 Content subscriptions using IAP must last a minimum of 7 days and be available to the user from all of their iOS devices
If you choose to use user registration to meet this requirement, please keep in mind that it is not appropriate to require user registration. Such user registration must be made optional. It would be appropriate to make it clear to the user that only by registering will they be able to access the content from all of their iOS devices; and to provide them a way to register later, if they wish to access the content on their other iOS devices at a future time.
For more information about Purchasability Type, please to refer to the iTunes Connect Developer Guide.
Now I have created new in-app products which are non-renewing. But this works the same way as I mentioned earlier, i.e. the server keeps track of whether user is premium user or not, expiry date. When user goes to other device and does login, the app comes to know whether user is premium or not and based on that app works.
But I have couple of questions on this,
Should I need to provide the "Restore" button in the app? If so what is the purpose and how it works?
Since the user can access this service only after doing login to the app (it is different from app store account). Will these two logins make any issue?
Please share your valuable inputs.
It is highly unlikely that the user will end up in a situation where they won't be able to use your app unless they restore their purchases, however it is still possible. Imagine your server goes down for a day and during that day some user purchases a subscription, gets a new iPhone, installs your app on the new device and then wipes their old iPhone. I can think of a couple of other, equally unlikely, but still possible situations (Apple receipt validation server going down, etc) in which the purchase receipt will get lost in transit. It's best to provide the button, and if Apple thinks that you need it in your app, you will have a hard time convincing them otherwise.
If by "two logins" you mean user having to log in to your system and then log in to the App Store to purchase the subscription, that should not be a problem.
I recommend you make the changes Apple requested to the Purchasability Type and then re-submit. If you need to clarify a lack of a restore button put it in the notes for the reviewer

how to prevent users sharing their apple id for in-app-purchase

I am implementing an App with in app purchase of type:non-renewing subscriptions.
according to apple documents:
If your app uses non-renewing subscriptions, your app is responsible for the restoration process.
FROM HERE
My question is, if the restoring is mandatory by apple, how to prevent thousands of users sharing one apple account with only one description?
For example, if in my app, you pay $0.99 that can use this app for 10 days, from apple's requirements, the user must be able to use app within 10 days on any his/her devices, with simply enter the credentials. However, if the user set a simple account credentials and share it with 100 people, then, the 100 people don't have to buy the subscription anymore and can use the app free during the 10 days.
Some people keep assert that people won't share their account... how do you know that? i saw people register some apple id exclusive for sharing apps and games, and only need to pay once.
Besides, i don't implement my own server and my App don't need one. Is there a way to prevent this?
Thanks in advance
Since non-renewing subscriptions seem to require the app (developer) to use a separate (non-Apple) server to deal with the restore process (for example, see How to support multiple devices with non-renewing In-App Purchase?), why not have that server keep track of the number of restores per "user"? Then you could impose a maximum number of restores per "user". Each installed app that has made a purchase could have its own unique_token (for example, see app rejected.how to track user non-renewing subscription). The user would then have to have a username/password, which would be associated with the unique_token, in order to do a restore (for example, see Restore transactions for Non-renewing subscriptions without registration; and see Registration should be always optional on non-renewing subscription?).

iOS Non-Renewable IAP - Limit number of devices

We are looking at using consumable (non-renewable) IAP for subscriptions for our app after being rejected for auto-renewable subscriptions. I've read through many posts pertaining to this, but haven't seen any discussion on limiting the number of iOS devices a user can use the consumable on or "restore" to.
The main concept seems to be, let user create an account (optionally) on your server, and allow them to enter account info to restore/share across multiple devices.
My primary question is, how can we limit the number of devices a user is allowed to use the subscription on, and the number of devices a user is allowed to "restore" to, and still meet Apple's requirements for restoring purchases?
If we setup a server, and allow the user to optionally create an account to store the receipt information, how can we keep that user from sharing their login information with anyone if we have no way to uniquely track the number of unique devices that are using the account? (perhaps I'm wrong here, but with the deprecation of UUID and the possibility of identifierForAdvertising changing if the app is deleted and re-installed, there is no way to cache a unique device to determine how many devices have used the subscription, correct?)
I've contemplated storing an auth token in the user's iCloud, but from my understanding, there is no upper limit on how many devices can share an iCloud account.
I'm sure I'm not the first to run into this problem, how is everyone solving this?
Thanks -
Matt
Consumable items are intended to be device-sepcific. And once consumed, the user must purchase it again, even if it were purchased previously on the given device.
Apple doesn't officially want you to limit the number of devices for subscriptions or non-consumables - they want your IAP subscriptions and non-consumables to be available on ALL of a user's devices. See: https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/StoreKitGuide/APIOverview/OverviewoftheStoreKitAPI.html
Why not use iCloud to transfer an IAP non-renewable-subscription between devices? That limits it to just the user's device set. Why do you care if they have 2 devices or 10? I bet that users don't typically share their apple-id's outside of their immediate family.

Differentiating between initial buy and free "re-buy" in StoreKit/In-App Purchase

From the StoreKit guide:
If the user attempts to purchase a nonconsumable product or a renewable subscription 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.
This presents a huge problem in an app I am working on. We have licensed a large body of content from a publisher for sale through in-app purchase. They require that every time we sell a piece of this content (i.e. user pays us), our server calls an API on their servers to report the transaction. This is for accounting purposes and ultimately used to determine how much we pay them at the end of the month, per our agreement with them.
I have read several suggestions on SO and elsewhere about calling restoreCompletedTransactions rather frequently and maintaining a local understanding, on the device, of what the user has already purchased so they cannot be allowed to purchase it again. This to me seems like something that should be able to be implemented on the server side. However, the receipts that we are getting back from the Apple servers are exactly the same for a buy and a re-buy, as promised by the StoreKit guide.
If payment callbacks from StoreKit cannot be trusted as a valid accounting mechanism in this kind of situation ("you got paid" vs. "you didn't get paid"), what other real-time insights into transaction traffic are available? I don't think the publisher we are working with is going to be happy if we tell them we have to wait 45 days after the end of the month to get the REAL paid dollar amount out of iTunes Connect.
I have recently looked into the same problem. In my case, I wanted to implement accurate revenue tracking using Mobile App Tracking to track revenue generated from different customer acquisition campaigns.
Fortunately enough, there is a way to do it. It should be noted that SKPaymentTransactionStatePurchased vs. SKPaymentTransactionStateRestored solely depends on the initating action, e.g. whether you initiated a restore or a (re-)purchase, so that doesn't work.
What does work instead is checking for SKPaymentTransaction.originalTransaction which will be != nil for restores and re-purchases. The latter is unfortunately undefined behavior (docs). I'd consider a null check fair enough though.
Another option is to validate the transaction-receipt of transactions with SKPaymentTransactionStatePurchased and check that the original_transaction_id property in the returned, validated receipt matches the transaction_id.
The bad news is: In the current iOS version (4.3.x) there's no way to distinguish between a buy and a re-buy of non-consumable products.
To ease the situation I would recommend two things:
First
After a successful purchase, store the product identifier of the purchased product in the NSUserDefaults on the device. You can then hide the already purchased products from the user and thus handle a re-buy situation.
The NSUserDefaults are backed up by iTunes when the user synchronizes his device. So your stored purchase information is not lost when the user gets a new device.
Second
Store the receipt data together with the device ID on your server. Analyze the receipt's product identifier and the device ID.
If you receive another receipt with the same product identifier and device ID combination, then assume a re-buy. At least this would allow you to cover most of the re-buy cases.
Assuming that an ordinary iPhone user switches his device every 1-2 years, you will at least cover most of the re-buy cases and maybe apple will fix this in the future.
I have one solution,
Configure the product as consumable.
this will solve the problem - (They require that every time we sell a piece of this content (i.e. user pays us)).
Next you need to implement a logic in product buy option. It is in a way that once the user purchase a product the buy option need to remove otherwise the user may happendly go purchase and lost is cash once again for same product in same device.
you can use NSUserdefaults for this purpose.
thanks,

Resources