transactionobserver not called when user has no payment method

247 views Asked by At

My iap problem start with when a user has not a payment method. iaps working in sandbox (interrupted simluation too) and real world. But in real app (downloaded from appstore - i tested in ios 12 - iphone 6) if i have no payment method app warning me to add one. Then appstore app opens (my app goes background) and i enter all credit card features to buy. Everything goes well and appstore prompt me that you bought product. But after turning back to my app (taking it to foreground) nothing happens. I cant get any information about transaction. Even i add appdidbecomeactive observer to catch again unfinished transactions. Again nothing... Then i added unfinishedTransaction function in app start. if i terminate app and start again. It catches unfinishedtransaction and doing my codes. But users who has no payment method think that app didnt work and they ask money back. So they are right i am paying back or change database of them. How can i handle this problem? I can't even test it in sandbox. Everytime i am giving price to the apple to test. Please help me.

1

There are 1 answers

0
xowiacain On
otherViewcontroller
@objc func saveBtnTUI() { 
    mainVC.messageSN(subject: subjectTF.text!, explain: explainTV.text!) 
    }

i'm handling my database connection to open new draft in mainviewcontroller after that calling pay func...

import StoreKit
MainViewcontroller, SKPaymentTransactionObserver    
func pay() { 
    SKPaymentQueue.default().add(SKPayment(product: product)) SKPaymentQueue.default().add(self) 
    }

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
            for transaction in transactions {
                ...
                case .purchased: complete(transaction: transaction); break
                case .failed: fail(transaction: transaction); break
                ...
    }
    }

    func complete(transaction: SKPaymentTransaction) {
            print("complete...")
            DispatchQueue.main.async { self.paymentID = transaction.transactionIdentifier!; self.paySN()}
            SKPaymentQueue.default().finishTransaction(transaction);  SKPaymentQueue.default().remove(self)
        }
         
        func fail(transaction: SKPaymentTransaction) {
            DispatchQueue.main.async {self.view.viewWithTag(999)?.removeFromSuperview()}
            
            if let err = transaction.error as? SKError {
                if err.code != .paymentCancelled {
                    var mStr:String = "", statusStr:String = ""; print("fail", err.localizedDescription, err.code.self)
                    if err.code == .clientInvalid {mStr = "..."; statusStr = mStr}
                    else if err.code == .cloudServiceNetworkConnectionFailed {mStr = "..."; statusStr = mStr}
                    else if err.code == .cloudServicePermissionDenied {mStr = "..."; statusStr = mStr}
                    else if err.code == .cloudServiceRevoked {mStr = "..."; statusStr = mStr}
                    else if err.code == .paymentInvalid {mStr = "..."; statusStr = mStr}
                    else if err.code == .paymentNotAllowed {mStr = "..."; statusStr = mStr}
                    else if err.code == .storeProductNotAvailable {mStr = "..."; statusStr = mStr}
                    else {mStr = "..."; statusStr = "..."}
                    
                    if #available(iOS 12.2, *) {
                        if err.code == .invalidOfferIdentifier {mStr = "..."; statusStr = mStr}
                        else if err.code == .invalidOfferPrice {mStr = "..."; statusStr = mStr}
                        else if err.code == .invalidSignature {mStr = "..."; statusStr = mStr}
                        else if err.code == .missingOfferParams {mStr = "..."; statusStr = mStr}
                    } else {
                        mStr = "..."; statusStr = "..."
                    }
                    
                    let alert = UIAlertController(title: NSLocalizedString("ERROR", comment: ""), message: mStr, preferredStyle: .alert)
                    let cancelA = UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .cancel, handler: nil); alert.addAction(cancelA)
                    self.present(alert, animated: true, completion: nil)
                    self.paymentStatusSN(status: "fail", message: statusStr)
                }
                else {print("..."); self.paymentStatusSN(status: "cancel", message: "...")}
            }
            else {
                let alert = UIAlertController(title: NSLocalizedString("ERROR", comment: ""), message: "...", preferredStyle: .alert)
                let cancelA = UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .cancel, handler: nil); alert.addAction(cancelA)
                self.present(alert, animated: true, completion: nil)
                self.paymentStatusSN(status: "fail", message: "...")
            }
            SKPaymentQueue.default().finishTransaction(transaction); SKPaymentQueue.default().remove(self)
        }