How to redownload an in-App purchase application programmatically - iphone

I am able to implement in-App purchase successfully. I am also able to purchase a product through in - App purchase.I am storing purchase information in NSUserDefaluts.So if next time user tries to purchase same product again i am able to handle it locally.My problem is if a user deletes the application from the device,How do i handle the re-downloading of the application without charging for the same product again.I know that if an application has been deleted from the device having in App purchase it has to be downloaded again.Can anybody show a sample code for the same?
Thanks
Aditya
Hi
Thanks for a prompt reply.I have implemented the same as you have suggested.What i'm wondering is if i delete my app and install it again , i am asked to purchase it again.Do i have to pay again for the upgrade or is it handled from the apple server(i.e if i upgrade the same product again am i charged again?).Is there a way to know it was upgraded without asking to upgrade again?

The StoreKit api takes care of this and gives you, on request, a list of identifiers of the purchased items. Once you got those, it's up to you to re-download the products again(if not already bundled inside the app).
Excerpt from the StoreKit API help:
-(void)restoreCompletedTransactions
Asks the payment queue to restore previously completed purchases.
Your application calls this method to restore transactions that were previously finished so that you can process them again. For example, your application would use this to allow a user to unlock previously purchased content onto a new device.
When you create a new product to be sold in your store, you choose whether that product can be restored or not. See the In App Purchase Programming Guide for more information.
The payment queue will deliver a new transaction for each previously completed transaction that can be restored. Each transaction includes a copy of the original transaction.

////Comments pseudo code////
// Reinstall App:
// Restore already purchased transactions...
// Does the NSUserDefaults have the Purchase History??? -
// YES: Load the Table View of Items remaining for sale, Else -
// NO: Get the restoreCompletedTransactions list from Apple
// and create a container to hold previous transaction purchases.
// Fresh new App install:
// When a user makes the first IAP. Add it to the container and NSUserDefaults
// This container will be added to the NSUserDefaults when at least one purchase has been made.

Related

IOS buy, erase phone, detect previously purchased

I got most of IAP purchase working, using user defaults etc
But supposing a user buys an app, then erases or updates to a new phone.
Then reinstalls the app.
How do I detect that the user has previously purchased the app?
That is what restore functionality is for. See the Restore section of:
https://developer.apple.com/documentation/storekit/in-app_purchase/offering_completing_and_restoring_in-app_purchases
There are three ways:
If you store some purchase indicator in the app keychain, it will be present when the app is re-installed. If you are doing subscriptions also include an expiration date you can check if a subscription is possibly out of date.
If you send the app receipt up to Apple, it will always give you back the most current purchase data - which includes any prior purchases. So on first launch, always send the receipt up to Apple to see if you might want to automatically restore a purchase made previously. Note that sometimes an application receipt will not be present immediately after install (although it should always be there), which is why you also need to allow for option 3.
There is also a SKPaymentQueue’s restoreCompletedTransactions() call you can make to basically replay previous purchase transactions. This is something you should wire to a button somewhere in your UI - Apple requires that. It's not something you want to automatically call as it can prompt for the user to enter their iTunes account password, so you should not rely on this method to restore purchases automatically, but it is good to have in place as a backup for the user.

In-App purchase error - consumable you've already purchased this item, but it hasn't been downloaded

I am new in ios developement .I added an in-app purchase to my app, and I get the products data from the appstore successfully. the iap is a consumable.When I call the "addPayment:" method, I get the "Confirm your in-app purchase... [Environment: Sandbox]" question. I click Yes, and then I get a message which says:
"You've already purchased this but it hasn't been downloaded. Tap OK to download it now. [Environment: Sandbox]".would be very grateful if anyone had any ideas whats wrong?
This happens when the user is making a purchase on something they have already bought. Given that you are working with a consumable, you need to make sure you send a consumption/provisioning request to the Apple purchase servers when you give the user what they bought.
I was in a similar situation; resolved by restarting my iPhone (holding home/power buttons until the white-apple-logo-on-black-background appears).
Specifically, I had non-consumable purchase hosted on Apple's Server. Installed app to iphone5, made purchase. Deleted App, reinstalled in another build, and upon restorePreviouslyPurchasedTransactions, ITunesStore server didn't respond with my hosted-contact productIdentifier. (Although it did respond and restore some other test purchases that were non-hosted). Purchasing the hosted-content item again produced the error "You've already purchased this In-App Purchase but it hasn't been downloaded."; the alert was without an option to download. I found this site, http://support.nimblebit.com/customer/portal/articles/672080-problem-making-in-app-purchase-ios-os-x; restarted my device, and restore now recognizes the previous purchase.
I don't know exactly what triggered this problem, but note that I had been performing extensive testing on the downloading of this hosted-content item, debugging and ending the program before downloads were complete. I had code in place, upon startup, to spot unfinished transactions and finish them. So FinishTransaction was eventually called. At the time of this error, there were no outstanding transactions in the paymentQueue. My only guess is that abruptly killing an app at some point in the download process leaves a flag intact on the device that the item is being downloaded and so is not available to restore, which if this is the case, fortunately gets reset upon restarting the device.
Have you uploaded content?
This In-App Purchase is not currently available for testing in the sandbox environment because you have chosen to host your content with Apple, but have not delivered your content. Upload your content to test this In-App Purchase in sandbox.

Removing autorenewable subscriptions from iPhone App

I have an iPhone app that also features autorenewable products as an in-app purchase. The products are subscriptions to our service for up to 1 year in the future. We wanted to remove the whole in-app-purchase and autorenewable product from our app in the next version.
To accomplish this, we removed the signup option inside our app, so no new user should be able to sign up. Now we would like to disable the automatic renewal for all existing users.
How can I accomplish this? Is it sufficient to remove the in-app-products for our app inside iTunes Connect? Do the users get notified about this?
According to Apple (see WWDC 2011 Session 510, In App Purchases for iOS and OS X, at the 48:55 mark), the only things you can do as a developer to prevent subscriptions from auto-renewing are:
Raise the price.
Remove the auto-renewing IAP product from iTunes connect.
In both cases, notification emails are sent to subscribers, though not immediately. The talk says Apple checks 10 days before a (yearly) subscription renewal and sends email at that time. It's not documented anywhere, though, so I'd treat that as an implementation detail.
I've done the latter (removing the product) several times with my own (monthly) apps, and it seems to work as advertised.
One important note: if your app is a Newsstand app, it must have at least one auto-renewing subscription available. If you remove the last one, the app will be removed form the App Store. Users who have already purchased it will still be able to use it, and will be able to download copies from the "previously purchased" section of the app store, but no new copies will show up for purchase in the App Store proper.
It will depend on how you've implemented your system. Do you check receipts (and provide data/service) from your own server, or do it all within the app directly with Apple's servers?
In iTunes Connect you can remove a product from sale, effective immediately or at a future date. I suspect that's enough to stop a renewing subscription. (Remember you can test this with shortened timescales in the Sandbox.) But if not:
If you use your own server to validate receipts, go and give it an incorrect shared secret so that the verification step fails. That means the subscription validity will return as false (although for the 'wrong' reason) so your customers won't be able to renew.
If you do it within the app, generate a new shared secret so the one within your existing structures is incorrect. Then, as above.
If you can, I suggest sending a notification to your current users notifying them of the change, suggesting that they change, and letting them know it will 'fail' in the future but that's ok.

iOS in-app purchase keeping track of items purchased

I am new to the world of in-app purchase and I just watched the tutorial on iTunes about how to integrate it to my app. I am wondering how the developer would keep track of the items purchased WITHOUT having to verify the receipt. I thinking it would be nice if we could just store the purchased items in the app because then we would be able to identify items purchased without having internet connection.
What's the convention to do this? Is this a bad practice?
There are 2 way you can keep track of purchased items:
1 - Storage - Temporary / Permanent. Obviously Temporary storage doesn't protect you against deletion / device change. Permanent storage can be ensured if you store it in keychain or on your own server soon after purchase is successful.
2 - Apple's own API tells you - based on certain rules / condition.
Condition: If this is non-consumable purchase, and you try to purchase again.([SKPaymentQueue addPayment])
The response from itunes store will cause storekit to invoke updatedtransactions - with status - SKPaymentTransactionStateRestored. This simply means that product is already purchased, needs to be restored - so it is your responsibility to unlock it.
In short, it won't allow you to purchase again if it's nonconsumable purchase. Same must be true for subscriptions that haven't yet expired (not sure about it).
If you need step by step tutorial on how to integrate IAP - here is my own lecture series with SWIFT and Objective C. It also accompanies code sample.
This is a bad practice because, what happens when your user deletes and re-installs the app?
He won't have his purchased items anymore.
This tutorial is a very good one, it should point you in the right direction.
There should be an app or device feature that is allowed or is capable of recording and managing EVERY in-app purchase made through the Apple ID.
Problem is… The current setup of in-app purchases is not user friendly.
In short: Buying is your problem and recording your purchases is only a "convenient feature provided generously" by Apple Inc and app developers.
It shouldn't be like this though. Apple Inc and the app developers should consolidate user purchase info and make it transparent and easy to access/understand by the user.
This is the 21st century, after all.

testing an in app purchase?

i developed a application with in app purchases..when user buys the subscription it gets stored on my server..after testing it few times i deleted the data from server to test it again but when i buy it the sandbox environment says u
you already purchased this.TAP OK to download it again for free
also i have used this test account on my previous application?? does it means i will have to create a new test account for this application?? also by mistake i used this account on apple store..i read somewhere that doing this will make your test account invalid...is it true?? should i create a new account for it??
For first question -
Since you are using the non-consumable model "you already purchased this.TAP OK to download it again for free" This is the valid behavior... StoreKit maintains the information whether you have purchased the app already or not. If you purchased already you can download data for free.
In your code, you need to check whether the data is present in the server, if it is present then don't download else download it.
InAppPurchase products are tied with the application... If there are two applications like HDversion and liteVersion... You need to create different ProductID's for inAppPurchase.