I'm having some problems with restoreCompletedTransactions while developing an application for iPhone. All of the following problems occur when working in a sandbox environment. The app is not yet for sale. It is being developed with Xcode 4.3.2 running in simulators 5.0 and 5.1. I get the following issues:
- Each time the application starts and when addTransactionObserver is called, updateTransactions is called with the purchase of the transaction. On every callback, my code calls finishTransaction: to complete the purchase, and yet this problem continues to occur every time the application starts. Confirmation of exactly the same purchase comes.
- Calling [[SKPaymentQueue defaultQueue] restoreCompletedTransactions] will not list all non-consumable items purchased in your account. I have 2 purchases of items not consumed, and only 1 is returned every time. If I try to buy an item that is not in the list, I will receive a message stating that the item has already been purchased. The missing item in the list is NOT the one for which I am getting problem 1 (see above).
At this moment I am completely stuck. My application relies on the AppStore to return information about non-expendable resources, since we do not store this data on our own servers. But we need to make sure that AppStoreKit returns a list with ALL purchased items. Not just some.
Here is the relevant code that I use to verify restoreCompletedTransactions:
- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { NSLog(@"updatedTransactions started. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ "); NSLog(@"Number of transactions received: %d.", [transactions count]); int count = 0; for (SKPaymentTransaction *trans in transactions) { NSLog(@"Data for transaction %d: ", ++count); NSString *transId = [trans transactionIdentifier]; switch ([trans transactionState]) { case SKPaymentTransactionStatePurchasing: NSLog(@"Purchasing transaction: %@", transId); if (transId == nil) { NSLog(@" Original transaction Id: %@", [[trans originalTransaction] transactionIdentifier]); } NSLog(@" No action taken in update"); break; case SKPaymentTransactionStateFailed: NSLog(@"Purchase transaction failed for transaction %@", transId); NSLog(@" Error %d (%@)", [[trans error] code], [[trans error] localizedDescription]); NSLog(@" Action Taken: finish transaction."); [queue finishTransaction: trans]; break; case SKPaymentTransactionStatePurchased: NSLog(@"Purchased transaction %@", transId); NSLog(@" Purchased qty %d of product %@", [[trans payment] quantity], [[trans payment] productIdentifier]); NSLog(@" Action: called [queue finishTransaction:] to complete purchase"); [queue finishTransaction: trans]; break; case SKPaymentTransactionStateRestored: { SKPayment *paym = [trans payment]; SKPaymentTransaction *origTrans = [trans originalTransaction]; SKPayment *origPayment = [[trans originalTransaction] payment]; NSLog(@"Transaction restored: %@ with original transaction %@", transId, [[trans originalTransaction] transactionIdentifier]); NSLog(@" TRANSACTION DATA:"); NSLog(@" purchased %d of product %@ on %@.", [paym quantity], [paym productIdentifier], [[trans transactionDate] description]); NSLog(@" ORIGINAL TRANSACTION DATA:"); NSLog(@" purchased %d of product %@ on %@.", [origPayment quantity], [origPayment productIdentifier], [[origTrans transactionDate] description]); NSLog(@" No action taken."); break; } default: NSLog(@"Unexpected transaction state: %d", [trans transactionState]); NSLog(@" No action taken."); break; } } NSLog(@""); NSLog(@"updatedTransactions ended. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ "); } - (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue { NSLog(@"Restore completed transactions finished."); NSLog(@" Number of transactions in queue: %d", [[queue transactions] count]); for (SKPaymentTransaction *trans in [queue transactions]) { NSLog(@" transaction id %@ for product %@.", [trans transactionIdentifier], [[trans payment] productIdentifier]); NSLog(@" original transaction id: %@ for product %@.", [[trans originalTransaction] transactionIdentifier], [[[trans originalTransaction] payment]productIdentifier]); } NSLog(@""); }
source share