RMStore offline receipt verification

2.2k views Asked by At

One question about offline receipt verification using RMStore (https://github.com/robotmedia/RMStore)

On App start I check if the app has a valid in app purchase (PRO Version) (my App is iOS7 only)

I do that like that:

RMStoreAppReceiptVerificator *verificator = [[RMStoreAppReceiptVerificator alloc] init];
BOOL isValidReceipt = [verificator verifyAppReceipt];
if (isValidReceipt)
{
    BOOL isProVersion = [[RMAppReceipt bundleReceipt] containsInAppPurchaseOfProductIdentifier:xxx];
    ...
}

I still have version 1.0 in the App Store... But now i'd like to make an update soon... This will still work after an app store update, right? The App will still have the receipt in there and verification should still pass, right?

I ask because testing in-app purchases is not really easy (especially updating and stuff) and if something fails users would be pissed....

1

There are 1 answers

6
hpique On BEST ANSWER

The code should work as before. However, you're not verifying the receipt correctly. Quoting the Receipt Validation Programming Guide:

If validation fails in iOS, use the SKReceiptRefreshRequest class to refresh the receipt.

Using RMStore, that would look like this:

const BOOL verified = [self verifyReceiptWithCustomLogic];
if (verified)
{
    // Verification succeeded
} 
else 
{ // Apple recommends to refresh the receipt if validation fails on iOS
    [[RMStore defaultStore] refreshReceiptOnSuccess:^{
        const BOOL verified = [self verifyReceiptWithCustomLogic];
        if (verified)
        {
            // Verification succeeded
        }
        else
        {
            // Verification failed
        }
    } failure:^(NSError *error) {
            // Verification failed
    }];
}

Where your verification logic appears to be:

- (BOOL)verifyReceiptWithCustomLogic
{
    RMStoreAppReceiptVerificator *verificator = [RMStoreAppReceiptVerificator new];
    if ([verificator verifyAppReceipt])
    {
        return [[RMAppReceipt bundleReceipt] containsInAppPurchaseOfProductIdentifier:xxx];
    }
    return NO;
}

Note that refreshing the receipt makes receipt verification an asynchronous process.