0

我正在应用程序购买中实现(非消耗型 - 歌曲)。当用户为每首歌曲购买点击购买时,我调用startPurchase 功能。我的歌曲内容通过我的服务器交付。

因为当我购买了一些东西并再次尝试重新购买相同的东西时,它不会被视为购买的恢复。它会进行新的购买。委托方法被多次调用

实际上我的问题是,我点击购买并继续付款,然后购买了该商品。

再次,当我尝试购买相同的商品时,当我点击“确定”时,苹果警报显示为“您已经购买了该商品,点击确定下载”。这不是在SKPaymentTransactionStateRestored下,而是转到SKPaymentTransactionStatePurchased。为什么会发生这种情况? 请帮忙

请帮帮我

- (void)startPurchase:(NSString*)inProductId{

  if ([SKPaymentQueue canMakePayments])
  {
     myProductId = inProductId

    SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:myProductId]];
    productsRequest.delegate = self;
    [productsRequest start];
  }
  else {
    NSLog(@"Parental-controls are enabled");
      }

}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:
  (SKProductsResponse *)response {

  NSLog(@"response received");
  SKProduct *validProduct = nil;
  int count = [response.products count];

  UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Message" message:
  [NSString stringWithFormat:@"%d",response.products.count] delegate:
  self cancelButtonTitle:@"OK" otherButtonTitles:nil];

  [alert show];
  [alert release];

  if (count > 0) {
    validProduct = [response.products objectAtIndex:0];
    NSLog(@"products available");
    SKPayment *payment = [SKPayment paymentWithProductIdentifier:myProductId];
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
  }
  else if (!validProduct) {
    NSLog(@"No products available");
  }
}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions)
    {
        SKPayment *payment = [transaction payment];

      if([payment.productIdentifier isEqualToString:myProductId])
      {
          NSLog(@"%@payement queue payment.productIdentifier",payment.productIdentifier);

        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
                NSLog(@"completeTransaction");
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateFailed:
                NSLog(@"failedTransaction");
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"restoreTransaction");
                [self restoreTransaction:transaction];
            default:
                break;
        }
      }
    }
}

- (void)provideContent:(NSString *)productIdentifier
{
    NSLog(@"Provide Content %@", productIdentifier);

    }

- (void)recordTransaction:(SKPaymentTransaction *)transaction {
    NSLog(@"inside the recordTransaction");

}

- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
    [self recordTransaction: transaction];
    [self provideContent: transaction.payment.productIdentifier];
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];


}

- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
    NSLog(@"restoreTransaction transaction inside");

   }

- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        if(transaction.error.code == SKErrorUnknown) {
            NSLog(@"Unknown Error (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
            message: @"There was an error purchasing this item please try again."
            delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }

        if(transaction.error.code == SKErrorClientInvalid) {
            NSLog(@"Client invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
            message: @"There was an error purchasing this item please try again."
            delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }

        if(transaction.error.code == SKErrorPaymentInvalid) {
            NSLog(@"Payment invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
            message: @"There was an error purchasing this item please try again."
            delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }

        if(transaction.error.code == SKErrorPaymentNotAllowed) {
            NSLog(@"Payment not allowed (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
            message: @"There was an error purchasing this item please try again."
            delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }
    }
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
4

2 回答 2

0

我认为您的问题添加事务服务器重复反映尝试下面的代码以避免添加事务服务器重复可能是它的工作:

- (void)startPurchase:(NSString*)inProductId{

  if ([SKPaymentQueue canMakePayments])
  {
     myProductId = inProductId

    SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:myProductId]];
    productsRequest.delegate = self;
    [productsRequest start];
  }
  else {
    NSLog(@"Parental-controls are enabled");
      }

}
static bool hasAddObserver=NO;
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:
  (SKProductsResponse *)response {

  NSLog(@"response received");
  SKProduct *validProduct = nil;
  int count = [response.products count];

  UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Message" message:
  [NSString stringWithFormat:@"%d",response.products.count] delegate:
  self cancelButtonTitle:@"OK" otherButtonTitles:nil];

  [alert show];
  [alert release];

  if (count > 0) {
    validProduct = [response.products objectAtIndex:0];
    NSLog(@"products available");
    SKPayment *payment = [SKPayment paymentWithProductIdentifier:myProductId];
    if (!hasAddObserver) {
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    hasAddObserver=YES;
    }
    [[SKPaymentQueue defaultQueue] addPayment:payment];
  }
  else if (!validProduct) {
    NSLog(@"No products available");
  }
}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions)
    {
        SKPayment *payment = [transaction payment];

      if([payment.productIdentifier isEqualToString:myProductId])
      {
          NSLog(@"%@payement queue payment.productIdentifier",payment.productIdentifier);

        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
                NSLog(@"completeTransaction");
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateFailed:
                NSLog(@"failedTransaction");
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"restoreTransaction");
                [self restoreTransaction:transaction];
            default:
                break;
        }
      }
    }
}

- (void)provideContent:(NSString *)productIdentifier
{
    NSLog(@"Provide Content %@", productIdentifier);

    }

- (void)recordTransaction:(SKPaymentTransaction *)transaction {
    NSLog(@"inside the recordTransaction");

}

- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
    [self recordTransaction: transaction];
    [self provideContent: transaction.payment.productIdentifier];
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];


}

- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
    NSLog(@"restoreTransaction transaction inside");

   }

- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        if(transaction.error.code == SKErrorUnknown) {
            NSLog(@"Unknown Error (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
            message: @"There was an error purchasing this item please try again."
            delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }

        if(transaction.error.code == SKErrorClientInvalid) {
            NSLog(@"Client invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
            message: @"There was an error purchasing this item please try again."
            delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }

        if(transaction.error.code == SKErrorPaymentInvalid) {
            NSLog(@"Payment invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
            message: @"There was an error purchasing this item please try again."
            delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }

        if(transaction.error.code == SKErrorPaymentNotAllowed) {
            NSLog(@"Payment not allowed (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
            message: @"There was an error purchasing this item please try again."
            delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }
    }
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

在你的我检查交易服务器是否添加到代码下方:

if (!hasAddObserver) {
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    hasAddObserver=YES;
    }

hasAddObserver 变量静态 bool 数据类型是检查是否已添加容易添加检查事务服务器!

于 2012-06-29T09:40:34.663 回答
0

就 [official Apple documentation][1] 而言,这是正常行为:
“如果用户尝试购买可恢复的产品(而不是使用您实现的恢复接口),应用程序会收到该项目的常规交易,而不是restore transaction。但是,不会再次向用户收取该产品的费用。您的应用程序应将这些交易视为与原始交易相同的交易。"

于 2013-04-22T13:05:40.183 回答