chargebee_flutter 0.4.5 copy "chargebee_flutter: ^0.4.5" to clipboard
chargebee_flutter: ^0.4.5 copied to clipboard

This is the official Software Development Kit (SDK) for Chargebee Flutter.

example/lib/main.dart

import 'dart:async';
import 'dart:developer';

import 'package:chargebee_flutter/chargebee_flutter.dart';
import 'package:chargebee_flutter_sdk_example/Constants.dart';
import 'package:chargebee_flutter_sdk_example/alertDialog.dart';
import 'package:chargebee_flutter_sdk_example/items_listview.dart';
import 'package:chargebee_flutter_sdk_example/network_connectivity.dart';
import 'package:chargebee_flutter_sdk_example/product_ids_listview.dart';
import 'package:chargebee_flutter_sdk_example/product_listview.dart';
import 'package:chargebee_flutter_sdk_example/progress_bar.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) => MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const MyHomePage(title: 'Chargebee-Flutter SDK'),
      );
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({Key? key, required this.title}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController siteNameController = TextEditingController();
  final TextEditingController apiKeyController = TextEditingController();
  final TextEditingController sdkKeyController = TextEditingController();
  final TextEditingController iosDdkKeyController = TextEditingController();
  final TextEditingController productIdTextFieldController =
      TextEditingController();

  List<Product> products = [];
  late List<String> cbMenu = Constants.menu;
  late String siteName = '', apiKey = '', androidSdkKey = '', iosSdkKey = '';
  late String productIDs;
  late String userInput;
  late ProgressBarUtil mProgressBarUtil;

  final Map<String, String> queryParams = {
    'channel': 'play_store',
    'customer_id': 'abc'
  }; // sample query params for retrieveSubscriptions
  final Map<String, String> params = {
    'subscriptionId': 'AzZlGJTC9U3tw4nF'
  }; // eg. query params for entitlements
  final Map<String, String> itemsQueryParams = {
    'limit': '10',
    'channel[is]': 'play_store'
  }; // eg. query params for getAllItems, limit- default=100, min=1, max=100
  final Map<String, String> plansQueryParams = {
    'limit': '5',
    'channel[is]': 'play_store'
  }; // eg. query params for getAllPlans
  Map _source = {ConnectivityResult.none: false};
  final NetworkConnectivity _networkConnectivity = NetworkConnectivity.instance;
  String string = '';

  _MyHomePageState();

  @override
  void initState() {
    super.initState();
    _networkConnectivity.initialise();
    _networkConnectivity.myStream.listen((source) {
      _source = source;
      switch (_source.keys.toList()[0]) {
        case ConnectivityResult.mobile:
          string =
              _source.values.toList()[0] ? 'Mobile: Online' : 'Mobile: Offline';
          debugPrint(string);
          _verifyLocalCache();
          _configure();
          break;
        case ConnectivityResult.wifi:
          string =
              _source.values.toList()[0] ? 'WiFi: Online' : 'WiFi: Offline';
          debugPrint(string);
          _verifyLocalCache();
          _configure();
          break;
        case ConnectivityResult.none:
        default:
          string = 'Offline';
          debugPrint(string);
      }
    });
  }

  _verifyLocalCache() async {
    final prefs = await SharedPreferences.getInstance();
    final productId = prefs.getString('productId');
    final products = <String>['$productId'];
    if (productId != null) {
      retrieveProducts(products);
    } else {
      debugPrint('Local cache empty!');
    }
  }

  _configure() async {
    /// For both iOS and Android
    authentication('your-site', 'publishable_api_key', 'iOS ResourceID/SDK Key',
         'Android ResourceID/SDK Key',);
  }

  Future<void> retrieveProducts(List<String> productIDsList) async {
    try {
      final products = await Chargebee.retrieveProducts(productIDsList);
      debugPrint('result : $products');
      if (products.isNotEmpty &&
          products.first.subscriptionPeriod.unit.isNotEmpty &&
          products.first.subscriptionPeriod.numberOfUnits != 0) {
        validateReceipt(products.first.id);
      } else {
        validateNonSubscriptionReceipt(products.first.id);
      }
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    mProgressBarUtil = ProgressBarUtil(context);
    return Scaffold(
      appBar: AppBar(
        title: const Text('Chargebee- Flutter SDK Example'),
      ),
      body: ListView.builder(
        itemCount: cbMenu.length,
        itemBuilder: (context, pos) => Card(
          child: ListTile(
            title: Text(cbMenu[pos]),
            onTap: () {
              onItemClick(cbMenu[pos]);
            },
          ),
        ),
      ),
    );
  }

  onItemClick(String menuItem) {
    switch (menuItem) {
      case Constants.config:
        showAuthenticationDialog(context);
        break;

      case Constants.getProducts:
        showSkProductDialog(context);
        break;

      case Constants.getSubscriptionStatus:
        mProgressBarUtil.showProgressDialog();
        retrieveSubscriptions(queryParams);
        break;
      case Constants.getProductIdentifiers:
        mProgressBarUtil.showProgressDialog();
        retrieveProductIdentifers();
        break;
      case Constants.getEntitlements:
        mProgressBarUtil.showProgressDialog();
        retrieveEntitlements(params);
        break;
      case Constants.getAllPlans:
        mProgressBarUtil.showProgressDialog();
        retrieveAllPlans(plansQueryParams);
        break;
      case Constants.getAllItems:
        mProgressBarUtil.showProgressDialog();
        retrieveAllItems(itemsQueryParams);
        break;
      case Constants.restorePurchase:
        mProgressBarUtil.showProgressDialog();
        restorePurchases();
        break;
      case Constants.showManageSubscriptions:
        Chargebee.showManageSubscriptionsSettings();
        break;
      default:
        break;
    }
  }

  Future<void> authentication(
    String siteName,
    String apiKey, [
    String? iosSdkKey = '',
    String? androidSdkKey = '',
  ]) async {
    try {
      await Chargebee.configure(siteName, apiKey, iosSdkKey, androidSdkKey);
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');
    }
  }

  Future<void> getProducts(List<String> productIDsList) async {
    try {
      products = await Chargebee.retrieveProducts(productIDsList);
      debugPrint('result : $products');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
      if (products.isNotEmpty) {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (BuildContext context) =>
                ProductListView(products, title: 'Google Play-Product List'),
          ),
        );
      } else {
        _showDialog(context, 'Items not available to buy');
      }
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
    }
  }

  Future<void> retrieveProductIdentifers() async {
    try {
      final queryparam = <String, String>{'limit': '10'};
      final result = await Chargebee.retrieveProductIdentifiers(queryparam);
      log('result : $result');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }

      if (result.isNotEmpty) {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (BuildContext context) => ProductIdentifiersView(
              result,
              title: 'Product Identifiers List',
            ),
          ),
        );
      } else {
        _showDialog(context, 'Product Ids not avilable in chargebee');
      }
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
    }
  }

  Future<void> retrieveSubscriptions(Map<String, String> queryparam) async {
    try {
      final result = await Chargebee.retrieveSubscriptions(queryparam);
      debugPrint('result : $result');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
      if (result.isNotEmpty) {
        _showDialog(context, 'Subscriptions retrieved successfully!');
      } else {
        _showDialog(context, 'Subscription not found in Chargebee System');
      }
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');
      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
      _showDialog(context, '${e.message}');
    }
  }

  Future<void> retrieveEntitlements(Map<String, String> queryparam) async {
    try {
      final result = await Chargebee.retrieveEntitlements(queryparam);
      debugPrint('result : $result');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }

      if (result.isNotEmpty) {
        final entitlement = result.first.cbEntitlement;
        debugPrint('${entitlement?.subscriptionId}');
        debugPrint('${entitlement?.featureId}');
        debugPrint('${entitlement?.featureName}');
        debugPrint('${entitlement?.featureType}');
        debugPrint('${entitlement?.name}');
        debugPrint('${entitlement?.value}');
        debugPrint('${entitlement?.isOverridden}');
        debugPrint('${entitlement?.isEnabled}');
        _showDialog(context, 'entitlements retrieved successfully!');
      } else {
        _showDialog(context, 'Entitlements not found in system');
      }
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');
      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
      _showDialog(context, '${e.message}');
    }
  }

  Future<void> retrieveAllPlans(Map<String, String> queryparam) async {
    try {
      final result = await Chargebee.retrieveAllPlans(queryparam);
      debugPrint('result : $result');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
      final name = <String>[];
      if (result.isNotEmpty) {
        for (final cbPlan in result) {
          name.add(cbPlan != null ? cbPlan.name! : 'null');
        }
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (BuildContext context) =>
                ItemsView(name, title: 'List Plans'),
          ),
        );
      } else {
        _showDialog(context, 'Plans not available in chargebee');
      }
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');
      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
      _showDialog(context, '${e.message}');
    }
  }

  Future<void> retrieveAllItems(Map<String, String> queryparam) async {
    try {
      final result = await Chargebee.retrieveAllItems(queryparam);
      debugPrint('result : $result');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }

      final name = <String>[];
      if (result.isNotEmpty) {
        for (final cbItem in result) {
          name.add(cbItem != null ? cbItem.name! : 'null');
        }

        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (BuildContext context) =>
                ItemsView(name, title: 'List Items'),
          ),
        );
      } else {
        _showDialog(context, 'Items not available in chargebee');
      }
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
      _showDialog(context, '${e.message}');
    }
  }

  Future<void> restorePurchases() async {
    try {
      final customer = CBCustomer(
        'Test123',
        'CB',
        'Test',
        'cbTest@chargebee.com',
      );
      final result = await Chargebee.restorePurchases(true, customer);
      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
      if (result.isNotEmpty) {
        for (final subscription in result) {
          if (subscription.storeStatus == StoreStatus.active) {
            debugPrint('Active Subscriptions : $subscription');
          } else {
            debugPrint('All Subscriptions : $subscription');
          }
        }
        _showDialog(
            context, '${result.length} Purchases Restored Successfully');
      } else {
        _showDialog(context, 'Purchase not found to restore');
      }
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');

      if (mProgressBarUtil.isProgressBarShowing()) {
        mProgressBarUtil.hideProgressDialog();
      }
    }
  }

  Future<void> validateReceipt(String productId) async {
    try {
      final customer = CBCustomer(
        '',
        '',
        '',
        '',
      );
      final result = await Chargebee.validateReceipt(productId, customer);
      debugPrint('subscription result : $result');
      debugPrint('subscription id : ${result.subscriptionId}');
      debugPrint('plan id : ${result.planId}');
      debugPrint('subscription status : ${result.status}');
      mProgressBarUtil.hideProgressDialog();

      /// if validateReceipt success, clear the cache
      final prefs = await SharedPreferences.getInstance();
      prefs.remove('productId');
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');
      mProgressBarUtil.hideProgressDialog();
    }
  }

  Future<void> validateNonSubscriptionReceipt(String productId) async {
    try {
      const productType = ProductType.non_consumable;
      final customer = CBCustomer(
        '',
        '',
        '',
        '',
      );
      final result = await Chargebee.validateReceiptForNonSubscriptions(
          productId, productType, customer);
      debugPrint('subscription result : $result');
    } on PlatformException catch (e) {
      debugPrint(
          'Error Message: ${e.message}, Error Details: ${e.details}, Error Code: ${e.code}');
      mProgressBarUtil.hideProgressDialog();
    }
  }

  _showDialog(BuildContext context, String message) {
    final alert = BaseAlertDialog('Chargebee', message);
    showDialog(
      context: context,
      builder: (BuildContext context) => alert,
    );
  }

  showSkProductDialog(BuildContext context) => showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: const Text('Please enter Product Ids(Comma separated)'),
          content: TextField(
            onChanged: (value) {
              setState(() {
                productIDs = value.trim();
              });
            },
            controller: productIdTextFieldController,
            decoration: const InputDecoration(hintText: "Product ID's"),
          ),
          actions: <Widget>[
            TextButton(
              style: TextButton.styleFrom(
                foregroundColor: Colors.white,
                backgroundColor: Colors.red,
                textStyle: const TextStyle(fontStyle: FontStyle.normal),
              ),
              child: const Text('CANCEL'),
              onPressed: () {
                setState(() {
                  Navigator.pop(context);
                });
              },
            ),
            TextButton(
              style: TextButton.styleFrom(
                foregroundColor: Colors.white,
                backgroundColor: Colors.green,
                textStyle: const TextStyle(fontStyle: FontStyle.normal),
              ),
              child: const Text('OK'),
              onPressed: () {
                setState(() {
                  try {
                    Navigator.pop(context);
                    debugPrint('productIds from user : $productIDs');
                    mProgressBarUtil.showProgressDialog();

                    final listItems = productIDs.split(',');
                    getProducts(listItems);
                    productIdTextFieldController.clear();
                  } catch (e) {
                    log('error : ${e.toString()}');
                  }
                });
              },
            ),
          ],
        ),
      );

  Future<void> showAuthenticationDialog(BuildContext context) async =>
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: const Text('Chargebee'),
          content: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              TextField(
                onChanged: (value) {
                  setState(() {
                    siteName = value;
                  });
                },
                controller: siteNameController,
                decoration: const InputDecoration(hintText: 'Site Name'),
              ),
              TextField(
                onChanged: (value) {
                  setState(() {
                    apiKey = value;
                  });
                },
                controller: apiKeyController,
                decoration: const InputDecoration(hintText: 'API Key'),
              ),
              TextField(
                onChanged: (value) {
                  setState(() {
                    iosSdkKey = value;
                  });
                },
                controller: iosDdkKeyController,
                decoration: const InputDecoration(
                  hintText: 'iOS SDK Key',
                ),
              ),
              TextField(
                onChanged: (value) {
                  setState(() {
                    androidSdkKey = value;
                  });
                },
                controller: sdkKeyController,
                decoration: const InputDecoration(
                  hintText: 'Android SDK Key',
                ),
              ),
            ],
          ),
          actions: <Widget>[
            TextButton(
              style: TextButton.styleFrom(
                foregroundColor: Colors.white,
                backgroundColor: Colors.red,
                textStyle: const TextStyle(fontStyle: FontStyle.normal),
              ),
              child: const Text('CANCEL'),
              onPressed: () {
                setState(() {
                  Navigator.pop(context);
                });
              },
            ),
            TextButton(
              style: TextButton.styleFrom(
                foregroundColor: Colors.white,
                backgroundColor: Colors.green,
                textStyle: const TextStyle(fontStyle: FontStyle.normal),
              ),
              child: const Text('Initialize'),
              onPressed: () {
                Navigator.pop(context);
                debugPrint(
                  'app details : $siteName, $apiKey, $androidSdkKey, $iosSdkKey',
                );
                authentication(
                  siteName,
                  apiKey,
                  iosSdkKey,
                  androidSdkKey,
                );
              },
            )
          ],
        ),
      );
}
6
likes
140
pub points
76%
popularity

Publisher

verified publisherchargebee.com

This is the official Software Development Kit (SDK) for Chargebee Flutter.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

collection, flutter, json_annotation, progress_dialog_null_safe

More

Packages that depend on chargebee_flutter