如何完成付款交易 - 在应用程序购买

时间:2012-06-29 09:24:45

标签: iphone ios ios4 in-app-purchase

我正在购买应用程序(非消耗类型 - 歌曲)。当用户点击购买每首歌曲购买时,我打电话给 startPurchase funtion 。我的歌曲内容通过我的服务器发送。

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

实际上我的问题是,我点击购买并继续付款,并购买该项目。

再次当我尝试购买相同的商品时,苹果提醒称为“您已购买此商品,请点按”确定下载“,当我点按”确定“时。这不是< strong> 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];
}

2 个答案:

答案 0 :(得分: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数据类型检查是否已经添加了易于添加的检查事务服务器!

答案 1 :(得分:0)

就官方Apple文档[1]所说,这是正常行为:
“如果用户尝试购买可恢复的产品(而不是使用您实施的恢复界面),应用程序将收到该项目的常规交易,而不是恢复交易。但是,用户不会收取费用对于该产品,您的应用程序应该将这些交易与原始交易的交易完全相同。“