Restore purchase gives all users for free

Hi everyone,


I have 1 product as IAP Non-consumable item in my APP, I have implement the restore purchase button into my app. However any user click that button get the item successfully purchased. I'm not sure what's wrong. Below in my code:


@IBAction func btn_restore(_ sender: Any) {
        SKPaymentQueue.default().add(self)
        SKPaymentQueue.default().restoreCompletedTransactions()

    }


func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
  
  
        for transaction in queue.transactions {
            let t: SKPaymentTransaction = transaction
            let prodID = t.payment.productIdentifier as String
      
            switch prodID {
            case No_Ads_ID:
          
                print("remove ads")
                remove_ads_purchased = true
                UserDefaults.standard.set(remove_ads_purchased, forKey: "remove_ads_purchased")
          
                UIAlertView(title: "Title",
                            message: "You've successfully restored your purchase!",
                            delegate: nil, cancelButtonTitle: "OK").show()
                break
          
            default:
                print("IAP not found")
            }
        }
  
  

    }


func fetchAvailableProducts()  {
   
        /
        let productIdentifiers = NSSet(objects:
            No_Ads_ID
        )
   
        productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
        productsRequest.delegate = self
        productsRequest.start()
    }


func canMakePurchases() -> Bool {  return SKPaymentQueue.canMakePayments()  }
    func purchaseMyProduct(product: SKProduct) {
        if self.canMakePurchases() {
            let payment = SKPayment(product: product)
            SKPaymentQueue.default().add(self)
            SKPaymentQueue.default().add(payment)
        
            print("PRODUCT TO PURCHASE: \(product.productIdentifier)")
            productID = product.productIdentifier
        
        
            /
        } else {
            let alert = UIAlertController(title: "Error!", message: "Purchases are disabled in your device!", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default,handler:
                {(alert: UIAlertAction!) in
                
                
            }
            ))
            self.present(alert, animated: true, completion: nil)
        }
    }



func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction:AnyObject in transactions {
            if let trans = transaction as? SKPaymentTransaction {
                switch trans.transactionState {
                 
                case .purchased:
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
                 
                    /
                     if productID == No_Ads_ID {
                     
                        /
                        remove_ads_purchased = true
                        UserDefaults.standard.set(remove_ads_purchased, forKey: "remove_ads_purchased")

                        let alert = UIAlertController(title: "Title", message: "You've successfully Remove Ads", preferredStyle: UIAlertControllerStyle.alert)
                        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default,handler:
                            {(alert: UIAlertAction!) in
                             
                             
                        }
                        ))
                        self.present(alert, animated: true, completion: nil)
                    }
                 
                    break
                 
                case .failed:
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
                    break
                case .restored:
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
                    break
                 
                default: break
                }}}
    }


func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {
        if (response.products.count > 0) {
            iapProducts = response.products
          
            /
            let numberFormatter = NumberFormatter()
            numberFormatter.formatterBehavior = .behavior10_4
            numberFormatter.numberStyle = .currency
          
          
            /
            let secondProd = response.products[0] as SKProduct
          
            /
            numberFormatter.locale = secondProd.priceLocale
            let price2Str = numberFormatter.string(from: secondProd.price)
          
        }
    }
Accepted Answer

If a purchase is available to restore then StoreKit calls updatedTransactions with a case of .restored. Whether or not there is a purchase to restore StoreKit calls paymentQueueRestoreCompletedTransactionsFinished to signal it is completed.


Move your code that grants the purchase from paymentQueueRestoreCompletedTransactionsFinished to updatedTransactions.

Restore purchase gives all users for free
 
 
Q