In App Purchase

 avatar
cashlinkml2021
plain_text
7 months ago
9.5 kB
11
Indexable
Never
class InAppProductsScreen extends StatefulWidget {

  @override
  State<InAppProductsScreen> createState() => _InAppProductsScreenState();
}

class _InAppProductsScreenState extends State<InAppProductsScreen> {
  List<String> _kProductIds = [];
  final bool _kAutoConsume = Platform.isIOS || true;
  final InAppPurchase _inAppPurchase = InAppPurchase.instance;
  List<ProductDetails> _products = <ProductDetails>[];
  bool _isAvailable = false;
  bool _loading = true;
  StreamSubscription<List<PurchaseDetails>>? _subscription;

  bool isProcessing = false;
  bool pendingOrder = false;
  String orderID = 'Test Order ID = GPA-ABCD-1234-XYZ-09876';
  int quantity = 1;
  User? currentUser = FirebaseAuth.instance.currentUser;

  @override
  void initState() {
    getProductIdsFromFirestore();
    _subscription = InAppPurchase.instance.purchaseStream.listen((List<PurchaseDetails> purchaseDetailsList) {
      _listenToPurchaseUpdated(purchaseDetailsList);
    });
    super.initState();
  }


  void getProductIdsFromFirestore() async {
    final CollectionReference productsCollection = FirebaseFirestore.instance.collection('InAppProduct');
    QuerySnapshot querySnapshot = await productsCollection.get();
    List<String> productIds = [];
    for (DocumentSnapshot documentSnapshot in querySnapshot.docs) {
      String productId = documentSnapshot['ID'];
      productIds.add(productId);
    }
    _kProductIds.addAll(productIds);
    initStoreInfo();
  }


  Future<void> initStoreInfo() async {
    final bool isAvailable = await _inAppPurchase.isAvailable();

    final ProductDetailsResponse productDetailResponse = await _inAppPurchase.queryProductDetails(_kProductIds.toSet());

    setState(() {
      _isAvailable = isAvailable;
      _products = productDetailResponse.productDetails;
      _loading = false;
    });
  }

  void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async{
    purchaseDetailsList.forEach((PurchaseDetails purchaseDetails) async {

      if (purchaseDetails.status == PurchaseStatus.pending) {
        await _inAppPurchase.completePurchase(purchaseDetails);
        setState(() {
          isProcessing = false;
          quantity = 1;
          pendingOrder = true;
          orderID = purchaseDetails.purchaseID!;
        });


        print('Pending');

      } else if (purchaseDetails.status == PurchaseStatus.error) {
        // Handle purchase error here
        setState(() {
          isProcessing = false;
          quantity = 1;
        });
        VxToast.show(context, msg: 'Purchase Error',bgColor: kPrimaryLightColors);
        print('Error');


      }else if (purchaseDetails.status == PurchaseStatus.canceled){
        setState(() {
          isProcessing = false;
          quantity = 1;
        });
        VxToast.show(context, msg: 'Purchase Canceled',bgColor: kPrimaryLightColors);
        print('Cancel');


      }

      if (purchaseDetails.pendingCompletePurchase) {
        await _inAppPurchase.completePurchase(purchaseDetails);

        var product = await FirebaseFirestore.instance.collection('InAppProduct').doc(purchaseDetails.productID).get();
        FirebaseFirestore.instance.collection('About-Info').doc('TotalBalance').update({
          'Balance' : FieldValue.increment(product['Price'] * quantity),
        });

        setState(() {
          isProcessing = false;
          quantity = 1;
        });

        VxToast.show(context, msg: 'Purchase Successfull ${product['Price'] * quantity}',bgColor: kPrimaryLightColors);

      }

    });
  }



  @override
  void dispose() {
    _subscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Scaffold(
      appBar: AppBar(
        title: Text('Products',style: TextStyle(
            color: Colors.white
        ),),
        backgroundColor: kPrimaryColors,
        elevation: 0,
      ),
      body: ListView(
        children: <Widget>[

          _buildProductList(),
        ],
      ),
    );
  }

  Card _buildProductList() {
    if (_loading) {
      return const Card(
          child: ListTile(
              leading: CircularProgressIndicator(color: kPrimaryColors,),
              title: Text('Fetching products...')));
    }

    _products.sort((a, b) => a.rawPrice.compareTo(b.rawPrice));
    final List<ListTile> productList = <ListTile>[];

    productList.addAll(_products.map(
          (ProductDetails productDetails) {
        return ListTile(
          title: Text('Purchase ${productDetails.price}',style: TextStyle(
              fontSize: MediaQuery.of(context).size.width * 0.045,
              color: Colors.black54
          )
          ),
          subtitle: Text(
              productDetails.description,style: TextStyle(
              fontSize: MediaQuery.of(context).size.width * 0.04,
              color: Colors.black54
          )
          ),
          trailing: TextButton(
            style: TextButton.styleFrom(
              backgroundColor: Colors.green[800],
              primary: Colors.white,
            ),
            onPressed: () async {

              late PurchaseParam purchaseParam;
              purchaseParam = GooglePlayPurchaseParam(productDetails: productDetails, changeSubscriptionParam: null);

              _inAppPurchase.buyConsumable(
                purchaseParam: purchaseParam,
                autoConsume: _kAutoConsume,
              );

              setState(() {
                isProcessing = true;
              });

            },
            child: Text(productDetails.price),
          ),
        );
      },
    ));

    return Card(
      child:Column(
        children: <Widget>[

          if(isProcessing)...[
            Divider(),
            Container(
              margin: EdgeInsets.symmetric(
                  horizontal: MediaQuery.of(context).size.width * 0.2
              ),
              child: Row(
                children: [
                  CircularProgressIndicator(),
                  SizedBox(width: 10,),
                  Text('Processing... ',style: TextStyle(
                      fontSize: MediaQuery.of(context).size.width * 0.05,
                      color: Colors.green
                  )),
                ],
              ),
            ),
            SizedBox(height: 5,),
            Divider(),
          ],

          if(pendingOrder)...[
            Divider(),
            Text(orderID,style: TextStyle(
                fontSize: MediaQuery.of(context).size.width * 0.04,
                color: Colors.black54
            ),),
            Text('আপনার অর্ডারটি Pending হয়ে গেছে\nস্ক্রিনশর্ট নিন এবং আপনার এডমিন কে জমা দিন',style: TextStyle(
                fontSize: MediaQuery.of(context).size.width * 0.04,
                color: Colors.red
            )),
            SizedBox(height: 5,),
            GestureDetector(
              onTap: (){
                setState(() {
                  pendingOrder = false;
                  orderID = '';
                });
              },
              child: Container(
                width: double.infinity,
                color: Colors.lightGreen[100],
                padding: EdgeInsets.symmetric(
                    vertical: MediaQuery.of(context).size.width * 0.01
                ),
                child: Center(child: Text('Close',style: TextStyle(
                    color: Colors.black54,
                    fontSize: MediaQuery.of(context).size.width * 0.04
                ),)),
              ),
            ),
            Divider(),
          ],

          Container(
            margin: EdgeInsets.symmetric(
                horizontal: MediaQuery.of(context).size.width * 0.047
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [

                IconButton(
                    onPressed: (){
                      setState(() {
                        quantity = quantity - 1;
                      });
                    },
                    icon: Icon(Icons.remove)
                ),

                Text('Qt ${quantity}',style: TextStyle(
                    fontWeight: FontWeight.bold
                ),),

                IconButton(
                    onPressed: (){
                      setState(() {
                        quantity = quantity + 1;
                      });
                    },
                    icon: Icon(Icons.add)
                ),


                //Restore Purchase
                ShortButton(
                  text: 'Restore Purchase',
                  press: (){
                    _inAppPurchase.restorePurchases();
                    VxToast.show(context, msg: 'Restore Success',bgColor: kPrimaryLightColors);

                    // Navigator.push(context, MaterialPageRoute(builder: (context)=>ShowCustomAlert()));
                  },
                  fontSize: 0.04,
                )
              ],
            ),
          )

        ] + productList,
      ),
    );

  }
}


Leave a Comment