user1597878
user1597878

Reputation:

SKPayments Complete transaction called two times

I got serious problem i am working on In app purchase and when i try to purchase first time it works fine and for the second time my completeTransaction called two times.. I dont know why i got this issue.

After i got receipt i call my verification method and if verify Okay than server send me audio file in http responce and i downlaod that and when i successfully download file i call finishtransaction.

Here is my code

- (void)startPurchase {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
if([SKPaymentQueue canMakePayments]) {
    NSLog(@"IN-APP:can make payments");
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject:myIdentifier]];
    request.delegate = self;
      NSLog(@"** Productdata is ** %@",myIdentifier);
    [request start];

}
else {
    NSLog(@"IN-APP:can't make payments");
    loadingHUD.hidden=YES;
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {

NSLog(@"IN productsRequest END %d",[response.products count]);

@try {
    SKProduct *product = [response.products objectAtIndex:0];
    SKPayment *newPayment = [SKPayment paymentWithProduct:product];
    [[SKPaymentQueue defaultQueue] addPayment:newPayment];
    NSLog(@"IN-APP:productsRequest END");

    loadingHUD.hidden=YES; // Hide the Loading progress bar 

}

@catch (NSException *exception) {

    // Failed to purchase Hide the progress bar and Display Error Dialog
    loadingHUD.hidden=YES;
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"error" message:@"Errror " delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertView show];

}
}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
 {
for (SKPaymentTransaction *transaction in transactions)
{
    switch (transaction.transactionState)
    {
        case SKPaymentTransactionStatePurchased:
            [self completeTransaction:transaction];
            break;
        case SKPaymentTransactionStateFailed:
            [self failedTransaction:transaction];
            break;
        case SKPaymentTransactionStateRestored:
            [self restoreTransaction:transaction];
        default:
            break;
    }
  }
  }
 - (void) completeTransaction: (SKPaymentTransaction *)transaction
   {
  NSLog(@"Transaction Completed");
// Finally, remove the transaction from the payment queue.
 [self verifyReceipt:transaction]; // Call the verifyReceipt method to send transaction.bytes
// [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
 NSLog(@"Purchase Transaction finish");

 }

In VerifyTransaction method in download success block i call finish transaction

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
 {

      [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; // Finish the transaction

    // NSLog(@"Successfully downloaded file to %@",[[NSString alloc] initWithData:operation.responseData encoding:NSASCIIStringEncoding]);

     // Give alert that downloading successful.
     NSLog(@"Successfully downloaded file to %@", destPath);

    // NSLog(@"response: %@", operation.responseString);  // Give alert that downloading successful.

     // [self.target parserDidDownloadItem:destPath];

     //loadingHUD.detailsLabelText = [NSString stringWithFormat:@"%@ %i%%",@"Downloading",100];
     [loadingHUD hide:TRUE];

     [DBHelper savePurchaseId:fileName]; // save the purchase itune id into local database to populate hover image of play button on main List
     [self movieReceived];

 }

Upvotes: 6

Views: 3731

Answers (2)

beetree
beetree

Reputation: 941

I ended up doing the following:

if(contains(self.transactions, trans.transactionIdentifier) == false) {
    self.transactions.append(trans.transactionIdentifier)
    //Give the user the purchased product
}

Removing the observers somewhat relieved the problem but I still had occasional double-calls going through when I "spammed" the purchase button in the app. The solution above completely resolved it though and seems very robust in my testing.

Upvotes: 1

Swap-IOS-Android
Swap-IOS-Android

Reputation: 4383

its Look like your Observer queue still contain Older product id

- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
{
    NSLog(@"Purchase removedTransactions");

    // Release the transaction observer since transaction is finished/removed.
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

To remove product id once you finish your transaction.

Upvotes: 8

Related Questions