1

Providing content for my non-consumable item is not happening immediately after purchase but on demand, whenever user would like to download content. Server has receipt validation routine as well, so I need to save receipt to later show to server for validation and content downloading.

I know that for iOS 7.0 I don't have to store receipt, because my iAP purchase receipts are located in app receipt itself, which is not hard to parse and get that information.

But for iOS 6.1 or earlier, can I save receipt from transaction in NSUserDefaults so later when I need to for instance download some content from self-hosted server, I can use that receipt to validate that particular download on server(and then server will send it to apple)? Is it legit, safe and common practice to store receipt?

Pablo
  • 28,133
  • 34
  • 125
  • 215

1 Answers1

2

I am pretty sure you already went through the following link

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Restoring.html#//apple_ref/doc/uid/TP40008267-CH8-SW9

Apart from that, I believe there is no problem in saving the transaction data. As for saving it in NSUserDefaults, there is one problem with that I can think of: If the user deletes and reinstalls the app, or buys a new phone, that data will not be stored on the device. Therefore saving the receipt in some way in YOUR self-hosted server would be better. For pre iOS7 devices, the link mentions this technique:

"If you need to support versions of iOS earlier than iOS 7, where the app receipt isn’t available, restore completed transactions instead."

  • So if someone will steal receipt from `NSUserDefaults`, he can send it to my server and download the content I was trying to secure. Or am I missing something? Also I don't understand the logic behind saving receipt in my server. Then what should I keep on device? what to send from device to server to make sure providing content is authenticated? I would appreciate your thoughts on above. – Pablo Feb 19 '14 at 14:17
  • I don't think anyone can actually steal a receipt because after all they are connected to that particular user's apple ID. Apart from that, because your non-consumable good is delivered on-demand, I am assuming you are holding each user's purchase data on your server as well. When you save the receipt in your server, whenever the user tries to actually download the content, you could check the receipt associated with that content as an added layer of security for you. That's the only reason I suggested saving it on your server. – Cömert Tülümen Feb 19 '14 at 14:42
  • Even if receipt is connected to Apple ID, having only receipt data(stolen using iFunbox, even if device is not jailbroken) will give bad guys an opportunity to send it to my server for authentication. No, I don't keep purchase information at all. My server is used only as proxy between device and Apple validation server. I understand what you mean, just check that the receipt is valid one by verifying purchase date and other fields. But still we come to first issue, when receipt itself is stolen. Downloadable content can be downloaded not even from iDevice, but from PC, using HTTP(S) request. – Pablo Feb 19 '14 at 14:53
  • You could try this. Store the transaction data in your `NSUserDefaults` but before storing it encrypt it with some method in your app. When you need to check for validity (within the app or the server), decrpyt it. So even if someone sees the transaction data using iFunbox etc... they will not see the actual receipt. – Cömert Tülümen Feb 19 '14 at 15:11
  • Yes, that was first I considered but based on what I read, Apple is very careful about cryptography in Apps and it may be reason to reject app only because of that(encryption is classified as munition). I always tried to avoid cryptography in my app. But overall I understand that receipt itself is not secure piece of data. It can go out of my device and easily be validated with my or Apple server. – Pablo Feb 19 '14 at 15:20
  • What about storing the receipt in the KeyChain? (e.g., see http://stackoverflow.com/questions/13488793/is-there-any-length-limit-of-string-stored-in-keychain) – Chris Prince Feb 20 '14 at 16:26