There's not much that app can do in the case that the in_app array is empty.
One verified reason for this issue occurring - the in-app purchase app is run on a jailbroken device - where the addPayment call is intercepted and the updatedTransaction delegate method is called back immediately with a state of SKPaymentTransactionStatePurchased. Since the applicationReceipt cannot be updated as it is cryptographically signed by Apple, the applicationReceipt is left as is - often in the same state it was installed with by the iTunes Store server - with an empty in_app array. The applicationReceipt can be validated which presents one case for the finding many of you report.
The presence of an empty in_app array indicates that the iTunes Store has not recorded an in-app purchase for the iTunes user account and application. When the app process validates the applicationReceipt and the in_app array is empty the application must not call finishTransaction, Doing so indicates that the application has validated the successful transaction indication. When the in_app array is empty, there is no indication that a purchase has taken place. In such case, the user is advised to contact Apple Care. the Apple Care representative can verify that a charge was made to the iTunes user account. They will also be able to tell that the application did not call finishTransaction.
I see this issue reported by developers to DTS. In some cases, there is the response that the typical customer would not be running the iAP app on a jailbroken device. My only suggestion is - submit a bug report to be investigated by the iTunes Store Server Engineers. The contents of the applicationReceipt are under the control of the iTunes Store Server. When a buy request is made and the transaction is successful, the applicationReceipt and the successful transaction notice are passed to the application in the same payload. The applicationReceipt is updated then the updatedTransaction delegate method is called with the state - SKPaymentTransactionStatePurchased. If the applicationReceipt's in_app array is empty, and assuming that the device is not jailbroken, then either the in_app array was empty when the receipt was returned to the app, or iOS did not update the receipt on the successful transaction. Either case or any other possibility is a bug report.
To submit a bug report, I suggest that you include the following information.
1. the application ID
2. the base64 encoded applicationReceipt such that anyone could use the curl command to send the receipt contents to the iTunes Store verifyReceipt server manually and see the validated contents.
I use -
user$ curl -d '{ "password":"yyyy" "receipt-data": "xxxx"}' https://buy.itunes.apple.com/verifyReceipt
where yyyy - is the shared secret - only needed if there is an auto-renewing subscription in-app purchase item in the receipt.
otherwise, one can use the command
user$ curl -d '{ "receipt-data": "xxxx"}' https://buy.itunes.apple.com/verifyReceipt
3. include the transactionID value in the bug report
4. Ideally it would help if you could include the iTunes User account name in the bug report associated with the purchase resulting in the applicationReceipt with the empty in_app array.
I would also file separate bug reports for each applicationReceipt which exhibits this behavior.
rich kubota - rkubota@apple.com
developer technical support CoreOS/Hardware/MFI