Skip to main content

HiĀ Team/Community,

I have a issue at the moment where a user can not make a purchase on the Apple App Store in BOTH Production and Testing, which rules out Sandbox accounts etc (have also dived down said route).Ā  The same code is working perfectly for Android.Ā 

Things I have explored/tried:

  • Deleting and creating sandbox accounts for Apple.
  • Checked I have no outstanding agreements with Apple.
  • Made sure in-app purchases in enabled.
  • Tried configuringĀ the purchases_flutter package with both legacy and new api key.
  • I am sure a ton more, that I donā€™t remember.

The error looks as follows:

flutter: \^er38;5;12mā”‚ šŸ’” now trying to purchase<ā€¦>

oPurchases] - DEBUG: ā„¹ļø Vending Offerings from cache
Purchases] - DEBUG: ā„¹ļø makePurchase
øPurchases] - DEBUG: šŸ’° Purchasing product from package Ā - finMonitor_1500_1y_1w0 in Offering App Access
OPurchases] - DEBUG: ā„¹ļø PaymentQueue updatedTransaction: finMonitor_1500_1y_1w0 (null) ((null)) (null) - 0
<SKPaymentQueue: 0x2824dfa00>: Payment completed with error: Error Domain=ASDErrorDomain Code=500 "Unhandled exception" UserInfo={NSUnderlyingError=0x282863960 {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}
oPurchases] - DEBUG: ā„¹ļø PaymentQueue updatedTransaction: finMonitor_1500_1y_1w0 (null) (Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x2828602a0 {Error Domain=ASDErrorDomain Code=500 "Unhandled exception" UserInfo={NSUnderlyingError=0x282863960 {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}}}) (null) - 2
ePurchases] - ERROR: šŸŽā€¼ļø There was a problem with the App Store.
Purchases] - DEBUG: šŸ’° Finishing transaction finMonitor_1500_1y_1w0 (null) ((null))
iPurchases] - DEBUG: ā„¹ļø PaymentQueue removedTransaction: finMonitor_1500_1y_1w0 (null) ((null) Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x2828602a0 {Error Domain=ASDErrorDomain Code=500 "Unhandled exception" UserInfo={NSUnderlyingError=0x282863960 {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}}}) {
Ā  Ā  NSLocalizedDescription = "An unknown error occurred";
Ā  Ā  NSUnderlyingError = "Error Domain=ASDErrorDomain Code=500 \"Unhandled exception\" UserInfo={NSUnderlyingError=0x282863960 {Error Domain=AMSErrorDomain Code=301 \"Invalid Status Code\" UserInfo={NSLocalizedDescription=Invalid Status Code, NSLocalizedFailureReason=The response has an invalid status code}}, NSLocalizedFailureRea

flutter: \^pa38;5;196mā”‚ ā›” Paywall Upgrade - Exception caught: Error code PurchasesErrorCode.storeProblemError<ā€¦>

Ā 

Here is the code I am using to make the purchase:

onPressed: () async {  
showLoadingBanner(context, 'Purchase is progress...');
try {
loggerInfo(logMessage: 'now trying to purchase');
_purchaserInfo = await Purchases.purchasePackage(widget.package);

loggerInfo(logMessage: 'purchase completed');
paywallData.isPro = _purchaserInfo.entitlements.all "App Access"]!.isActive;

loggerDebug(logMessage: 'is user pro? ${paywallData.isPro}');

The code continues for some dialog handling etc, but it never reaches the loggerInfo(logMessage: 'purchase completed');

The widget.package is passed from the widget above, and is fetched as follows:

return FutureBuilder(
future: _fetchOfferings(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) {
Offerings offerings = snapshot.data;
final offering = offerings.current;
if (offering != null) {
final annual = offering.annual;
if (annual != null) {
return TopBarAgnosticNoIcon(
text: "Welcome!",
style: kSendButtonTextStyle(context),
uniqueHeroTag: 'purchase_screen',
child: Scaffold(
backgroundColor: Theme.of(context).backgroundColor,

body: Stack(children: r
Center(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget><
Padding(
padding: const EdgeInsets.all(18.0),
child: Image.asset("assets/logos/finMonitor_Transparent.png"),
),
Text(
'Select the subscription plan to get started.',
textAlign: TextAlign.center,
style: kSendButtonTextStyle(context),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: PurchaseButton(package: annual),

The code used for the _fetchOfferings future function is:

Future<Offerings?> _fetchOfferings() async {
Offerings? offerings;
try {
offerings = await Purchases.getOfferings();
} on PlatformException catch (e) {
loggerError(logMessage: 'Paywall Upgrade - _fetchOfferings: Exception caught $e');
if (Platform.isAndroid) {
_showSnackBar(context, 'Issue fetching information for purchase, please check you are signed into the play store');
} else {
_showSnackBar(context, 'Issue fetching information for purchase, please check you are signed into the app store');
}
}
return offerings;
}

Lastly the the SDK is configured as shown in the documentation, with a few conditional tweaks:

    await Purchases.setDebugLogsEnabled(true)
.whenComplete(() => loggerInfo(logMessage: 'setDebugLogsEnabled completed'));
if (Platform.isAndroid){
if ((username != null && username != '') && (password != null && password != '') && (custKey != null && custKey != '')) {
await Purchases.setup(apiAndroidRevenueKey, appUserId: '$username-$custKey');
}else{
await Purchases.setup(apiAndroidRevenueKey);
}

}
else if (Platform.isIOS){
if ((username != null && username != '') && (password != null && password != '') && (custKey != null && custKey != '')) {
await Purchases.setup(apiIosRevenueKey, appUserId: '$username-$custKey');
}else{
await Purchases.setup(apiIosRevenueKey);
}

loggerInfo(logMessage: 'After purchases.setup');
}

Any help will be hugely appreciated.

Ā 

To add Flutter Doctor also shows no errors or missing packages etc.


MaybeĀ 

Ā can help you


@Olympus SoftwareĀ That definitely could be related! Definitely gives me some more places to look and see whats going on.


Is anyone at RevenueCat able to assist me?


Heya, Iā€™ve done some digging, and this isnā€™t a RC-specific error. The error youā€™re seeing is coming back from Apple.Ā There are potentially many errorsā€¦Ā here is a (non-exhaustive) list Iā€™ve found:

  • If youā€™re testing in a sandbox with an account that has 2fa- disable itĀ šŸ™ƒ
  • Sandbox server might be temporarily down/misbehaving
  • You must be signed in to the App Store with the same user as specified in: Menu: Product > Scheme > Edit Scheme > Test > info > Debug Process as: <whatever name you have here>

  • Try again, youā€™re holding it wrongĀ 


Reply