In App Purchase
cashlinkml2021
plain_text
2 years ago
9.5 kB
17
Indexable
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,
),
);
}
}
Editor is loading...
Leave a Comment