Reputation: 557
I'm getting an issue on my iOS app: when I touch the 'buy' button to purchase an IAP product, a pop-up appears showing this message:
This In-App purchase has already been bought. It will be restored for free.
I never had this pop-up before, and my products are only non-renewing subscriptions, so I wonder why this message appears when buying subscriptions.
When I touch ok to close this pop-up, the purchase is not performed.
Here is my code:
for transaction in transactions {
switch transaction.transactionState {
case SKPaymentTransactionState.Purchased, SKPaymentTransactionState.Restored:
print("Transaction completed successfully.")
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
transactionInProgress = false
// Sauvegarde le produit acheté
savePurchasedProduct(transaction.transactionDate!);
break
case SKPaymentTransactionState.Failed:
print("Transaction Failed");
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
transactionInProgress = false
break
default:
break
}
}
Upvotes: 9
Views: 16348
Reputation: 554
We can also get all transactions and mark as completed by using below method.
You can add below code in viewdidload
method.
for transactionPending in SKPaymentQueue.default().transactions {
SKPaymentQueue.default().finishTransaction(transactionPending)
}
I tried lot of other solutions but this works for me.So, now i can buy product multiple times.
Upvotes: 6
Reputation: 844
I had the same problem with a non-recurring subscription. It was saying that it had already been purchased, it would restore for free, but not let me buy another subscription extension.
Part of the problem was my transaction switch logic:
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
complete(transaction: transaction)
case .restored:
restore(transaction: transaction)
break
...
For case .purchased I was calling:
SKPaymentQueue.default().finishTransaction(transaction)
But for case .restored I never called finishTransaction. Somehow during development I must have missed a finishTransaction and had one "in the queue" which I was never finishing.
My fix was to modify my restoreTransaction to (after making sure the subscription was recorded in my licenses object) call .finishTransaction. I checked that I didn't duplicate the subscription checking for unique transaction IDs.
Then I attempted to purchase 2 more times. The first time the transaction was finished, and the 2nd time I was able to buy again!
Upvotes: 0
Reputation:
I had the same issue. Fixed it here:
My IAP isn't working. Bugs at func Paymentqueue
Here is the solution I had found:
Delete
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
everywhere you have it and put it once (ONLY ONCE) in a place where it will be executed each time your app boots up (I put it in viewDidLoad()).
This will check for all unfinished transactions and terminate them once the app has loaded, thus removing any possible errors before your users triggers an IAP.
P.S.: Also, this wasn't my issue, but make sure to finishTransaction() for each PurchaseState, like here:
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("IAP unlocked")
print(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID{
case "IAP id":
print("Keep on")
keepOn()
default:
print("IAP not setup")
}
queue.finishTransaction(trans)
break
case .Failed:
print ("Buy error")
queue.finishTransaction(trans)
break
default:
print("default: Error")
break
}
}
}
Never forget this:
queue.finishTransaction(trans)
Upvotes: 6