iOS transactions not in SKPaymentTransactionStateRestored state during restore flow

Hi guys,


A small subset of my users are stuck in a strange state where they cannot purchase anything because they apparently have the purchase but they also cannot restore.


I recently tried switching to a RMStore for cleaner code and to get rid of my messy homemade solution but the same issue is still happening for affected users.


For those familiar with RMStore my restore block looks like this:


[[RMStore defaultStore] restoreTransactionsOnSuccess:^(NSArray *transactions){
     if ([SKPaymentQueue defaultQueue].transactions.count == 0) {
          [self fail:@"There are no items available to restore at this time."];
     } else {
          for (SKPaymentTransaction *transaction in transactions) {
               if (transaction.transactionState == SKPaymentTransactionStateRestored) {
                    if ([transaction.payment.productIdentifier isEqualToString:(NSString*)productID]) {
                         [Utils setPremium:YES];
                    }
               }
          }
          [self success];
     }
}
failure:^(NSError *error) {
//...
}];


For whatever reason the affected users hit the ELSE case but do not have premium activated. The only possiblities are that the transaction doesnt match the product identifier or the transaction state is not SKPaymentTransactionStateRestored. I only have the one product and I haven't changed it since it was first created so I'm guessing the transaction state is the issue.


Should I be doing [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; if transactions are found in the for loop that are not in the restore state? Is this bad practice? Could this potentially fix my users in a bad state?


Any suggestions would be greatly appreciated.

You should call finishTransaction on almost all transactions that come into your updatedTransactions method. It is unclear when your RMStore method is being called.

RMStore switches to a block handling of purchase, restore and query. You no longer have to implement any of the oberserver delegate methods like updatedTransactions. From what I've seen from the docs and the demo project you also don't have to manually call finishTransaction on any transactions.

https://github.com/robotmedia/RMStore


This RMStore block is being called in relation to the "Restore Purchases" touch up inside.

You have an unfinished transaction that is not

transaction.transactionState == SKPaymentTransactionStateRestored

iOS transactions not in SKPaymentTransactionStateRestored state during restore flow
 
 
Q