An unknown error occurred while purchasing in app product in ios

Viewed 652

I have consumable, auto renewable and non renewable in app purchase in my application. I am able to purchase product in sandbox mode successfully. But sometimes i am getting following error randomly.

transaction error code is Optional(Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x28225aca0 {Error Domain=ASDErrorDomain Code=500 "Unhandled exception" UserInfo={NSUnderlyingError=0x28225b1e0 {Error Domain=AMSErrorDomain Code=301 "Invalid Status Code" UserInfo={NSLocalizedDescription=Invalid Status Code, NSLocalizedFailureReason=The response has an invalid status code}}, NSLocalizedFailureReason=An unknown error occurred, NSLocalizedDescription=Unhandled exception}}})

Following is the code i have implemented.

open class IAPHelper : NSObject  {
  
  static let IAPHelperPurchaseNotification = "IAPHelperPurchaseNotification"
  var productIdentifiers: Set<ProductIdentifier>?
  fileprivate var purchasedProductIdentifiers = Set<ProductIdentifier>()
  fileprivate var productsRequest: SKProductsRequest?
  fileprivate var productsRequestCompletionHandler: ProductsRequestCompletionHandler?

  static let shared : IAPHelper = IAPHelper()
     
     override public init() {
       super.init()
       print("IAP Init method called")
     }

   public func getProducts(productIds: Set<ProductIdentifier>)
   {
     productIdentifiers = productIds
     for productIdentifier in productIds {
       let purchased = UserDefaults.standard.bool(forKey: productIdentifier)
       if purchased {
         purchasedProductIdentifiers.insert(productIdentifier)
         print("Previously purchased: \(productIdentifier)")
       } else {
         print("Not purchased: \(productIdentifier)")
       }
     }
        if(appDel.isObserverAdded == false)
        {
          print("observer added")
         // SKPaymentQueue.default().remove(self)
          SKPaymentQueue.default().add(self)
          appDel.isObserverAdded = true
        }
   }
  
}

// MARK: - StoreKit API

extension IAPHelper {

  public func requestProducts(completionHandler: @escaping ProductsRequestCompletionHandler) {
    productsRequest?.cancel()
    productsRequestCompletionHandler = completionHandler
    productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers!)
    productsRequest!.delegate = self
    productsRequest!.start()
  }

  public func buyProduct(_ product: SKProduct) {
    appDelChat.isPurchaseDone = true
    print("Buying \(product.productIdentifier)...")
    let payment = SKPayment(product: product)
    SKPaymentQueue.default().add(payment)
  }

  public func isProductPurchased(_ productIdentifier: ProductIdentifier) -> Bool {
    return purchasedProductIdentifiers.contains(productIdentifier)
  }
  
  public class func canMakePayments() -> Bool {
    return SKPaymentQueue.canMakePayments()
  }
  
  public func restorePurchases() {
    SKPaymentQueue.default().restoreCompletedTransactions()
  }
}

// MARK: - SKProductsRequestDelegate

extension IAPHelper: SKProductsRequestDelegate {

  public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse)
  {
    print("sk payment response is",response.invalidProductIdentifiers)
    var products = response.products
    print("Loaded list of products...",products)
    products = products.sorted(by: { (item1, item2) -> Bool in
                 return item1.price.doubleValue < item2.price.doubleValue
             })
    print("sorted products are",products)
    productsRequestCompletionHandler?(true, products)
    clearRequestAndHandler()
    for p in products {
      print("Found product: \(p.productIdentifier) \(p.localizedTitle) \(p.price.floatValue)")
    }
  }
  
  public func request(_ request: SKRequest, didFailWithError error: Error) {
    print("Failed to load list of products.")
    print("Error: \(error.localizedDescription)")
    productsRequestCompletionHandler?(false, nil)
    clearRequestAndHandler()
  }

  private func clearRequestAndHandler() {
    productsRequest = nil
    productsRequestCompletionHandler = nil
  }

  
}

// MARK: - SKPaymentTransactionObserver
 
extension IAPHelper: SKPaymentTransactionObserver {
 
  public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction])
  {
     print("updated transaction")
     for transaction in transactions {
      switch (transaction.transactionState)
      {
      case .purchased:
        print("product purchased",transaction.payment.productIdentifier)
        complete(transaction: transaction)
         print("credit purchase delegate",creditPurchasedDelegate)
          print("all did purchase delegate",allDIDPurchasedDelegate)

          NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPHelper.IAPHelperPurchaseNotification), object: transaction)

        break
      case .failed:
        fail(transaction: transaction)
          NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPHelper.IAPHelperPurchaseNotification), object: transaction)


        break
      case .restored:
        restore(transaction: transaction)
          NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPHelper.IAPHelperPurchaseNotification), object: transaction)


        break
      case .deferred:
          NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPHelper.IAPHelperPurchaseNotification), object: transaction)


        break
      case .purchasing:
          NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPHelper.IAPHelperPurchaseNotification), object: transaction)


        break
      }
    }
  }
     
 
  private func complete(transaction: SKPaymentTransaction) {
    print("complete...")
    SKPaymentQueue.default().finishTransaction(transaction)
  }
 
  private func restore(transaction: SKPaymentTransaction) {
    guard let productIdentifier = transaction.original?.payment.productIdentifier else { return }
    print("restore... \(productIdentifier)")
    SKPaymentQueue.default().finishTransaction(transaction)
  }
 
  private func fail(transaction: SKPaymentTransaction) {
    print("fail...")
    if let transactionError = transaction.error as? NSError {
      if transactionError.code != SKError.paymentCancelled.rawValue {
        print("Transaction Error: \(transaction.error?.localizedDescription)")
      }
    }
    SKPaymentQueue.default().finishTransaction(transaction)
  }

What could be the cause of this error?

0 Answers
Related