bizz84 / SwiftyStoreKit

Lightweight In App Purchases Swift framework for iOS 8.0+, tvOS 9.0+ and macOS 10.10+ ⛺
MIT License
6.58k stars 795 forks source link

Pretty often purchaseProduct returns: Unknown error. Please contact support #169

Open bb-git opened 7 years ago

bb-git commented 7 years ago

Platform

In app purchase type

Environment

Version

ℹ Please replace this with the version of SwiftyStoreKit you're using. 0.8.4

Related issues

ℹ Please replace this with references to similar issues (either open or already closed).

Report

Issue summary

I migrated from 0.6.1 which worked fine and now I'm pretty often experiencing this error while testing. Is this a know issue?

What did you expect to happen

Purchase should succeed

What happened instead

Unknown error occurs.

bizz84 commented 7 years ago

@bb-git could you post a stack trace for this?

You can get this by adding a breakpoint in the completion block of the purchase() method, then type bt in the debugger console once the breakpoint is triggered.

Also please see #154. It includes some information from Apple about potential configuration mistakes that could cause problems with IAPs.

Toldy commented 7 years ago

I have the same problem. The issue is linked to https://forums.developer.apple.com/thread/75044. It seems to be a bug from Apple (don't worry, not a SwiftyStoreKit migration issue ✌️)

bizz84 commented 7 years ago

@bb-git do you still experience this? I'm tagging this as an Apple bug and I'll close soon it if there are no updates.

oleynikd commented 7 years ago

I'm having the same issue after migrating to 0.10.x Reverting back to 0.8.5 fixes it. Here's a stack trace of completion block of the purchaseProduct():

* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x00000001000e92b8 myapp`PlansViewController.(result=error, self=0x000000015be6d5a0, completion=0x00000001000f09d0 myapp`partial apply forwarder for myapp.PlansViewController.((purchase in _B1D083F8BD0307D69ADF96FB14E5F4C2) (price : myapp.Price) -> ()).(closure #1).(closure #1) at PlansViewController.swift) -> ()) -> ()).(closure #1) at PlansViewController.swift:142
    frame #1: 0x000000010174f5d8 SwiftyStoreKit`SwiftyStoreKit.(result=failed, completion=0x00000001000f043c myapp`partial apply forwarder for myapp.PlansViewController.((payWithApple in _B1D083F8BD0307D69ADF96FB14E5F4C2) (pgpid : Swift.String, completion : (Swift.Bool) -> ()) -> ()).(closure #1) at PlansViewController.swift, self=0x0000000170257d60) -> ()) -> ()).(closure #1) at SwiftyStoreKit.swift:73
    frame #2: 0x000000010173d0f8 SwiftyStoreKit`PaymentsController.processTransaction(transaction=0x000000017000e310, paymentQueue=PaymentQueue @ 0x000000016fd3a1a8, self=0x000000017003f4c0) -> Bool at PaymentsController.swift:88
    frame #3: 0x000000010173daec SwiftyStoreKit`PaymentsController.($0=0x000000017000e310, self=0x000000017003f4c0, paymentQueue=PaymentQueue @ 0x000000016fd3a220) -> [SKPaymentTransaction]).(closure #1) at PaymentsController.swift:110
    frame #4: 0x00000001017388bc SwiftyStoreKit`thunk at PaymentQueueController.swift:0
    frame #5: 0x0000000101914e50 libswiftCore.dylib`(extension in Swift):Swift.Sequence.filter ((A.Iterator.Element) throws -> Swift.Bool) throws -> Swift.Array<A.Iterator.Element> + 424
    frame #6: 0x000000010173da48 SwiftyStoreKit`PaymentsController.processTransactions(transactions=1 value, paymentQueue=PaymentQueue @ 0x000000016fd3a408, self=0x000000017003f4c0) -> [SKPaymentTransaction] at PaymentsController.swift:110
    frame #7: 0x0000000101738354 SwiftyStoreKit`PaymentQueueController.paymentQueue(queue=0x0000000170007e30, transactions=1 value, self=0x0000000170462980) -> () at PaymentQueueController.swift:170
    frame #8: 0x0000000101738c10 SwiftyStoreKit`@objc PaymentQueueController.paymentQueue(SKPaymentQueue, updatedTransactions : [SKPaymentTransaction]) -> () at PaymentQueueController.swift:0
    frame #9: 0x0000000198bcf6e4 StoreKit`__NotifyObserverAboutChanges + 104
    frame #10: 0x000000018b9d6710 CoreFoundation`CFArrayApplyFunction + 68
    frame #11: 0x0000000198bcf660 StoreKit`-[SKPaymentQueue _notifyObserversAboutChanges:sendUpdatedDownloads:] + 148
    frame #12: 0x0000000198bd0158 StoreKit`-[SKPaymentQueue _processUpdates:trimUnmatched:sendUpdatedDownloads:] + 1220
    frame #13: 0x0000000198bd0c78 StoreKit`-[SKPaymentQueue _updatePaymentsForMessage:] + 144
    frame #14: 0x0000000198bcf510 StoreKit`__44-[SKPaymentQueue _handleMessage:connection:]_block_invoke + 152
    frame #15: 0x0000000102201a50 libdispatch.dylib`_dispatch_call_block_and_release + 24
    frame #16: 0x0000000102201a10 libdispatch.dylib`_dispatch_client_callout + 16
    frame #17: 0x0000000102206b78 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 1204
    frame #18: 0x000000018baa90c8 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
    frame #19: 0x000000018baa6ce4 CoreFoundation`__CFRunLoopRun + 1572
    frame #20: 0x000000018b9d6da4 CoreFoundation`CFRunLoopRunSpecific + 424
    frame #21: 0x000000018d440074 GraphicsServices`GSEventRunModal + 100
    frame #22: 0x0000000191c91058 UIKit`UIApplicationMain + 208
    frame #23: 0x000000010014c8a8 myapp`main at AppDelegate.swift:65
    frame #24: 0x000000018a9e559c libdyld.dylib`start + 4

Here's my purchase method:

fileprivate func payWithApple(pgpid: String, completion: @escaping (Bool) -> Void) {
  debugPrint("payWithApple:", pgpid)
  SwiftyStoreKit.purchaseProduct(pgpid, atomically: false) { (result) in

    switch result {
    case .success(let purchase):
      self.app.validateReceipt(transaction: purchase.transaction, completion: { (success) in
        debugPrint("Purchase Success: \(purchase.productId)")
        if success {
          completion(true)
        } else {
          completion(false)
        }
      })
    case .error(let error):
      switch error.code {
      case .unknown: debugPrint("Unknown error. Please contact support")
      case .clientInvalid: debugPrint("Not allowed to make the payment")
      case .paymentCancelled: break
      case .paymentInvalid: debugPrint("The purchase identifier was invalid")
      case .paymentNotAllowed: debugPrint("The device is not allowed to make the payment")
      case .storeProductNotAvailable: debugPrint("The product is not available in the current storefront")
      case .cloudServicePermissionDenied: debugPrint("Access to cloud service information is not allowed")
      case .cloudServiceNetworkConnectionFailed: debugPrint("Could not connect to the network")
      default: debugPrint("Default")
      }
      completion(false)
    }

  }
}

I'm always getting .unknown error.code

Also, not sure if it matters, but I get this when trying to print out description of the result:

Printing description of result:
expression produced error: error: /var/folders/wh/z9ff290x1f3c8gz_hbtx1wj80000gn/T/./lldb/75373/expr2.swift:1:80: error: 'PurchaseResult' is not a member type of 'SwiftyStoreKit'
Swift._DebuggerSupport.stringForPrintObject(Swift.UnsafePointer<SwiftyStoreKit.PurchaseResult>(bitPattern: 0x104f507d0)!.pointee)
oleynikd commented 7 years ago

Anyone?

oleynikd commented 7 years ago

Rolled back to 0.8.5 - issue remains. Can't figure out WHY!?!? Tried different devices, rebooted, cleaned project, etc... Nothing helped. 😫

bizz84 commented 7 years ago

I've been investigating this. It appears that it can happen when the device can't connect to the iTunes Store. Because this is not a specific SKError, it maps to SKError.Code.unknown.

I'll update the sample demo code to show a more accurate error message, however I don't have an answer to why this happens in the first place.

iwasrobbed commented 7 years ago

This happens every time to me when up/down/cross-grading between subscriptions. I haven't been able to figure out if this is a relic of testing in Sandbox or TestFlight (since my app is not released yet), a configuration error or a bug on Apple's side.

At the very least, make sure you have a Restore Purchase button and that'll get them back into a good state.

mobilinked commented 6 years ago

In Sandbox environment for macOS app testing, this happens every time when cross-grading between subscriptions in the same group.

The purchasing shows message "You are all set", then strangely shows "Unknown error"

zabolotiny commented 6 years ago

Any news here? Had same issue today.

rebeloper commented 6 years ago

For me sometimes it goes through sometimes i get "Unknown error". My guess is that its an iTunes Store issue indeed.

klische commented 6 years ago

I just got rejected during App Review for .purchaseProduct resulting in an .unknown error code. These were all working before, so it definitely seems like a bug on Apple's test servers.

klische commented 6 years ago

Resubmitted the binary, and got rejected again. This doesn’t seem like an Apple issue.

rafaelapaula commented 6 years ago

Someone find a solution?

kuzdu commented 6 years ago

Same here (Version 0.13.3) . I track my in app purchases: In relation 12 purchases of 100 failed. Poorly I haven't a stacktrace, I just receive the error .unknown.

But a good message: A friend of mine told me that he received the unknown error but the purchase worked. In the appconnect I have more purchases than I track. So I suspect that the purchases not really failed.

twprzybysz commented 6 years ago

Yeah I've got the same problem. When I'm trying to change subscription in the same group SwiftyStoreKit.purchaseProduct fails.

sensencoder commented 5 years ago

In fact, I have bought it successfully, but the error returned is still unknown, which seems to be SwiftyStoreKit~

dustin-mehra-pierce commented 5 years ago

Having the same issue when going across the same subscription group

dustin-mehra-pierce commented 5 years ago

Also, the first time I make a purchase in TestFlight it works, if I try to switch to a new purchase it says success but SwiftyStoreKit says “Unknown Error” but then if I switch back to the original one it works again!