When I hear reports of users being charged, but the application not providing content, this tells me that the app is being called via the updatedTransactions delegate method with a successful purchase indication, and the app is making the decision to provide or not provide the content. The number one reason for such discrepancy lies in receipt validation. Since the problem doesn’t happen to all customers, the most common reason is that the receipt validation process is incorrectly encoding the hex receipt into base64. This can be observed when the receipt validation process returns status error 21002.
You also indicated - "The charge only appears once, however - presumably the purchased product is not being consumed, and thus the user can not purchase the product a second time.” Which leads me to believe that because the content is not provided, the app doesn’t make the finishTransaction call (which is the right thing to do) leaving the transaction incomplete. The next attempt to purchase the item will result in an dialog that states you’ve already purchased the item and do you want to try again (something like this).
This is all a guess based on past experience. Looking at the log may help if the app logs the in app purchase progress. As for base64 encoding the receipt, I recommend what is shown in the Receipt Validation PG
NSDictionary *requestContents = @{
@"receipt-data": [receipt base64EncodedStringWithOptions:0]
};
Rather than doing your own custom algorithm. The above NSData method is iOS7 and greater.
rich kubota - rkubota@apple.com
developer technical support CoreOS/Hardware/MFI