Search code examples
swiftin-app-purchasexcode7sandbox

ios sandbox restored non-consumable IAP without buying


Friends, my question about testing IAP in the Sandbox.

My Steps:

  1. Sign up in itunes-connect the new sandbox tester.
  2. itunes / appstore on the test phone log out

  3. Delete App from device

  4. RUN in Xcode.

All beautifully displayed on my phone. Everything works exactly the way I want to. Except for one scenario.

I just don't know, maybe it should be in the Sandbox, Sandbox-testers feauture.

In my view-controller, which is implemented non-consumable IAP, there are two buttons: "buy" and "restore."

By clicking "restore" (ONLY "restore"), and entering id / password just registered tester, I expect that nothing will be restored, because this id has never been pressed "Buy" button.

But the recovery is successful. Without buying process. It's OK?

My code

import UIKit
import StoreKit

class PurchaseUI: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver{

override func viewDidLoad() {

    super.viewDidLoad()
    self.navigationItem.setHidesBackButton(true, animated:true)
    if (SKPaymentQueue.canMakePayments()) {
            let productID: NSSet = NSSet(object: "bla.bla.bla.pro1")
            let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)
            request.delegate = self
            request.start()
    }
}

@IBAction func buyBtn(sender: AnyObject) {
    for product in flag0{
        let prodID = product.productIdentifier
        if (prodID == ""bla.bla.bla.pro1""){
            flag1 = product
            buyproduct()
            break
        }
    }
}

func fullVers(){
    cashflag = true // global var
}

@IBAction func restorebtn(sender: AnyObject) {
    SKPaymentQueue.defaultQueue().addTransactionObserver(self)
    SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}

var flag0 = [SKProduct]()
var flag1 = SKProduct()

func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
    let myProduct = response.products
    for product in myProduct {
        flag0.append(product)
    }
}

func buyproduct(){
    let pay = SKPayment(product: flag1)
    SKPaymentQueue.defaultQueue().addTransactionObserver(self)
    SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
}

func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {
    for transaction in queue.transactions {
        let t: SKPaymentTransaction = transaction as SKPaymentTransaction
        let prodID = t.payment.productIdentifier as String
        switch prodID {
        case "bla.bla.bla.pro1":
            fullVers()
        default:
            break
        }
    }
}

func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction:AnyObject in transactions {
        let trans = transaction as! SKPaymentTransaction
        switch trans.transactionState {
        case .Purchased, .Restored:
            for transaction in queue.transactions {
                let t: SKPaymentTransaction = transaction as SKPaymentTransaction
                let prodID = t.payment.productIdentifier as String
                switch prodID {
                case "bla.bla.bla.pro1":
                    fullVers()
                default:
                    break
                }
            }
            queue.finishTransaction(trans)
            break
        case .Deferred:
            queue.finishTransaction(trans)
            break
        case .Failed:
            queue.finishTransaction(trans)
            break
        default:
            break
        }
    }
}

func finishTransaction(trans: SKPaymentTransaction){

}

func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
}

}


Solution

  • In the paymentQueueRestoreCompletedTransactionsFinished method, you need to check the transaction state - you are granting full access no matter what happened in the transaction. The method has returned saying the transaction finished but, since no purchases were made, nothing should happen. Check for SKPaymentTransactionStateRestored in there and I think that should do the trick.

    You're doing the check in paymentQueue:updatedTransactions but not in that one.