Skip to content

in_app_purchase Pending Purchases must be enabled Exception #37821

@piano375

Description

@piano375

Steps to Reproduce

Trigger

Try to call .queryProductDetails() and queryPastPurchases() in the InAppPurchaseConnection.instance. Works correctly in iOS but throws an error in Android stating Support for pending purchases must be enabled. Enable this by calling 'enablePendingPurchases()' on BillingClientBuilder.

class Subscribe extends StatefulWidget {
  final User user;

  Subscribe({this.user});

  @override
  _SubscribeState createState() => _SubscribeState();
}

class _SubscribeState extends State<Subscribe> {
  bool showSpinner = true;
  InAppPurchaseConnection _iap = InAppPurchaseConnection.instance;
  bool _available = true;
  List<ProductDetails> _products = [];
  List<PurchaseDetails> _purchases = [];
  StreamSubscription _subscription;
  String storeID = 'chromaticStoreID';

  // Get available products (our monthly subscription)
  Future<void> _getProducts() async {
    Set<String> ids = <String>[storeID].toSet();
    ProductDetailsResponse response = await _iap.queryProductDetails(ids);
    print('Products Available: ${response.productDetails}');

    setState(() {
      _products = response.productDetails;
    });
  }

  // Get past purchase for restoring if already purchased
  Future<void> _getPastPurchases() async {
    QueryPurchaseDetailsResponse response = await _iap.queryPastPurchases();
    print('Past Purchase: ${response.pastPurchases}');

    for (PurchaseDetails purchase in response.pastPurchases) {
      if (Platform.isIOS) {
        _iap.completePurchase(purchase);
      }
    }
    setState(() {
      showSpinner = false;
      _purchases = response.pastPurchases;
    });
  }

  // Initialize the In app purchase module by loading products available and past purchases plus listening for any purchases
  void _iapInitialize() async {
    _available = await _iap.isAvailable();
    print('Available? -> $_available');

    if (_available) {
      await _getProducts();
      await _getPastPurchases();

      _verifyPurchase();

      _subscription = _iap.purchaseUpdatedStream.listen((data) => setState(() {
            print('New Purchase: $data');
            _purchases.addAll(data);
            _verifyPurchase();
          }));
    }
  }

  @override
  void initState() {
    super.initState();
    _iapInitialize();
  }

Logs

[  +17 ms] I/flutter (11387): Firebase login success!
[   +3 ms] I/flutter (11387): Removing User Cache from DB
[  +18 ms] I/flutter (11387): Not a Subscriber
[  +56 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): Failed to handle method call
[        ] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): java.lang.IllegalArgumentException:
Support for pending purchases must be enabled. Enable this by calling 'enablePendingPurchases()' on
BillingClientBuilder.
[   +1 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
com.android.billingclient.api.BillingClient$Builder.build(BillingClient.java:309)
[        ] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
io.flutter.plugins.inapppurchase.InAppPurchasePlugin.buildBillingClient(InAppPurchasePlugin.java:278)
[        ] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
io.flutter.plugins.inapppurchase.InAppPurchasePlugin.startConnection(InAppPurchasePlugin.java:126)
[   +1 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
io.flutter.plugins.inapppurchase.InAppPurchasePlugin.onMethodCall(InAppPurchasePlugin.java:89)
[   +1 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:222)
[   +8 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:96)
[        ] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:643)
[        ] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
android.os.MessageQueue.nativePollOnce(Native Method)
[        ] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
android.os.MessageQueue.next(MessageQueue.java:325)
[   +3 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
android.os.Looper.loop(Looper.java:142)
[   +1 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
android.app.ActivityThread.main(ActivityThread.java:6944)
[   +4 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
java.lang.reflect.Method.invoke(Native Method)
[   +1 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
[   +1 ms] E/MethodChannel#plugins.flutter.io/in_app_purchase(11387): 	at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)


 info • Unused import: 'package:flare_flutter/flare_actor.dart' •
          lib/components/broadcastTile.dart:12:8 • unused_import
   info • The value of the local variable 'playState' isn't used •
          lib/components/broadcastTile.dart:71:10 • unused_local_variable
   info • Unused import: 'package:listener/views/localNotification.dart' •
          lib/components/message.dart:5:8 • unused_import
   info • The value of the local variable 'playState' isn't used •
          lib/components/savedTile.dart:53:10 • unused_local_variable
   info • Unused import: 'package:flare_flutter/flare_actor.dart' • lib/views/homepage.dart:22:8
          • unused_import
   info • This function has a return type of 'FutureOr<User>', but doesn't end with a return
          statement • lib/views/login.dart:181:51 • missing_return
   info • This function has a return type of 'FutureOr<FirebaseUser>', but doesn't end with a
          return statement • lib/views/login.dart:186:51 • missing_return
   info • The member 'positions' can only be used within instance members of subclasses of
          'package:flutter/src/widgets/scroll_controller.dart' • lib/views/savedSongs.dart:96:27
          • invalid_use_of_protected_member

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.7.8+hotfix.4, on Mac OS X 10.14.5 18F132, locale en-US)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 10.3)
[✓] iOS tools - develop for iOS devices
[✓] Android Studio (version 3.4)
[✓] VS Code (version 1.36.1)
[✓] Connected device (1 available)

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions