SKPayments 完成交易两次调用

Posted

技术标签:

【中文标题】SKPayments 完成交易两次调用【英文标题】:SKPayments Complete transaction called two times 【发布时间】:2013-08-19 11:03:40 【问题描述】:

我遇到了严重的问题,我正在处理应用内购买,当我第一次尝试购买时它工作正常,第二次我的 completeTransaction 调用了两次.. 我不知道为什么我会遇到这个问题。

收到收据后,我调用我的验证方法,如果验证成功,服务器会在 http 响应中向我发送音频文件,我下载该文件,当我成功下载文件时,我调用 finishtransaction。

这是我的代码

- (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");

 

在下载成功块中的 VerifyTransaction 方法中,我调用完成事务

[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];

 

【问题讨论】:

【参考方案1】:

看起来您的观察者队列仍然包含旧产品 ID

- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions

    NSLog(@"Purchase removedTransactions");

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

在您完成交易后删除产品 ID。

【讨论】:

这个代表没有打电话给我 如何处理后续交易?我的理解是,当您为任何后续购买恢复事务观察器时,它将使用 App Store 中用户的现有队列进行更新。因此,这似乎只是一个临时修复。 当任何随机事务都可以从队列中移除时,移除事务观察者很奇怪..【参考方案2】:

我最终做了以下事情:

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

删除观察者在一定程度上缓解了这个问题,但当我向应用程序中的购买按钮“发送垃圾邮件”时,我仍然偶尔会遇到双重呼叫。上面的解决方案完全解决了它,并且在我的测试中看起来非常强大。

【讨论】:

以上是关于SKPayments 完成交易两次调用的主要内容,如果未能解决你的问题,请参考以下文章

NSOperation completionBlock 被调用两次

PayPal批准/完成交易后调用外部函数[重复]

SKPayementQueue:恢复交易完成而不在发布配置中调用“updatedTransactions”但不是调试配置

订阅被调用两次

服务同时调用两次

调用 PayPal DO_DIRECT_PAYMENT 时出现问题:com.paypal.sdk.exceptions.FatalException:无法完成 HTTPS 交易