In this Flutter application we will show you a Pizza Application which will get the Data from Firebase and Integrate RazorPay Payment gateway.
What we will learn
Let's get started
Step 1: Create a flutter application in your respected IDE , here i have used Android studio
Step 2: Add required packages in pubspec.yaml file
google_fonts: ^2.1.0 intl: ^0.17.0 url_launcher: cloud_firestore: ^2.5.3 firebase_core: ^1.7.0 razorpay_flutter: ^1.2.7 |
Step 3: Implement UI
In this application we have two screens
Let's create List of Pizza screen
SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Hello User', style: poppinsTextStyle.copyWith( fontSize: 24, fontWeight: FontWeight.w500, color: blackColor, ), ), Text( 'Yummy pizza delivered fast & fresh', style: poppinsTextStyle.copyWith( fontSize: 18, fontWeight: FontWeight.w500, color: greyColor, ), ), const SizedBox(height: 22), Text( 'Recomended Menu', style: poppinsTextStyle.copyWith( fontSize: 18, fontWeight: FontWeight.w400, color: blackColor, ), ), const SizedBox(height: 22),
Column(
// ignore: unnecessary_cast
children:[]),
const SizedBox(height: 20), ], ), ) |
This will show the Home screen, at present it can't show any pizza list, because we were not implemented any logic to fetch data from firebase.
Design Pizza Details screen
Let' design our details page
import 'package:flutter/material.dart'; import 'package:foodsapp/models/menu.dart'; import 'package:foodsapp/models/size.dart'; import 'package:foodsapp/theme.dart'; import 'package:foodsapp/widgets/size_card.dart'; import 'package:intl/intl.dart'; import 'package:url_launcher/url_launcher.dart'; import 'checkout.dart'; // ignore: must_be_immutable class DetailScreen extends StatefulWidget { Menu menu; DetailScreen( this.menu, {Key? key}) : super(key: key); @override State<DetailScreen> createState() => // ignore: no_logic_in_create_state _DetailScreen(); } class _DetailScreen extends State<DetailScreen> { _DetailScreen(); launchUrl(String url) async { launch(url); } int i = 1; int price =0; int pricePromo =0; int dataPrice =0; int dataPricePromo=0 ; bool isMini = true; bool isSedang = false; bool isBesar = false; bool isSuperBesar = false; @override void initState() { // TODO: implement initState super.initState(); price=widget.menu.price; dataPrice=widget.menu.price; pricePromo=widget.menu.pricePromo; dataPricePromo=widget.menu.pricePromo; } void _minus() { setState(() { if (i > 1) { i--; if (isMini == true) { price = dataPrice * i; pricePromo = dataPricePromo * i; } else if (isSedang == true) { price = (dataPrice ) * i; pricePromo = (dataPricePromo ) * i; } else if (isBesar == true) { price = (dataPrice ) * i; pricePromo = (dataPricePromo ) * i; } else if (isSuperBesar == true) { price = (dataPrice ) * i; pricePromo = (dataPricePromo ) * i; } } }); } void _plus() { setState(() { i++; if (isMini == true) { price = dataPrice * i; pricePromo = dataPricePromo * i; } else if (isSedang == true) { price = (dataPrice ) * i; pricePromo = (dataPricePromo ) * i; } else if (isBesar == true) { price = (dataPrice ) * i; pricePromo = (dataPricePromo ) * i; } else if (isSuperBesar == true) { price = (dataPrice ) * i; pricePromo = (dataPricePromo ) * i; } }); } void _clickMini() { setState(() { }); } void _clickSedang() { setState(() { }); } void _clickBesar() { setState(() { }); } void _clickSuperBesar() { setState(() { }); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Stack( children: [ Image.network( widget.menu.image, width: MediaQuery.of(context).size.width, fit: BoxFit.cover, ), ListView( children: [ const SizedBox(height: 264), Container( width: MediaQuery.of(context).size.width, decoration: const BoxDecoration( borderRadius: BorderRadius.vertical( top: Radius.circular(20), ), color: Colors.white, ), child: Column( children: [ Padding( padding: const EdgeInsets.symmetric( vertical: 30, horizontal: 24, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( 'assets/promo.png', width: 60, ), const SizedBox(height: 8), Row( children: [ Expanded( child: Text( widget.menu.name, style: poppinsTextStyle.copyWith( fontSize: 18, fontWeight: FontWeight.w500, color: blackColor, ), ), ), InkWell( onTap: _minus, child: Image.asset( 'assets/minus.png', width: 34, ), ), const SizedBox(width: 16), Text( '$i', style: poppinsTextStyle.copyWith( fontSize: 22, fontWeight: FontWeight.w500, color: blackColor, ), ), const SizedBox(width: 16), InkWell( onTap: _plus, child: Image.asset( 'assets/plus.png', width: 34, ), ), ], ), const SizedBox(height: 12), Row( children: [ Text( NumberFormat.currency( locale: 'id', symbol: 'Rs ', decimalDigits: 0) .format(price), style: poppinsTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.w500, color: greyColor, decoration: TextDecoration.lineThrough, ), ), const SizedBox(width: 4), Text( NumberFormat.currency( locale: 'id', symbol: 'Rs ', decimalDigits: 0) .format(pricePromo), style: poppinsTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.w500, color: yellowColor, ), ), ], ), const SizedBox(height: 18), Text( 'Choose Options', style: poppinsTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.w500, color: blackColor, ), ), const SizedBox(height: 12), SizedBox( height: 40, child: ListView( scrollDirection: Axis.horizontal, shrinkWrap: true, children: [ InkWell( onTap: _clickMini, child: SizeCard( Size( id: 1, name: 'Veg', isActive: isMini, ), ), ), const SizedBox(width: 12), InkWell( onTap: _clickSedang, child: SizeCard( Size( id: 2, name: 'Non Veg', isActive: isSedang, ), ), ), const SizedBox(width: 12), InkWell( onTap: _clickBesar, child: SizeCard( Size( id: 3, name: 'Side Order', isActive: isBesar, ), ), ), const SizedBox(width: 12), InkWell( onTap: _clickSuperBesar, child: SizeCard( Size( id: 4, name: 'Beverages', isActive: isSuperBesar, ), ), ), ], ), ), const SizedBox(height: 18), Text( 'About Product', style: poppinsTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.w500, color: blackColor, ), ), const SizedBox(height: 12), // ignore: sized_box_for_whitespace Container( width: MediaQuery.of(context).size.width, child: Text( widget.menu.note, style: poppinsTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.w300, color: greyColor, ), ), ), const SizedBox(height: 18), Text( 'Lokasi Burger Jawa', style: poppinsTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.w500, color: blackColor, ), ), const SizedBox(height: 12), InkWell( onTap: () { launchUrl('https://www.dominos.co.in/?share'); }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Image.asset( 'assets/store.png', width: 50, ), const SizedBox(width: 18), Expanded( child: Text( 'Domino''s Pizza India, ower-D, Plot No. 5,', style: poppinsTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.w500, color: greyColor, ), ), ), const Spacer(), IconButton( onPressed: () {}, icon: Icon( Icons.chevron_right, color: greyColor, size: 30, ), ), ], ), ), const SizedBox(height: 40), // ignore: sized_box_for_whitespace Container( width: MediaQuery.of(context).size.width, // ignore: deprecated_member_use child: RaisedButton( padding: const EdgeInsets.only( top: 12, bottom: 12, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18), ), elevation: 0, focusElevation: 0, hoverElevation: 0, disabledElevation: 0, highlightElevation: 0, onPressed: () async{ var result=await Navigator.push(context, MaterialPageRoute(builder: (context){ return CheckoutScreen(widget.menu); })); print("result $result"); if(result['status']==1||result['status']==2) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Order Placed Success"),)) ; Navigator.pop(context); } else if(result['status']==0) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Order Placed failed, please try again"),)) ; }, color: yellowColor, child: Text( 'Order', style: poppinsTextStyle.copyWith( fontSize: 18, fontWeight: FontWeight.w500, color: whiteColor, ), ), ), ), ], ), ), ], ), ), ], ), Padding( padding: const EdgeInsets.all(20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: () { Navigator.of(context).pop(); }, child: Image.asset('assets/btn_back.png', width: 40), ), InkWell( onTap: () {}, child: Image.asset('assets/btn_share.png', width: 40), ), ], ), ), ], ), ), ); } } |
Step 4: Integrate Firebase data with flutter
We are ready with our design part, now we need to create our data on the Firebase database. Read here about Integrate firebase with flutter.
Our database consist of below fields
Step 5: Fetch data from Firebase
Now we are ready with UI and Pizza database, let's add functionality to fetch live data from firebase data. To fetch data from firebase we are using the streambuilder widget
First we need to create instance of FirebaseFirestore and CollectionReference respectively
FirebaseFirestore firestore = FirebaseFirestore.instance; CollectionReference products = firestore.collection('products'); |
StreamBuilder<QuerySnapshot>( stream: products.orderBy('id', descending: false).snapshots(), builder: (_, snapshot) { if (snapshot.hasData) { return Column( // ignore: unnecessary_cast children: (snapshot.data! as QuerySnapshot) .docs .map( (e) => MenuCard( Menu( id: e['id'], image: e['image'], name: e['name'], price: e['price'], pricePromo: e['pricePromo'], note: e['note'], isPromo: e['isPromo'], ), ), ) .toList(), ); } else { return const Center( child: CircularProgressIndicator(), ); } }) |
Step 6: Integrate RazoPay
To integrate razorpay in flutter application we need to create an application Razorpay dashboard. Read here Integrate Razorpay Payment Gateway with flutter
Our Payment class will be like this
import 'package:flutter/material.dart'; import 'package:foodsapp/models/menu.dart'; import 'package:razorpay_flutter/razorpay_flutter.dart'; class CheckoutScreen extends StatefulWidget{ Menu menu; CheckoutScreen(this. menu); @override State<StatefulWidget> createState() { // TODO: implement createState return CheckoutScreenState(); } } class CheckoutScreenState extends State<CheckoutScreen> { late Razorpay _razorpay; String PAYMENT_STATUS=""; @override void initState() { // TODO: implement initState super.initState(); _razorpay = Razorpay(); _razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess); _razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError); _razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet); createOrder(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Payment', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar(title: Text("Checkout Process"),), body: Container( width: double.infinity, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox(height: 20,), Text(PAYMENT_STATUS,style: TextStyle(color: Colors.brown,fontWeight: FontWeight.bold,fontSize: 22,),textAlign: TextAlign.center,), ], ), ), ), ); } @override void dispose() { // TODO: implement dispose super.dispose(); _razorpay.clear(); } void _handlePaymentSuccess(PaymentSuccessResponse response) { print("Payment Process On response success ${response.paymentId}"); setState(() { PAYMENT_STATUS="Payment Success.\n\nYour Payment Id is: ${response.paymentId}"; }); Map<String,dynamic>payment=Map(); payment['status']=1; payment['order_id']=response.orderId; payment['payment_id']=response.paymentId; Navigator.pop(context,payment); } void _handlePaymentError(PaymentFailureResponse response) { print("Payment Process On response Error ${response.message}"); setState(() { PAYMENT_STATUS="Payment Failed. ${response.message}"; }); Map<String,dynamic>payment=Map(); payment['status']=0; Navigator.pop(context,payment); } void _handleExternalWallet(ExternalWalletResponse response) { print("Payment Process On response Waller ${response.walletName}"); setState(() { PAYMENT_STATUS="Payment Done with wallet information . ${response.walletName}"; }); Map<String,dynamic>payment=Map(); payment['status']=2; Navigator.pop(context,payment); } void createOrder() async { var options = { 'key': 'PUT_API_KEY', 'amount': widget.menu.price*100, 'name': widget.menu.name, 'description': widget.menu.note, 'prefill': {'contact': '9879879879', 'email': 'test_987@razorpay.com'}, 'external': { 'wallets': ['paytm'] } }; try { _razorpay.open(options); } catch (e) { debugPrint('Error: e'); } } } |
Let's run your application
Conclusion: In this flutter application we learned how to integrate firebase with flutter application, fetch data from firestore collections, and integrate Razorpay payment gateway.
Flutter Strip Paymentgateway integration
How do i integrate Razorpay Payment gateway in PHP Mysql website
Article Contributed By :
|
|
|
|
1650 Views |