IOS Preventing Duplicate Purchases - ios

Let's say I have an iOS app that allows users to upload photos. I want to offer an in-app purchase that will perform processing on the image and store an 'upgraded' version of it.
Both the original and upgraded image will be associated with the user in my database.
I want to prevent the following scenario:
user buys the upgrade via in-app purchase
image processing server is unavailable
confused user quits the app and tries to purchase again
user is double charged and still hasn't received their processed image
Is there any way to totally prevent a repeat purchase? It seems like I can't simply make the 'upgrade' product a non-consumable. I would quickly reach the 10,000 sku limit. If I raised an alert warning "your purchase is being processed", it seems like my users could just ignore it, close the app, and try the purchase again.

Related

Inapp purchase restoring consumable products

i have uploaded an application which doesnot have webservices, in my application there is an option for user to buy a coin (consumable) using inapp purchases and use these coins to unlock new level. today apple rejected the application and send me following note:
**
Your app uses intermediary currency (coins) to purchase items that
function as non-consumable products (unlocking levels) but does not
include a restore mechanism. Users restore transactions to maintain
access to content that they’ve already purchased.Please modify your
app to include an optional user registration feature that allows users
to restore their purchases to all of their iOS devices. We recommend
indicating that account registration is necessary to restore
previously purchased In-App Purchase products, and providing a way for
users to register later if they wish to access this content in the
future.
**
how can i fix this, as mentioned earlier i dont have a webserver and i cannot use webservices, is there any way around to fix this and get application uploaded.
finally i fixed it by adding login screen in the application and storing user Object in parse.com and when i use inapp purchase i store coins count on Parse and retrieving it on application startup. thanks everyone.

Can Apple tell me what purchases a user has?

I'm aware of the restore functionality and have implemented it in my apps before, but still has holes in it.
I'm trying to display customized screens based on what apps the user have. Without user interaction, I want to be able to ask apple to retrieve me the in-app purchases that belong to that user for this app?
Other posts mention that I should always keep track of that via calling methods like:
NSUserDefaults.StandardUserDefaults.BoolForKey
But at the same time considers it insecure.
I am currently storing the info in DB. That's easy, but consider the following scenario:
User downloads the app. My DB records that user has 0 in-app purchases. The user later purchases 1 in-app purchase. My DB records that too.
User deletes the app for whatever reason
After a while, he re-downloads the app. My DB at this point starts a fresh and records that the user 0 purchases.
the user sees the in-app purchase (he already bought) and clicks on purchase again.
Here, my execution flow stops and apple picks up... Apple alerts the user that he has already bought the in-app and offers to get it for free.
That message is for the benefit for the user only, and my app is unaware of that. I haven't been able to find a call to apple asking what purchases a user had made for my app? I too, wouldn't want the user to pay again, but be able to always know what purchases he has made in the past at any given point. Why is that information so sealed at apple side? They alrady know the user has may app and I am only asking about in-app purchases in that app.
I am using Xamarin.
You need to refresh the receipt file and then scan through it. It will list all purchases the user has made inside that app, whatever device it was on. This code will let you parse the file and see the purchases made: https://github.com/rmaddy/VerifyStoreReceiptiOS
You could simply make your database store account information the user creates when they want to purchase something from your in-app extras. So in order to make that purchase they have to create a username and password for your app, thus giving you a way to keep track of who owns what in app content without having to ask apple.

Purchase non-consumable in app feature multiple times

not sure if this pass as a Stackoverflow question (close if not).
The problem we're facing at the moment is we have an app that we want to allow user to pay to unlock additional content space so they can create more content but be able to purchase multiple copies of that item without being charged twice unless they've exceeded what they've initially purchased.
So a concrete example is this:
Think of a item bag in World of Warcraft that lets user carry more items. (Our app isn't a game but it's the same concept). Users can buy many copies of the bag and at the same time, it doesn't matter if the user log into the app from their home computer or another computer, the bags are still tied to their account.
I'm aware that I have two options really:
Non-Cosumable In App Purchase
User buys the in app purchase item once but does not buy another copy. In other words, they can only ever have 1 copy of that item, not 10 or 20 copies (which our business logic requires in this case).
Consumable In App Purchase
Allows purchasing multiple copies of the item BUT they are non-transferable purchases. This would mean users would need to pay for the same item again even if they bought a new iPad, they can't transfer those "bags" to the new iPad or if they delete the app and reinstall the app, they would still need to pay for those items again.
Subscription based in app purchase doesn't exactly fit our model.
So is there a special type of non-consumable in app purchase but allows the user to buy multiple copies of that item/feature?
Additional Considerations
We do not have a third party server to track users and the number of copies of that item/feature they unlocked.
It also doesn't make sense to make a hundred copies of the in app purchase in iTunes Connect manually.
I think only making a consumable in app purchase is our only option. We're reluctant to force to user to have to pay for unlocking the same content twice but at the same time don't want users to be able to keep creating additional "bags" for free.
If user purchases a non-consumable purchase twice, I am sure Apple store has mechanism to prevent the purchase.
Instead, it would simply say: You have already purchased this product. It will be downloaded again. You will get all the delegates being called normally, and content delivery will happen as per what you have coded, but the customer will not be charged.
To avoid the payment flow, you can store the purchased item under itunes user's keychain, too.

Restore used to restore purchases for different accounts in ios app

I had implemented the restore button in our app but it is causing us a issue where if the member created Account A from our app and pays through the appstore. then if he creates another member in our app and restores the purchase by tapping the restore button and putting in his app id in this fashion using just one apple app id he is able to have multiple platinum members by buying just once fo one single member and restoring multiple times for diferent members.
This is for an upcoming website and app where i have a free/basic plan for anyone who registers and then an upgradable one time/lifetime platinum plan.
Now in my ios app I have received a message from Apple in the resolution center that "To restore previously purchased In-App Purchase products, it would be appropriate to provide a "Restore" button and initiate the restore process when the "Restore" button is tapped by the user."
Now if a member has upgraded from one device and is logging in from another ios device he will not be a basic member as he is already a Platinum member as per our database and hence will not see the buy/upgrade to platinum scene in our app.
Basically Can I avoid a rejection by removing the Restore button.
What will be my solution the the above case
I have selected a Non-Consumable Purchase
is platinum membership associated with a specific login to your server? If so, then on your server, when you process the in-app purchase receipt and associated it with a user account you record the receipt ID. Every time you process a receipt, you check and see if another user has already claimed that purchase first, and don't honor it if it's a repeat. Replay attacks are a pretty classic ploy and easily defeated if the purchase is tied to a user login...

How to 'fake' a restore in-app purchase for previous app users when moving from paid to free

Our app is moving from paid to free, and in the process, moving a key functionality from being included to activating via In-App purchase. Obviously, we don't want current users who paid for the app functionality to be charged again in the In-App purchase for functionality they already had. So on the update by the user, we want to 1) identify current users and 2) make it so they don't see the In-App purchase in the first place, sort of 'faking' the In-App purchase so that the app will appear to them exactly as it did before.
The app does not have a backend, so we have to determine current users from new by examining the saved user data fields for certain values. I do understand that if a previous user has deleted the app from their device that nothing can be done, and I don't mind charging them for the In-App purchase, since they never used the app anyway.
But for those current users who update and assuming we can examine the saved user data and determine that they are current users, what would be a good way to bypass the In-App purchase and make the app look like they already got it, when in fact they never paid for it? Thanks!
Here's what I would do - keep in mind this will take some time:
Set up a server (I prefer EC2) with mySQL on it. Plenty of tutorials about this.
Submit an update to your app that sends the user's UUID to your server.
Wait. This is the hardest part. You'll need to wait until satisfactory majority has updated to your app. That majority percentage is up to you to figure out. It could take months for this to happen.
Make your new, free, app send the UUID to the server.
Check to see if the UUID is in the DB.
If it is, set whatever you would have set when an in-app purchase was made to true.
You have several options:
Free in-app purchase for a limited time:
You would create a free tier in-app purchase content and release an update that somehow makes the user sign up for it. This way, when your user switches devices they can restore the purchase and regain the functionality.
Wait for a period so most people use the in-app purchase content
Change the tiers and release your app as free
Dual versions
Make a demo version of your app. Note this can be rejected by Apple.
Create a file in the filesystem
Make a file in the filesystem and save into iCloud. The app will check for the file and thats how you would determine if the user has paid for the app (or should buy the in-app purchase).
iCloud will synchronise the file between user's devices and it will make sure that whatever device the user uses the app will see the user as 'paid'.
I hope this helps, currently having this problem myself.

Resources