Using the links at the bottom of my post I have built a basic in app purchase for my OSX app. Basically what I do is show a UI for the user to select that they want to purchase the upgrade (which just adds more content), then I start the transaction with a call to addPayment:, I receive the transaction in paymentQueue:updatedTransactions: and if it is purchased transaction I send it along to a method that provides the content and then calls finishTransaction:.
This all works in a single use of the app but then when I fire up the up again I would have to do the purchase again to reenable those features (this makes sense because I am not storing the upgrade data anywhere), but I am wondering what is the best way to store the data about the purchase to prevent the user from being asked to buy again after they have already purchased. Is this somehow suposed to be done through receipt validation? None of the documentation I found talked much about this.
Helpful links:
In app Purchase walkthrough
Apple's in app purchase documentation
EDIT:
My app is really just trying to enable built in content through the in app purchase so it seems that using property list is the what Apple would suggest:
Apple recommends using a property list (plist) to track product identifiers for your built-in features. Content-driven applications can use this to add new content without modifying the source for your application.
But I wonder how can I edit a plist file if it is stored in the bundle (this was cause the sandboxing to think the app had been compromised). Do you store the preferences plist in the container? The link apple gives that is supposed to discuss more about changing application preferences links to an IOS page and the only thing on that page about preferences is in the settings bundle. Implementing Application Preferences”
Is the application preferences method only to be used on IOS? Is the correct place to put the upgrade data in the settings bundle?
For purchases that enable additional content, Apple recommends using a server-based receipt validation setup as noted here:
http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/APIOverview/OverviewoftheStoreKitAPI.html#//apple_ref/doc/uid/TP40008267-CH100-SW12
"Apple recommends you retrieve product identifiers from your server, rather than including them in a property list. This gives you the flexibility to add new products without updating your application.
In the server model, your application retrieves the signed receipt associated with a transaction and sends it to your server. Your server can then validate the receipt and decode it to determine which content to deliver to your application. This process is covered in detail in “Verifying Store Receipts.”
The server model has additional security and reliability concerns. You should test the entire environment for security threats. Secure Coding Guide provides additional recommendations.
Although non-consumable products may be recovered using the built-in capabilities of Store Kit, non-renewing subscriptions must be restored by your server. You are responsible for recording information about non-renewing subscriptions and restoring them to users. Optionally, consumable products could also be tracked by your server. For example, if your consumable product is a service provided by your server, you may want the user to retrieve the results of that request on multiple devices."
You can create a UUID for the user and store it in the app's preferences. The advantage of doing this is that the uuid is then backed up when the user backs up or restores their device. It can also easily be synced across iCloud if it's a universal app. The server can then link that UUID to the purchases made and deliver the content that was purchased by that user. You may want to include additional security protocols to reduce any UUID spoofing by unscrupulous users, but unless the content is extremely valuable, that is usually more effort than it's worth IMHO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With