RestoreCompletedTransactions returns incomplete information in a sandbox environment

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(@""); } // Method to restore transactions when user clicks button in application - (void) onRestoreCompletedTransactions:(id)sender { [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; } 
+6
source share
2 answers

Are you trying to call restoreCompletedTransactions every time the application starts? If you need a list of all transactions, you should do SKProductsRequest

  SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productsSet]; productsRequest.delegate = self; [productsRequest start]; 

If you want to receive completed transactions and do not return everything, show the logs.

0
source

SKProductsRequest will return a list of SKProduct instances. The SKProduct class does not allow my reading to acquire information. I think you really want to use restoreCompletedTransactions and return a list of SKPaymentTransaction instances. However, I have the same issue with an isolated account. I am returning an incomplete list of transactions (23 of 48). But if I make a choice to buy a non-expendable, which was bought but not restored, then the store that he already purchased will send back for this item.

Any luck deciding this?

0
source

Source: https://habr.com/ru/post/915704/


All Articles