RevenueCat / purchases-flutter

Flutter plugin for in-app purchases and subscriptions. Supports iOS, macOS and Android.
https://www.revenuecat.com/
MIT License
608 stars 170 forks source link

The await for CustomerInfo customerInfo = await Purchases.purchasePackage(myProductList[index]); never completed; MagicWeather example, v.6.3.0 #875

Closed FuadEfendi closed 11 months ago

FuadEfendi commented 1 year ago

iPhone 15 Pro Max simulator iOS 17.0 purchases_flutter: ^6.3.0 MagicWeather official example

I configured MagicWeather official example with my Apple Store API key (taken from RevenueCat AppStore configuration). Configured In-App Purchase, monthly subscription; configured RevenueCat. Added some debug "print" messages to ensure Purchases.purchasePackage() method call will indeed return. This method call never returns.

  1. Click on "Change the Weather" opens "paywall" widget with correct price shown, and "terms and conditions" footer.
  2. Click on the product item in the list (and I have single product only) will popup iOS username/password screen, "Sign in with Apple ID"
  3. After authentication, I can "purchase" chosen product, using iOS "Sandbox" native widget (in my case, clicking "Subscribe" button triggers "Enter password to authorize this transaction")
  4. After "purchase" it returns to "paywall" screen, and after few seconds delay it returns back to iOS "purchase product" widget, although I don't click anything
  5. in a loop...

And the Purchases.purchasePackage(myProductList[index]);method call never returns; I added debug message after it to verify.

To follow current README file format, this is what expected:

Example Flow: Purchasing a Subscription

  1. On the home page, select Change the Weather.
  2. On the prompted payment sheet, select the product listed.
  3. On the next modal, select Subscribe.
  4. On the next modal, sign in with your Sandbox Apple ID.
  5. On the next modal, select Ok.
  6. Return to the home page and select Change the Weather to see the weather change!

And this is actual behavior:

  1. On the home page, select Change the Weather.
  2. On the prompted payment sheet, select the product listed.
  3. On the next modal, select Subscribe. [UNEXPECTED: wait 3-5 seconds!!!]
  4. On the next modal, sign in with your Sandbox Apple ID.
  5. On the next modal, select Ok. [UNEXPECTED: there is no Ok]
  6. After short Done modal, we have "list of product" screen, after which we have automatically Subscribe modal; in a loop; transaction never finishes.
FuadEfendi commented 1 year ago

Related: https://community.revenuecat.com/sdks-51/purchases-purchasepackage-doesn-t-return-1956

john-paradym commented 11 months ago

Seeing the same behaviour

I think it's only in Sandbox mode, as we haven't seen this before, but I'm trying to integrate with Purchasely using their documentation at https://docs.purchasely.com/quick-start-1/purchasely-with-revenuecat and seeing the issue for the first time

john-paradym commented 11 months ago

Extra info: I did a Flutter hot reload and removed the Purchasely code, and got this error

Product purchase for 'subs.par_9.99_30_3' failed with error: Error Domain=RevenueCat.ErrorCode Code=15 "The operation is already in progress for this product." UserInfo={readable_error_code=OPERATION_ALREADY_IN_PROGRESS_FOR_PRODUCT_ERROR, source_file=RevenueCat/PurchasesOrchestrator.swift:956, NSLocalizedDescription=The operation is already in progress for this product., source_function=addPurchaseCompletedCallback(productIdentifier:completion:)}

From my point of view, the original purchase went through, and I was trying again - but clearly the RevenueCat code thinks otherwise, and hence why the Purchases.purchasePackage() call never returned

EDIT: When I completely removed Purchasely, and went back to the purely RevenueCat code it started working again.

I suspect it's something to do with Purchasely also listening for StoreKit events, as I can see in the log output they are receiving receipts etc.

NachoSoto commented 11 months ago

That confirms the reason for this: you're configuring Purchasely to also finish transactions. See https://github.com/RevenueCat/purchases-ios/issues/2415#issuecomment-1579324706

If you want to use both SDKs, you need to either make sure that Purchasely doesn't finish transactions.

We added https://github.com/RevenueCat/purchases-ios/pull/3300 recently with a new log to make this more obvious. Can you confirm you saw this in your logs?

removedTransaction for xxx but no callbacks to notify. If the purchase completion block is not being invoked after this, it likely means that some other code outside of the RevenueCat SDK is calling SKPaymentQueue.finishTransaction, which is interfering with RevenueCat purchasing state handling

john-paradym commented 11 months ago

Thanks @NachoSoto

Just to wrap this up from my point of view (in case anyone else stumbles upon this):

  1. The additional logging was really helpful for us to determine for sure the issue - it was Purchasely interfering with the SK transaction
  2. Forcing Purchasely into using "StoreKit 1 mode" has appeared to have fixed the issue

I'm a bit worried that it's just a short-term fix, and that we will have interference problems again in the future, but for now we have both SDKs playing nicely with each other