I have an app that has been using the now-deprecated pre-iOS 7 method of implementing IAP by looking at the transactionReceipt
contained in the transactions that come to our transaction queue observer. That was working great. The new implementation of the observer just keeps track of whether any new transactions are being reported (state is SKPaymentTransactionStatePurchased
) and if any are found in the queue, it grabs the application receipt (not the transactionReceipt
) and sends that to the server.
Up until today, I found that the new transaction was always in the "in_app" field in the decrypted app receipt I get back from Apple. Today I'm testing subscriptions (which is working as far as I can tell) but noticed that when I order a non-subscription, non-consumable product, the transaction for it is not present in the "in_app" array in the app receipt until I order another non-subscription, non-consumable product. At that point I see the previously ordered product in the "in_app" array, but not the newly ordered one.
Both the previously purchased and newly purchased items are present in the "latest_receipt_info" array. I would just use that array instead of "in_app", but I hadn't started seeing "latest_receipt_info" until I started testing subscriptions, so I don't think it's always there.
Question: Am I missing a step? Should I be refreshing my app receipt in my transaction queue observer before using it? If I do, won't it prompt the user for their Apple ID credentials kind of inexplicably (they just placed an order and entered their credentials; I don't want them to have to do that again)?
I don't think you are missing a step. I do think it is strange that the consumable purchase isn't showing up immediately on the on disk receipt, but it is possible that this is normal behavior, I'm not sure.
You could always trigger a receipt refresh. If the user just purchased a non-consumable item, and went through the purchase flow they shouldn't see a another login pop-up.
The other alternative is to use the latest_receipt_info
on the server side as your source of truth. This field is only present if you send your iTunes Connect App-Specific Share Secret in the password
field of the request JSON.
Personally, I would use the latest_receipt_info
.