Solved

Unable to Purchase Package with Flutter SDK

  • 13 December 2021
  • 2 replies
  • 190 views

Badge +2

Hi RevenueCat, I’m glad that RevenueCat exists to help bridge the gap for in-app payment/subscription on the different platforms. For my app, I’m currently using Flutter SDK to get in-app auto-renewable subscription setup for both Android and iOS. I have read through the setup docs and have already done the setup, and I’m testing this locally in iOS simulator on iOS 15/14.5.

I’m aware that iOS 13 and below, is not compatible with testing in iOS simulator but with 14 and above, it should be compatible. I’m using the latest flutter SDK (purchases_flutter: ^3.8.0)

These are the following things done:

App Store Connect:

  • In-app purchase package creation
  • App-specific shared secret

Xcode:

  • Adding In-app purchase feature
  • Package setup
  • StoreKit configuration

RevenueCat:

  • Bundle ID setup
  • Package creation to be the same as App Store connect
  • Uploaded StoreKit public cert

I am able to retrieve the packages that are setup in the Flutter app correctly. However, when the code is called for Purchases.purchasePackage, it triggers the IAP and within the iOS prompt, it prompted successful purchase, and I am able to see the purchase transaction in the transactions within Xcode. However, it seems to return an error on the RevenueCat side when validating purchase receipt.

The error in the logs:

2021-12-13 11:59:35.622705+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ Vending Offerings from cache
2021-12-13 11:59:35.633267+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ Vending PurchaserInfo from cache.
2021-12-13 11:59:35.764465+0800 Runner[92486:31259270] flutter: purchaser info: PurchaserInfo{entitlements: EntitlementInfos{all: {}, active: {}}, latestExpirationDate: null, allExpirationDates: {}, allPurchaseDates: {}, activeSubscriptions: [], allPurchasedProductIdentifiers: [], firstSeen: 2021-12-13T03:58:57Z, originalAppUserId: $RCAnonymousID:19f6709fe8ba414090b936de95a42aaf, requestDate: 2021-12-13T03:58:57Z, originalApplicationVersion: null, originalPurchaseDate: null, managementURL: null, nonSubscriptionTransactions: []}
2021-12-13 11:59:35.767206+0800 Runner[92486:31259270] flutter: done loading... {default_offering: Offering{identifier: default_offering, serverDescription: The default offering to users, availablePackages: [Package{identifier: $rc_monthly, packageType: PackageType.monthly, product: Product{identifier: pockettdevPlus2021Monthly, description: , title: , price: 3.990000009536743, priceString: $3.99, currencyCode: USD, introductoryPrice: IntroductoryPrice{introPrice: 0.0, introPriceString: $0.00, introPricePeriod: P1W, introPricePeriodUnit: WEEK, introPricePeriodNumberOfUnits: 1, introPriceCycles: 1}}, offeringIdentifier: default_offering}, Package{identifier: $rc_annual, packageType: PackageType.annual, product: Product{identifier: pockettdevPlusYearly2021, description: , title: , price: 35.9900016784668, priceString: $35.99, currencyCode: USD, introductoryPrice: IntroductoryPrice{introPrice: 0.0, introPriceString: $0.00, introPricePeriod: P2W, introPricePeriodUnit: WEEK, introPricePeriodNumberOfUnits: 2, introPriceCycles: 1}}, offeringIdentifier: default_offering}], lifetime: null, annual: Package{identifier: $rc_annual, packageType: PackageType.annual, product: Product{identifier: pockettdevPlusYearly2021, description: , title: , price: 35.9900016784668, priceString: $35.99, currencyCode: USD, introductoryPrice: IntroductoryPrice{introPrice: 0.0, introPriceString: $0.00, introPricePeriod: P2W, introPricePeriodUnit: WEEK, introPricePeriodNumberOfUnits: 2, introPriceCycles: 1}}, offeringIdentifier: default_offering}, sixMonth: null, threeMonth: null, twoMonth: null, monthly: Package{identifier: $rc_monthly, packageType: PackageType.monthly, product: Product{identifier: pockettdevPlus2021Monthly, description: , title: , price: 3.990000009536743, priceString: $3.99, currencyCode: USD, introductoryPrice: IntroductoryPrice{introPrice: 0.0, introPriceString: $0.00, introPricePeriod: P1W, introPricePeriodUnit: WEEK, introPricePeriodNumberOfUnits: 1, introPriceCycles: 1}}, offeringIdentifier: default_offering}, weekly: null}}
2021-12-13 11:59:35.768842+0800 Runner[92486:31259270] flutter: 1 WEEK
2021-12-13 11:59:35.769674+0800 Runner[92486:31259270] flutter: 2 WEEK
2021-12-13 11:59:37.648316+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ Vending Offerings from cache
2021-12-13 11:59:37.650047+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ makePurchase
2021-12-13 11:59:37.651898+0800 Runner[92486:31258474] [Purchases] - DEBUG: 💰 Purchasing product from package - pockettdevPlusYearly2021 in Offering default_offering
2021-12-13 11:59:37.655581+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ PaymentQueue updatedTransaction: pockettdevPlusYearly2021 (null) ((null)) (null) - 0
2021-12-13 11:59:38.028223+0800 Runner[92486:31258474] Sentry - debug:: Persisting lastInForeground: 2021-12-13T03:59:38.028Z
2021-12-13 11:59:38.035232+0800 Runner[92486:31259270] flutter: check life cycle: AppLifecycleState.inactive
2021-12-13 11:59:43.005117+0800 Runner[92486:31258474] Sentry - debug:: Add breadcrumb: <SentryBreadcrumb: 0x600001a31ac0>
2021-12-13 11:59:43.005832+0800 Runner[92486:31258474] Sentry - debug:: Add breadcrumb: <SentryBreadcrumb: 0x600001a52b40>
2021-12-13 11:59:43.006788+0800 Runner[92486:31258474] Sentry - debug:: Add breadcrumb: <SentryBreadcrumb: 0x600001a43780>
2021-12-13 11:59:43.006952+0800 Runner[92486:31258474] Sentry - debug:: Reading timestamp of last in foreground at: /Users/alvin/Library/Developer/CoreSimulator/Devices/52CC8D1A-53DD-4BA2-B2C9-7012D92528F0/data/Containers/Data/Application/FBA80A19-583F-4968-A7D1-182B192FF63C/Library/Caches/io.sentry/8769ed6c3192ec94c2bdd2bec1c78d718b1f5168/lastInForeground.timestamp
2021-12-13 11:59:43.007239+0800 Runner[92486:31258474] Sentry - debug:: Deleting LastInForeground at: /Users/alvin/Library/Developer/CoreSimulator/Devices/52CC8D1A-53DD-4BA2-B2C9-7012D92528F0/data/Containers/Data/Application/FBA80A19-583F-4968-A7D1-182B192FF63C/Library/Caches/io.sentry/8769ed6c3192ec94c2bdd2bec1c78d718b1f5168/lastInForeground.timestamp
2021-12-13 11:59:43.007568+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ applicationDidBecomeActive
2021-12-13 11:59:43.007837+0800 Runner[92486:31259270] flutter: check life cycle: AppLifecycleState.resumed
2021-12-13 11:59:43.026720+0800 Runner[92486:31258474] Sentry - debug:: Persisting lastInForeground: 2021-12-13T03:59:43.027Z
2021-12-13 11:59:43.028364+0800 Runner[92486:31259270] flutter: check life cycle: AppLifecycleState.inactive
2021-12-13 11:59:44.769396+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ PaymentQueue updatedTransaction: pockettdevPlusYearly2021 0 ((null)) (null) - 1
2021-12-13 11:59:44.784585+0800 Runner[92486:31258474] [db] _LSSchemaConfigureForStore failed with error Error Domain=NSOSStatusErrorDomain Code=-10817 "(null)" UserInfo={_LSFunction=_LSSchemaConfigureForStore, ExpectedSimulatorHash={length = 32, bytes = 0x5e935dd2 25d8e25a 8d5ae46a d8b12b19 ... 01283238 4508f794 }, _LSLine=409, WrongSimulatorHash={length = 32, bytes = 0xde46d38b d4a53d76 616b84c1 fa2ca9ac ... 77f829e8 8f8d0cc8 }}
2021-12-13 11:59:44.785525+0800 Runner[92486:31258474] [db] Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-10817 "(null)" UserInfo={_LSFunction=_LSSchemaConfigureForStore, ExpectedSimulatorHash={length = 32, bytes = 0x5e935dd2 25d8e25a 8d5ae46a d8b12b19 ... 01283238 4508f794 }, _LSLine=409, WrongSimulatorHash={length = 32, bytes = 0xde46d38b d4a53d76 616b84c1 fa2ca9ac ... 77f829e8 8f8d0cc8 }}
2021-12-13 11:59:44.786321+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ Loaded receipt from url (null)
2021-12-13 11:59:44.786569+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ Receipt empty, refreshing
2021-12-13 11:59:44.808913+0800 Runner[92486:31258474] [db] _LSSchemaConfigureForStore failed with error Error Domain=NSOSStatusErrorDomain Code=-10817 "(null)" UserInfo={_LSFunction=_LSSchemaConfigureForStore, ExpectedSimulatorHash={length = 32, bytes = 0x5e935dd2 25d8e25a 8d5ae46a d8b12b19 ... 01283238 4508f794 }, _LSLine=409, WrongSimulatorHash={length = 32, bytes = 0xde46d38b d4a53d76 616b84c1 fa2ca9ac ... 77f829e8 8f8d0cc8 }}
2021-12-13 11:59:44.809034+0800 Runner[92486:31258474] [db] Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-10817 "(null)" UserInfo={_LSFunction=_LSSchemaConfigureForStore, ExpectedSimulatorHash={length = 32, bytes = 0x5e935dd2 25d8e25a 8d5ae46a d8b12b19 ... 01283238 4508f794 }, _LSLine=409, WrongSimulatorHash={length = 32, bytes = 0xde46d38b d4a53d76 616b84c1 fa2ca9ac ... 77f829e8 8f8d0cc8 }}
2021-12-13 11:59:44.809242+0800 Runner[92486:31258474] [Purchases] - DEBUG: ℹ️ Loaded receipt from url (null)
2021-12-13 11:59:44.809427+0800 Runner[92486:31258474] [Purchases] - WARN: 🍎‼️ Unable to load receipt, ensure you are logged in to a valid Apple account.
2021-12-13 11:59:44.809835+0800 Runner[92486:31258474] [Purchases] - ERROR: 🍎‼️ The receipt is missing.
2021-12-13 11:59:44.814199+0800 Runner[92486:31259270] flutter: purchase cancelled

I was also unable to login with the sandbox account I created, in iOS simulator. It returns “User name or password is incorrect”. However, the password is actually correct, as when I’ve input a wrong password, it displays a dialog message “Your Apple ID or password is incorrect”.

 

I have checked through other forum tickets here and it does not seem to help the issue here.

I’m running out of ideas how I can resolve this, would appreciate any assistance I can get here. Thank you.

icon

Best answer by ryan 14 December 2021, 00:53

View original

2 replies

Userlevel 5
Badge +9

Hey @Alvin!

From the error in your logs, it does appear to be related to the sandbox account that you’re using to test the purchases:

WARN: 🍎‼️ Unable to load receipt, ensure you are logged in to a valid Apple account.

 

A couple things I would try:

  1. Use a physical device for testing instead of a simulator. There are issues with some simulators and using a real device can rule these out.
  2. Try creating a new sandbox account in App Store Connect. Sometimes sandbox accounts fine themselves in an unrecoverable state for whatever reason so it can be a good debugging step to create a new sandbox user as well.
Badge +2

Hi Ryan,

Thanks for the suggestion. Indeed, it only worked on an actual iPhone. If only Apple can provide receipt verification in simulator to close the loop hopefully in future version.

Thanks again.

Reply