title: In-App-Purchase - purchase successful then transaction failed
body: <p>When I run the app with the code below, i buy one of the products using my test account and I get this in my console:</p>
  
  <pre><code>queue
  queue
  unlocked:
    buy20
  Transaction Failed
  </code></pre>
  
  <p>Somehow the purchase manages to be successful in the <code>- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions</code> method then immediately after, fails. Do you see any problems with the code below or have you heard of this problem before?</p>
  
  <pre><code>#import "BuyWindowViewController.h"
  
  @interface BuyWindowViewController ()
  
  @end
  
  @implementation BuyWindowViewController
  
  - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  {
      self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
      if (self) {
          // Custom initialization
      }
      return self;
  }
  
  - (void)viewDidLoad
  {
      [super viewDidLoad];
  
      [_closeButton setTitle:@"Close" forState:UIControlStateNormal];
      [_closeButton.titleLabel setFont:[UIFont fontWithName:@"Helvetica" size:16.0f]];
      [_titleBar setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"Button 400x50 Yellow.png"]]];
  
      _productIDs = [iAPBundleIDs returnAllIDs];
      [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
  
      [self getProductID];
  }
  
  - (void)didReceiveMemoryWarning
  {
      [super didReceiveMemoryWarning];
      // Dispose of any resources that can be recreated.
  }
  
  - (IBAction)closeButtonPressed:(id)sender {
      [self dismissViewControllerAnimated:YES completion:nil];
  }
  
  - (void)viewDidUnload {
      [self setTitleBar:nil];
      [super viewDidUnload];
  
  }
  
  - (NSUInteger)supportedInterfaceOrientations {
      return UIInterfaceOrientationMaskLandscape;
  }
  
  - (BOOL)shouldAutorotate {
      return YES;
  }
  
  - (IBAction)infoButtonPressed:(UIButton *)sender {
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Serpentine!" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
      if (sender.tag == 1) {
          //buy 20
          alert.title = @"Instantly get 20 Upgrade Points to spend in the Shop!";
      } else if (sender.tag == 2) {
          //buy 45
          alert.title = @"Instantly get 45 Upgrade Points to spend in the Shop!";
      } else if (sender.tag == 3) {
          //buy 100
          alert.title = @"Instantly get 100 Upgrade Points to spend in the Shop!";
      } else if (sender.tag == 4) {
          //double
          alert.title = @"Permanently double the upgrade points you receive at the end of each game!";
      } else if (sender.tag == 5) {
          //remove ads + 20
          alert.title = @"Remove those annoying iAds and get 20 upgrade points with one purchase!";
      }
      [alert show];
  }
  
  - (IBAction)purchaseButtonPressed:(UIButton *)sender {
      _whichProduct = 0;
      if (sender.tag == 1) {
          //buy 20
          _whichProduct = 1;
      } else if (sender.tag == 2) {
          //buy 45
          _whichProduct = 2;
      } else if (sender.tag == 3) {
          //buy 100
          _whichProduct = 0;
      } else if (sender.tag == 4) {
          //double
          _whichProduct = 3;
      } else if (sender.tag == 5) {
          //remove ads + 20
          _whichProduct = 4;
      }
  
      SKPayment *payment = [SKPayment paymentWithProduct:_products[_whichProduct]];
      [[SKPaymentQueue defaultQueue] addPayment:payment];
  
      [self showLoadingWithText:@"Purchasing item..."];
  }
  
  #pragma mark - Loading Stuff
  
  - (void)couldNotConnectToStoreWithText:(NSString *)text {
      [_spinner removeFromSuperview];
      [_spinner startAnimating];
      [_spinnerLabel setText:text];
  }
  
  - (void)hideLoading {
      [UIView animateWithDuration:0.5f animations:^{
          _spinnerBackground.alpha = 0;
      } completion:^(BOOL finished) {
          [_spinner removeFromSuperview];
          [_spinnerLabel removeFromSuperview];
          [_spinnerBackground removeFromSuperview];
      }];
  }
  
  - (void)showLoadingWithText:(NSString *)text {
      [_spinnerBackground addSubview:_spinner];
      [_spinnerBackground addSubview:_spinnerLabel];
      _spinnerLabel.text = text;
  
      [self.view addSubview:_spinnerBackground];
      [self.view bringSubviewToFront:_spinnerBackground];
  
      [UIView animateWithDuration:0.5f animations:^{
          _spinnerBackground.alpha = 0;
      }];
  }
  
  
  #pragma mark - iAP
  
  - (void)getProductID {
      if ([SKPaymentQueue canMakePayments]) {
          SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIDs];
          request.delegate = self;
  
          [request start];
      } else {
          [self couldNotConnectToStoreWithText:@"Error: Could not connect to store. Try enabling in-app-purchases in settings"];
      }
  
  }
  
  - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
      NSArray *products = response.products;
      if (products.count != 0) {
          _products = products;
  
          [self hideLoading];
      } else {
          [self couldNotConnectToStoreWithText:@"Error: Could not connect to iTunes"];
      }
  
      products = response.invalidProductIdentifiers;
  
      for (SKProduct *product in products) {
          NSLog(@"Product not found: %@", product);
      }
  }
  
  - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
      NSLog(@"queue");
      for (SKPaymentTransaction *transaction in transactions) {
          switch (transaction.transactionState) {
              case SKPaymentTransactionStatePurchased:[self unlockPurchase];
                  [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
  
              case SKPaymentTransactionStateFailed:NSLog(@"Transaction Failed");//[[[UIAlertView alloc] initWithTitle:@"Serpentine" message:@"Error: Transaction Failed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
                  [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
  
              default:break;
          }
      }
  }
  
  - (void)unlockPurchase {
      NSLog(@"unlocked:");
      if (_whichProduct == 1) {
          //buy 20
          NSLog(@"  buy20");
      } else if (_whichProduct == 2) {
          //buy 45
          NSLog(@"  buy45");
      } else if (_whichProduct == 0) {
          //buy 100
          NSLog(@"  buy100");
      } else if (_whichProduct == 3) {
          //double
          NSLog(@"  buydouble");
      } else if (_whichProduct == 4) {
          //remove ads + 20
          NSLog(@"  buyads");
      }
  
      [[[UIAlertView alloc] initWithTitle:@"Serpentine" message:@"Purchase successful!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
      [self hideLoading];
  }
  
  - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
      [self unlockPurchase];
      NSLog(@"restore");
  }
  
  - (void)restore {
      [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
  }
  
  @end
  </code></pre>
  
  <p>Thanks</p>