ios in app purchases - validating receipt data - ios

i am implementing in app purchases into a iOS application. I am using the server model (so all the in app items are stored on my server). The purchase model works like this:
user buys a item in the application
application sends the receipt-data to my server (receipt-data is a digitally signed chunk of data)
the server then sends a verification to the apple server
if the verification is successful the server returns data about the transaction
I've been searching through the documentation but i cant answer this questions:
can i validate that the receipt-data came from the apple store (checking the signiture or do i have to come up with a mechanism for that)?
if a user buys a item that was removed from the store (due to an old cache) can i reject the purchase?
If anyone has any experience with this i would appreciate the help.

You can validate the receipt-data come from the apple store by following Local validation.
If user buy a removed item. It's mean product_id does not exist in Itune. Transaction will be fail. You should update Product Request, when user use IAP.

Related

iOS In App Purchase Receipt Duplicate Management

When building In App Purchases into an iOS app, Apple gives you access to a receipt that you can send to your server to view all In App Purchase transactions for that given iTunes user related to your application.
If in my application I require users to login or create an account through my system before making a purchase, how can I guarantee that iTunes receipt will not be duplicated?
For example, if a user makes a purchase, the application sends the user ID, and iTunes receipt to my server. The server then stores that receipt along with the user ID in a database. The next time the server wants to check the users purchases we can retrieve all the receipts for that given user ID out of the database and run checks on it.
But if the user logs out and logs in as a different user and makes another purchase the receipt will be sent to the server again, with a different user ID. Effectively, allowing 1 purchase to be used on unlimited user accounts.
Due to the fact that the receipts change over time (auto renewing subscriptions, etc), I don't think it's safe to rely on the receipt being the same every time it's sent to my server and using the receipt data as a unique identifier.
I also considered storing the original_transaction_id for one of the transactions, but I don't think that would work since an application might have multiple non-consumable items, or multiple subscriptions, therefor there might be multiple completely valid original_transaction_id's in one receipt. So it doesn't really associate that receipt, but just the transaction.
Ideally, I'd like a system where when a user logs out, and logs in (as a different user or same), the application will send the receipt to the server, and dissociate any of the same receipts for all existing users, and link this new receipt to the user that logged in. Problem is, it doesn't look like there is any type of unique identifier for a given receipt that I can use to check for duplicate receipts in my system.
What is the best way to detect duplicate receipts sent to my server (so I can dissociate the old receipts accordingly)?
PS. I think this system is most important for subscriptions, and non-consumable items. For consumable items it will always have to be linked to 1 specific user, and I can just store the transaction_id and original_transaction_id for that consumable item to ensure it doesn't get duplicated.

In app purchase - Subscription - not based on Apple Id

I understand that If a user buy something using in app purchase, it should reflect in all the devices owned by the user ( based on logged in apple id ).
But in my case I need to handle it with "our own username and not apple id". That is if user logged in to our application in multiple device, We need to handle subscription all our own.
Just to clarify, even if user logged in to two devices with same apple id but different user in our application, only the username who actually bought our subscription should get the extended access.
I believed that non-renewable subscription is what We need, but on reading a bit, I think such a subscription should reflect in all devices registered by same apple id.
So it would be great if someone could help me to select which kind of in app purchase should i choose for this scenario.
Any help appreciated. Thanks.
The kind of in app purchase for this would be preferable is non consumable. In this case user don't have to buy the product again and again. Regarding your question with your own username you can maintain the record of purchase for single user in your local server. For that what you can do is while verifying the transaction receipt from your local server which you will get on every successful transaction from apple in app purchase server. For verifying the receipt you have to send the receipt to you local server in base64 encoded format then your local server will connect to the apple server you local server will verify the receipt while sending the receipt to your local server send the session id of the user to your local server if the verification of the receipt is successful then you local server will store the purchase information in local data base. If user will login in the second device also you local server will know that this user have purchase this many item and you can sink the data in all the device in which user have logged in.

Is it possible to get a list of validated receipt data from iTunes Connect?

After my new iOS App was approved last friday, today I recognized that I mistakenly rolled back an SVN change and therefor all In-App-Purchases that were made during the weekend were validated in the wrong place (Sandbox URL). (Error code 21008: This receipt is a production receipt, but it was sent to the sandbox server.)
Now, I can see in iTunes connect that there were a bunch of successful purchases. But the problem is that - since validation failed (due to the wrong URL) - I did not enabled the special features within the App for those users on the server side.
I tried the whole day to find out which of the app's users made a purchase, so that I can enable the extra features that the users paid for now (and to send them my apologize via email).
But since the receipt data is send via POST requests, I was not able to get this info from my server's log files. And in iTunes Connect I was not able to find some report(s) that include the receipt data for successful purchases.
The last option would be to enable the extra features within the app for all users who logged in during the weekend. However, I'd prefer to get my hands on the receipt data.
Is that possible at all? Does Apple grant access to this data? Any idea(s)?

Deliver Inapp Purchases (Serverside)

My app provides extra content in its inapp store (non-consumables). The products (external files) are all stored on my server, so I can dynamically add new. Once the user has bought an item, my server verifies it and remembers the transaction data.
How can I now deliver my content? Let's say the user buys it, exits the app, and comes back later to display the content. Since the data is on the server, my app now needs to query the server once again to get the content. How can the server verify that the client making the query is a valid buyer of the content? Should I save something (like the transaction ID) on the app and then verify through this? Or are there better approaches?
I chose to save the transaction ID and transaction date of a bought product on the local device. The server verifies through this. The ID and date are stored in the keychain, to give them some protection from being read by a 3rd party.
If someone has better suggestions, he/she can still post it.

How to verify a iTunes Store receipt for in-app purchase

First of all, I am not talking about calling https://buy.itunes.apple.com/verifyReceipt/, instead, what I am asking is how to verify an iTuneStore receipt from one of our users.
We have in-app purchase in our app, and we verify in-game receipts on our server before we grant the product. However, this particular user claimed that he got charged by iTunes store but did not get the purchased products, and sent us his receipt as a proof.
So I am wondering if there is anyway we can verify such a receipt. There is "receipt no" and "order number" in the iTunes Store receipt, however, with in-game receipt verification we get transaction_id, and these numbers are quite different. Any idea?
Thanks in advance.
You should contact Apple's developer support. I doubt there is a way to verify it by yourself if you can't find a respective transaction in your own systems.
There is no manual way to do this, unless you can somehow get the receipt data from his device, in which case you can use Apple's API that you mentioned to verify his claims. If what he says is true then suggest him to claim a refund and then re-purchase. He should be able to do this here.
Now, the Lookup Order ID of App Store Server API could get a customer’s in-app purchases from a receipt using the order ID.
GET https://api.storekit.itunes.apple.com/inApps/v1/lookup/{orderId}
You could find the corresponding transactionId from this API response JWSTransactionDecodedPayload
For how to do the Lookup Order ID request, please refer to https://github.com/richzw/appstore#look-up-order-id
There is source code at https://github.com/roddi/ValidateStoreReceipt/blob/master/validatereceipt.m which will validate a receipt, and let you parse it and dump out all the transactions.
If the IAP transaction is there you would see it.
You'd have to write a special-purpose iOS app which uses that code and feed it the receipt. It seems like a lot of work.
I am not talking about calling https://buy.itunes.apple.com/verifyReceipt/
Actually u have online receipt verification tool, accessible by link above.
There is no better way to verify Your receipt. Offline verification is possible, but if even it succeeded, nobody can give 100% warranty that Your receipt is valid(maybe just same signature, but still fake one).
Apple processing every purchase on its servers and if it successful, receipt saved to database. If u want to check receipt u must access to that database and request for Your receipt. So You have a tool, but don't want to use it? No reliable way then.

Resources