I'm trying to add purchases to my application. But I don't know how to check if purchase is already bought. As far as I understand when somebody bought purchase I need to store this into UserDefaults or KeyChain and then check if it is already there (it mean that this purchase is already bought). But what about when user bought this purchase prom another device?
I have code that give me information about all purchases in iTunes.
func productsRequest(request: SKProductsRequest!, didReceiveResponse response: SKProductsResponse!) {
}
Response object have two variables: "products" and "invalidProductIdentifiers". But as I understand products contain all products from iTunes and invalidProductIdentifiers contain all identifiers that I was asking to check for but Apple can't recognise them. So where I can check if purchase was already bought or not.
Assuming iOS 7+, you should be validating the receipt, ala A complete solution to LOCALLY validate an in-app receipts and bundle receipts on iOS 7 to determine what's purchased, what's valid (in the case of subscriptions or consumables), and as noted in the other comment, offer a "Restore Purchases" UI element which allows users to cleanly propagate sharable purchases to a newly restored/acquired device.
AFA the response object, that is catalog (purchasable items) information, not info on what has been purchased. In order to have IAP work correctly, assets are to be approved by Apple similarly to the app itself as well as being under "ready for sale" control of your own in iTunes Connect. For that pass, you send Apple a complete list of the times you want to offer and Apple returns to you the list split into the "if your user tries to buy this, they will succeed" (the products) and "if your user tries to buy this, they will fail" (the invalidProductIdentifiers).
When you're testing with sandbox/iTunes Connect Test users, your products do not need to be approved by Apple, but for production code they do.
Related
My problem is, the users cannot get the non-consumable item by redeeming the code.
I can confirm the non-consumable items can be bought correctly.
I used the app receipt to check whether the user owns it. I'll find through all the products to see if there's one the product id is matching.
I cannot find any useful docs to debug the redeeming process. I don't even know if there should be a callback when the app starts. Like the transactions are not completed.
How is redeeming handled behind the scene?
If the app is open after I redeemed a code, how should the app know the user 'bought' the item? How should I know when to send them the contents?
If the users try to buy the item they redeemed, they are told they can get it for free, and I see the purchase succeed callback. But then I check app receipt, the product still not exists. I got these logs from the users.
By the way I'm using in_app_purchase plugin from Flutter. And for checking the app receipt I'm using https://github.com/robotmedia/RMStore.
Products redeemed with a promo code will appear on the receipt just as a purchased product would - you won't be able to differentiate from the receipt a purchase vs promo code.
There isn't a callback on the device for promos specifically, if you refresh the receipt or the user restores transactions you should see the product in the receipt.
To be clear on my question, I am in the process of implementing a iOS IAP receipt validation (consumables) and I was not expecting more then just the item(s) the user 'currently' purchased in the 'current' transaction.
So lets say the user purchases one (1) $0.99USD item that gets them 100 coins I am expecting to see in the receipt using my validation code the one (1) transation detailing the one (1) product they purchased not an array of items from previous purchases which I found out that:
With iOS 7, Apple started using something they call the “Grand Unified Receipt”. Apps retain one receipt that contains information about the purchase of the app itself, as well as IAPs.
So my question is if anyone else has an issue with the receipt format and how have everyone been validating the purchases for consumables when the entire user purchase history is always present?
I am implementing In-App Purchase in my app and test around the existing apps to get some ideas. But I found a scenario which I am quite confused on it.
I have installed an iOS app and purchased the particular levels. Later I uninstall this app, sign out from existing iTunes store account and sign in again with another apple id, then reinstall that app again (same app). Here i can again i need to purchase the particular levels.But my doubt is In-App purchase method we can use based on the purchase Apple ID or Device token ?
If the user can purchased with Apple ID ,then the user can login with another device they no need to purchased again but one user can purchase app and user can login to another users Devices is the one problem..!why because another users no need to purchase.
And if we set the Device token, based on the in-app purchase user can only login that device only ,they can't login another devices with same Apple ID,here it is a problem.
I am quite confused on it... so is the purchased items tied on device if we use multiple apple ids on same device?
I understand that I can restore my purchased items on different devices using same apple id. But how about multiple apple id on multiple devices? If I have 2 apple id associated on an device, I use one of them purchased item, but later I use these 2 apple id login to another device, am I still need to pay again to download items I have purchased on previous device?
Please let me know if my questions are not clear... I hope someone can give some idea on sharing purchased items against different devices and apple ids.And which one use the in-app purchase.
Any suggestions and comments are welcome. Thanks a lot.
IAPs fall into two categories - consumable, and non-consumable.
Non-consumable purchases (purchase level 10-15 of a game, upgrade to pro, etc) are synced across devices by the system, and are restored by the system. They are tied to the Apple ID.
Consumable purchases (purchase 5 gold coins) are NOT synced or restored. Your application needs to remember that the purchase has been made, and store information about that so that a backup and restore correctly restores the user's state. If the user uninstalls and then reinstalls, they have lost any previous consumable purchases (but they will retain all non-consumable purchases, and your application can query for these). You can, of course, sync all information about consumable purchases to your own server, but you would then need to have the user create an account with you. This would allow you to sync consumables between devices.
The Device ID (which you can't get, anyway) has no relevance.
See https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Products.html for more discussion.
If the IAPs are non-consumables (or autorenewables) they can be 'restored' by the user (i.e. the app would execute a restoreCompletedTransactions or refreshReceipt). I believe that the username/password log-in required to restoreCompletedTransactions (or refreshReceipt) must be the same username/password as the person who downloaded the app onto the device. Given that requirement, I still believe that a single 'purchaser' can share their single purchase of a non-consumable IAP on many devices.
I am working with InApp purchase, so I have implemented a working model,I have referred this
link http://xcodenoobies.blogspot.in/2012/04/implementing-inapp-purchase-in-xcode.html.
Here when the user purchases an item I store some value in KeyChain and I cross check with this value to confirm that the user has purchased the item and if not I will ask the user to purchase the item.
This works, but I have 4 products available for purchase, which can be purchased individually, So I thought of creating different instances of KeyChain and storing different passwords for these 4 products and cross check, but keyChain can only save one username and password.
So I want to know what can be the alternative for this.Also NSUserdefaults will not work, because it is tied to the App bundle and whenever user deletes the app, the data is lost and so he will be asked to purchase again.
Regards
Ranjit
If you're adding a restorable in-app purchase (non-renewable subscription, free subscription or non-consumable product), then the Store Kit API already provides the "restore transaction" functionality for you: http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/MakingaPurchase/MakingaPurchase.html
In your UI, you need add a "Restore purchases" button to your product screen that calls the restoreCompletedTransactions method. This is important because Apple might reject your app if you don't provide this button.
I have an iPhone app with an in-app purchase and I want to be able to release the app independently from it (the in-app purchase). In other words, there could be times where the in-app purchase is "waiting for review" state and shouldn't be displayed by the app.
If I understand correctly, in this situation, the SKProductsResponse object (returned by the Apple App Store in response to a request for information about a list of products) will have the particular product listed under the invalidProductIdentifiers array. Thus, before displaying the in-app purchase, I could inspect the array to check for the existence of the product. This should still allow Apple to test the in-app purchase with the released version of my app since I assume their testing is done in a sandbox where all the in-app purchases are valid.
Is this correct? Should I follow a different approach?
You describe the proper workflow for displaying IAP content to the user. Put up a modal dialog or a UIActivityIndicator telling the customer that IAP content is being downloaded. Use the productIdentifiers that are returned to populate your store gui.
I discourage you from hard coding in a specific view for a specific in app purchase, and then attempting to populate that view. You can do that if you're smart about it and check for valid content ahead of time, but checking after the customer is already expecting to see something can end with both Apple review and your customer thinking your app is broken.
The least pretty implementation would be a tableView displaying the returned productIdentifiers and their respective prices, allowing the customer to pick from a familiar list.