1 Reply
      Latest reply on May 17, 2018 2:23 PM by PBK
      SebastianO Level 1 Level 1 (0 points)

        Hello,

         

        my problem is, if I click on the button to restore the purchases, the app is pretended that there is an in-app purchase and it appears at the same time the message that you should buy and confirm with the fingerprint.

        But it can not be restored to a purchase because it was never bought ... I do not know where my mistake lies.

        If I try out the app with sandbox tester he shows me that I have already bought a subscription 20 times (should not be possible) ...

        my code:

         

         

        override func viewDidLoad() {
            ....
            ....
                 if(SKPaymentQueue.canMakePayments()) {
                    print("IAP is enabled, loading")
                    let productID: NSSet = NSSet(objects: "com.SubMonth", "com.SubYear")
                    let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)
                    request.delegate = self
                    request.start()
                } else {
                    print("please enable IAPS")
                }
           }
        
        
        
        
            @IBAction func subscribeMonth(_ sender: Any) {
                for product in list {
                    let prodID = product.productIdentifier
                    if(prodID == "com.SubMonth") {
                        p = product
                        buyProduct()
                    }
                }
            }
            
            @IBAction func subscribeYear(_ sender: Any) {
                for product in list {
                    let prodID = product.productIdentifier
                    if(prodID == "com.SubYear") {
                        p = product
                        buyProduct()
                    }
                }
            }
            
            @IBAction func restore(_ sender: UIButton) {
                restorePurchases()
            }
            
            @IBAction func exit(_ sender: Any) {
                _exit(0)
            }
            
            func restorePurchases() {
                if SKPaymentQueue.canMakePayments(){
                    print("restored complete")
                    SKPaymentQueue.default().add(self)
                    SKPaymentQueue.default().restoreCompletedTransactions()
                }
                else{
                    print("restored faild, IAP not activ?")
                }
            }
        
        
            func buyProduct() {
                print("buy " + p.productIdentifier)
                let pay = SKPayment(product: p)
                SKPaymentQueue.default().add(self)
                SKPaymentQueue.default().add(pay as SKPayment)
            }
        
        
            func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
                print("product request")
                let myProduct = response.products
                for product in myProduct {
                    print("product added")
                    print(product.productIdentifier)
                    print(product.localizedTitle)
                    print(product.localizedDescription)
                    print(product.price)
        
        
                    list.append(product)
                }
            }
        
        
            
            func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
                print("transactions restored")
                for transaction in queue.transactions {
                    let t: SKPaymentTransaction = transaction
                    let prodID = t.payment.productIdentifier as String
        
        
                    switch prodID {
                    case "com.SubMonth":
                        readySubscribe()
                        break
                    case "com.SubYear":
                        readySubscribe()
                        break
                    default:
                        print("IAP not found")
                    }
                }
            }
        
        
            func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
                print("add payment")
        
        
                for transaction: AnyObject in transactions {
                    let trans = transaction as! SKPaymentTransaction
                    print(trans.error)
        
        
                    switch trans.transactionState {
                    case .purchased:
                        print("buy ok, unlock IAP HERE")
                        print(p.productIdentifier)
        
        
                        let prodID = p.productIdentifier
                        switch prodID {
                        case "com.SubMonth":
                            readySubscribe()
                            break
                        case "com.SubYear":
                            readySubscribe()
                            break
                        default:
                            print("IAP not found")
                        }
                        queue.finishTransaction(trans)
                    case .failed:
                        print("buy error")
                        queue.finishTransaction(trans)
                        break
                    default:
                        print("Default")
                        break
                    }
                }
            }
            
            func readySubscribe()  {
                self.performSegue(withIdentifier: "readySubscribe", sender: self)
            }
        

         

         

        Thank You very much

        • Re: Swift, In-App restore purchase
          PBK Level 6 Level 6 (2,520 points)

          You are handle a restored transaction in the updatedTransactions method when the transaction state is .restored.  The method paymentQueueRestoreCompletedTransactionsFinished does not handle restored transactions - and it seems like you are doing it there.  It is called after all transactions have been reported to the updatedTransactions method - you need it in case there are no restored transactions and therefore no calls to updatedTransactions.