In-App Purchase Receipt in wrong format

Hi


I'm validating my receipts against the appstore, following the Apple's guide The receipt is retrieved from the bundle using the following code:

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];

NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];

NSString *base64Receipt = [receipt base64EncodedStringWithOptions:0];


The encoded receipt is a signed binary file, as described in the documentation. However, in some weird cases the receipt is not the expected binary file but an NSDictionary with the form

{

pod = 50;

"purchase-info" = "ewo...";

signature = "Apdx...";

"signing-status" = 0;

}


When I try to validate those receipts against the appstore, the result is always 21002 ("The data in the receipt-data property was malformed or missing"). Any ideas in why the receipt retrieved from the bundle is in the wrong format?


Regards

I've been getting similar problems with apps in production lately. It seems like the receipts that get installed alongside the app or its updates are corrupt, or at the very least undocumented. Do you still get this problem after manually requesting a receipt refresh in your app?

Receipts need to be refreshed unless you are retrieving them after a call to updatedTransactions on that device.


It may be possible to hack an app and create a fake receipt. Getting a 21002 means it may be a hack attack that has failed. If you refuse to grant IAP rights when you get a 21002 then you can expect the user to reach out and complain. If you have a 'Contact Us' button and do not get a complaint that supports the conjecture that it was a hack attack.

I'm also seeing a lot of these receipts. Any chance you figured it out?

NSData *ios7ReceiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];

/

NSString * receiptStr = [ios7ReceiptData base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];




NSDictionary *receiptDict = [self dictionaryFromPlistData:ios7ReceiptData];



- (NSDictionary *)dictionaryFromPlistData:(NSData *)data

{

NSError *error;

NSDictionary *dictionaryParsed = [NSPropertyListSerialization propertyListWithData:data

options:NSPropertyListImmutable

format:nil

error:&error];

if (!responseDict)

{

if (error)

{

/

}

return nil;

}

return responseDict;

}

but it returns the receiptDict is nil. How to resolve the issue?

The contents of [[NSBundle mainBundle] appStoreReceiptURL] is not an encoded dictionary. You need to decode it using the procedures outlined here:


https://developer.apple.com/library/prerelease/content/releasenotes/General/ValidateAppStoreReceipt/Introduction.html#//apple_ref/doc/uid/TP40010573-CH105-SW1

In-App Purchase Receipt in wrong format
 
 
Q