Flutter Templates
Membangun Aplikasi E-commerce dengan Flutter, Back4App, dan Integrasi Stripe melalui Cloud Code
49 mnt
pendahuluan mengembangkan aplikasi e commerce melibatkan beberapa komponen, termasuk daftar produk, fungsionalitas keranjang belanja, pemrosesan pembayaran yang aman, pelacakan pesanan, dan ulasan pengguna menggabungkan toolkit ui yang kuat dari flutter dengan layanan backend yang dapat diskalakan dari back4app menyederhanakan proses pengembangan selain itu, mengintegrasikan stripe untuk pemrosesan pembayaran melalui back4app cloud code memungkinkan penanganan transaksi yang aman dan profesional dalam tutorial ini, anda akan membangun aplikasi e commerce dengan fitur fitur berikut daftar produk tampilkan produk dengan gambar, deskripsi, dan harga keranjang belanja tambahkan dan hapus produk dari keranjang akun pengguna kelola profil dan alamat pengguna checkout aman proses pembayaran dengan aman menggunakan stripe melalui back4app cloud code pelacakan pesanan lacak status dan riwayat pesanan ulasan dan penilaian izinkan pengguna untuk mengirimkan ulasan dan penilaian prasyarat untuk mengikuti tutorial ini, anda akan membutuhkan flutter sdk terinstal di mesin anda ikuti panduan instalasi flutter https //flutter dev/docs/get started/install pengetahuan dasar tentang flutter dan dart sebuah ide atau editor teks seperti visual studio code atau android studio akun back4app daftar di back4app https //www back4app com/ akun stripe daftar di stripe https //stripe com/ untuk mendapatkan kunci api node js dan npm terinstal untuk pengembangan cloud code langkah 1 – menyiapkan proyek flutter 1 1 buat proyek flutter baru buka terminal anda dan jalankan flutter create ecommerce app navigasikan ke direktori proyek cd ecommerce app 1 2 tambahkan dependensi buka pubspec yaml dan tambahkan dependensi berikut dependencies flutter sdk flutter parse server sdk flutter ^4 0 1 provider ^6 0 0 cached network image ^3 2 0 flutter stripe ^5 2 0 uuid ^3 0 6 jalankan flutter pub get untuk menginstal paket catatan parse server sdk flutter untuk integrasi back4app provider untuk manajemen status cached network image untuk pemuatan gambar yang efisien flutter stripe untuk integrasi stripe di sisi klien uuid untuk menghasilkan pengenal unik langkah 2 – menyiapkan back4app 2 1 buat aplikasi back4app baru masuk ke dasbor back4app https //dashboard back4app com/ klik pada "buat aplikasi baru" masukkan "ecommerceapp" sebagai nama aplikasi dan klik "buat" 2 2 siapkan model data kita perlu membuat beberapa kelas di back4app produk pengguna (kelas bawaan) pesanan itempesanan ulasan 2 2 1 kelas produk navigasikan ke "database" bagian klik pada "buat kelas" pilih "kustom" dan masukkan "produk" sebagai nama kelas tambahkan kolom berikut nama string deskripsi string harga nomor gambar file kategori string inventaris nomor 2 2 2 kelas pesanan buat kelas "pesanan" dengan kolom berikut pengguna pointer< user> totaljumlah nomor status string (nilai "pending", "dibayar", "dikirim", "dikirim") paymentintentid string (untuk melacak pembayaran stripe) alamatpengiriman string 2 2 3 kelas orderitem buat sebuah "orderitem" kelas dengan kolom kolom berikut pesanan pointer produk pointer kuantitas number harga number 2 2 4 kelas ulasan buat sebuah "review" kelas dengan kolom kolom berikut produk pointer pengguna pointer< user> penilaian number komentar string 2 3 dapatkan kredensial aplikasi navigasikan ke pengaturan aplikasi > keamanan & kunci catat id aplikasi dan kunci klien langkah 3 – mengimplementasikan manajemen produk 3 1 menginisialisasi parse di flutter buka lib/main dart dan modifikasi import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'package\ provider/provider dart'; import 'screens/home screen dart'; import 'services/product service dart'; void main() async { widgetsflutterbinding ensureinitialized(); const keyapplicationid = 'your application id'; const keyclientkey = 'your client key'; const keyparseserverurl = 'https //parseapi back4app com'; await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, autosendsessionid true, debug true, ); runapp(myapp()); } class myapp extends statelesswidget { @override widget build(buildcontext context) { return changenotifierprovider\<productservice>( create ( ) => productservice(), child materialapp( title 'e commerce app', theme themedata( primaryswatch colors blue, ), home homescreen(), ), ); } } ganti 'your application id' dan 'your client key' dengan kredensial back4app anda 3 2 membuat model produk buat direktori models di bawah lib dan tambahkan product dart // lib/models/product dart class product { string id; string name; string description; double price; string imageurl; string category; int inventory; product({ required this id, required this name, required this description, required this price, required this imageurl, required this category, required this inventory, }); } 3 3 mengimplementasikan layanan produk buat direktori services di bawah lib dan tambahkan product service dart // lib/services/product service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/product dart'; class productservice with changenotifier { list\<product> products = \[]; future\<void> fetchproducts() async { final query = querybuilder\<parseobject>(parseobject('product')); final response = await query query(); if (response success && response results != null) { products = response results! map((data) { return product( id data objectid!, name data get\<string>('name')!, description data get\<string>('description')!, price data get\<num>('price')! todouble(), imageurl data get\<parsefilebase>('image')! url!, category data get\<string>('category')!, inventory data get\<num>('inventory')! toint(), ); }) tolist(); notifylisteners(); } } } 3 4 membuat layar utama buat direktori layar di bawah lib dan tambahkan home screen dart // lib/screens/home screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/product service dart'; import 'product detail screen dart'; class homescreen extends statefulwidget { @override homescreenstate createstate() => homescreenstate(); } class homescreenstate extends state\<homescreen> { late productservice productservice; @override void initstate() { super initstate(); productservice = provider of\<productservice>(context, listen false); productservice fetchproducts(); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('e commerce app'), actions \[ iconbutton( icon icon(icons shopping cart), onpressed () { // navigate to cart screen (to be implemented) }, ), ], ), body consumer\<productservice>( builder (context, productservice, child) { if (productservice products isempty) { return center(child circularprogressindicator()); } return gridview\ builder( padding edgeinsets all(8 0), itemcount productservice products length, griddelegate slivergriddelegatewithfixedcrossaxiscount( crossaxiscount 2, childaspectratio 0 75, ), itembuilder (context, index) { final product = productservice products\[index]; return gesturedetector( ontap () { navigator push( context, materialpageroute( builder ( ) => productdetailscreen(product product), ), ); }, child card( child column( children \[ expanded( child image network( product imageurl, fit boxfit cover, ), ), text(product name), text('\\$${product price tostringasfixed(2)}'), ], ), ), ); }, ); }, ), ); } } 3 5 layar detail produk buat product detail screen dart di bawah lib/screens/ // lib/screens/product detail screen dart import 'package\ flutter/material dart'; import ' /models/product dart'; import ' /services/cart service dart'; import 'package\ provider/provider dart'; class productdetailscreen extends statelesswidget { final product product; productdetailscreen({required this product}); @override widget build(buildcontext context) { final cartservice = provider of\<cartservice>(context); return scaffold( appbar appbar(title text(product name)), body column( children \[ expanded(child image network(product imageurl)), padding( padding const edgeinsets all(16 0), child text(product description), ), text('\\$${product price tostringasfixed(2)}'), elevatedbutton( onpressed () { cartservice addtocart(product); scaffoldmessenger of(context) showsnackbar( snackbar(content text('added to cart')), ); }, child text('add to cart'), ), ], ), ); } } langkah 4 – mengimplementasikan akun pengguna 4 1 layanan autentikasi tambahkan auth service dart di bawah lib/services/ // lib/services/auth service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class authservice with changenotifier { parseuser? user; future\<bool> signup(string username, string password, string email) async { user = parseuser createuser(username, password, email); final response = await user! signup(); if (response success) { notifylisteners(); return true; } else { user = null; return false; } } future\<bool> login(string username, string password) async { user = parseuser(username, password, null); final response = await user! login(); if (response success) { notifylisteners(); return true; } else { user = null; return false; } } future\<void> logout() async { if (user != null) { await user! logout(); user = null; notifylisteners(); } } bool get isauthenticated => user != null; } 4 2 layar autentikasi buat login screen dart dan signup screen dart di bawah lib/screens/ layar masuk // lib/screens/login screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import 'home screen dart'; import 'signup screen dart'; class loginscreen extends statelesswidget { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void login(buildcontext context) async { final authservice = provider of\<authservice>(context, listen false); bool success = await authservice login( usernamecontroller text trim(), passwordcontroller text trim(), ); if (success) { navigator pushreplacement( context, materialpageroute(builder ( ) => homescreen()), ); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('login failed'))); } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('e commerce app login'), ), body padding( padding const edgeinsets all(16), child column( children \[ textfield( controller usernamecontroller, decoration inputdecoration(labeltext 'username or email'), ), textfield( controller passwordcontroller, decoration inputdecoration(labeltext 'password'), obscuretext true, ), sizedbox(height 20), elevatedbutton( onpressed () => login(context), child text('login'), ), textbutton( onpressed () { navigator push( context, materialpageroute(builder ( ) => signupscreen()), ); }, child text('don\\'t have an account? sign up'), ) ], ), ), ); } } layar pendaftaran // lib/screens/signup screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import 'home screen dart'; class signupscreen extends statelesswidget { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller emailcontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void signup(buildcontext context) async { final authservice = provider of\<authservice>(context, listen false); bool success = await authservice signup( usernamecontroller text trim(), passwordcontroller text trim(), emailcontroller text trim(), ); if (success) { navigator pushreplacement( context, materialpageroute(builder ( ) => homescreen()), ); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('signup failed'))); } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('e commerce app signup'), ), body padding( padding const edgeinsets all(16), child column( children \[ textfield( controller usernamecontroller, decoration inputdecoration(labeltext 'username'), ), textfield( controller emailcontroller, decoration inputdecoration(labeltext 'email'), ), textfield( controller passwordcontroller, decoration inputdecoration(labeltext 'password'), obscuretext true, ), sizedbox(height 20), elevatedbutton( onpressed () => signup(context), child text('sign up'), ), ], ), ), ); } } 4 3 perbarui utama untuk menyertakan authservice di main dart , bungkus materialapp dengan multiprovider // in main dart class myapp extends statelesswidget { @override widget build(buildcontext context) { return multiprovider( providers \[ changenotifierprovider\<productservice>( create ( ) => productservice(), ), changenotifierprovider\<authservice>( create ( ) => authservice(), ), changenotifierprovider\<cartservice>( create ( ) => cartservice(), ), ], child materialapp( // ), ); } } 4 4 pengalihan berdasarkan status autentikasi modifikasi main dart untuk memeriksa status autentikasi // main dart // inside the build method home consumer\<authservice>( builder (context, authservice, child) { if (authservice isauthenticated) { return homescreen(); } else { return loginscreen(); } }, ), langkah 5 – fungsionalitas keranjang belanja 5 1 buat layanan keranjang tambahkan cart service dart di bawah lib/services/ // lib/services/cart service dart import 'package\ flutter/material dart'; import ' /models/product dart'; class cartitem { final product product; int quantity; cartitem({required this product, this quantity = 1}); } class cartservice with changenotifier { map\<string, cartitem> items = {}; void addtocart(product product) { if ( items containskey(product id)) { items\[product id]! quantity++; } else { items\[product id] = cartitem(product product); } notifylisteners(); } void removefromcart(string productid) { items remove(productid); notifylisteners(); } void clearcart() { items clear(); notifylisteners(); } map\<string, cartitem> get items => items; double get totalamount { double total = 0 0; items foreach((key, cartitem) { total += cartitem product price cartitem quantity; }); return total; } } 5 2 buat layar keranjang tambahkan cart screen dart di bawah lib/screens/ // lib/screens/cart screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/cart service dart'; import 'checkout screen dart'; class cartscreen extends statelesswidget { @override widget build(buildcontext context) { final cartservice = provider of\<cartservice>(context); final cartitems = cartservice items values tolist(); return scaffold( appbar appbar(title text('your cart')), body column( children \[ expanded( child listview\ builder( itemcount cartservice items length, itembuilder (context, index) { final cartitem = cartitems\[index]; return listtile( leading image network(cartitem product imageurl), title text(cartitem product name), subtitle text('quantity ${cartitem quantity}'), trailing text('\\$${(cartitem product price cartitem quantity) tostringasfixed(2)}'), ); }, ), ), text('total \\$${cartservice totalamount tostringasfixed(2)}'), elevatedbutton( onpressed () { navigator push( context, materialpageroute(builder ( ) => checkoutscreen()), ); }, child text('proceed to checkout'), ), ], ), ); } } langkah 6 – pembayaran aman dengan integrasi stripe melalui cloud code 6 1 siapkan akun stripe daftar untuk akun stripe https //dashboard stripe com/register dapatkan kunci publik dan kunci rahasia dari dasbor stripe di bawah pengembang > kunci api 6 2 instal sdk stripe di cloud code back4app mendukung fungsi cloud code yang ditulis dalam javascript kami akan menulis fungsi cloud code untuk menangani pemrosesan pembayaran 6 2 1 buat proyek cloud code di dasbor aplikasi back4app anda, pergi ke pengaturan aplikasi > fungsi cloud code klik "edit kode" untuk membuka editor cloud code 6 2 2 inisialisasi npm dan instal paket stripe di terminal cloud code (yang disediakan di editor), jalankan npm init y npm install stripe\@8 174 0 catatan cloud code back4app menggunakan versi node js 14 x, jadi pastikan kompatibilitas 6 3 buat fungsi cloud untuk tujuan pembayaran buat atau modifikasi main js di editor cloud code // main js const stripe = require('stripe'); const stripe = stripe('your stripe secret key'); parse cloud define('createpaymentintent', async (request) => { const { amount, currency } = request params; try { const paymentintent = await stripe paymentintents create({ amount amount, currency currency, }); return { clientsecret paymentintent client secret }; } catch (error) { throw new parse error(500, error message); } }); ganti 'your stripe secret key' dengan kunci rahasia stripe anda yang sebenarnya catatan keamanan jangan pernah mengekspos kunci rahasia anda di sisi klien simpan dengan aman di cloud code 6 4 terapkan cloud code klik "terapkan" di editor cloud code untuk menerapkan fungsi anda 6 5 implementasi pembayaran di flutter 6 5 1 inisialisasi stripe di flutter di main dart , setelah parse() initialize , tambahkan import 'package\ flutter stripe/flutter stripe dart'; // inside main() async stripe publishablekey = 'your stripe publishable key'; ganti 'your stripe publishable key' dengan kunci publik stripe anda 6 5 2 buat layar checkout tambahkan checkout screen dart di bawah lib/screens/ // lib/screens/checkout screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/cart service dart'; import 'package\ flutter stripe/flutter stripe dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'order confirmation screen dart'; class checkoutscreen extends statelesswidget { future\<void> processpayment(buildcontext context) async { final cartservice = provider of\<cartservice>(context, listen false); final totalamount = (cartservice totalamount 100) toint(); // amount in cents // call cloud function to create payment intent final response = await parsecloudfunction('createpaymentintent') execute( parameters { 'amount' totalamount, 'currency' 'usd', }, ); if (response success) { final clientsecret = response result\['clientsecret']; // initialize payment sheet await stripe instance initpaymentsheet( paymentsheetparameters setuppaymentsheetparameters( paymentintentclientsecret clientsecret, merchantdisplayname 'your e commerce app', ), ); // display payment sheet await stripe instance presentpaymentsheet(); // payment successful // save order to back4app (to be implemented) cartservice clearcart(); navigator pushreplacement( context, materialpageroute(builder ( ) => orderconfirmationscreen()), ); } else { scaffoldmessenger of(context) showsnackbar( snackbar(content text('payment failed ${response error! message}')), ); } } @override widget build(buildcontext context) { final cartservice = provider of\<cartservice>(context); return scaffold( appbar appbar(title text('checkout')), body column( children \[ text('total \\$${cartservice totalamount tostringasfixed(2)}'), elevatedbutton( onpressed () => processpayment(context), child text('pay now'), ), ], ), ); } } 6 5 3 tangani konfirmasi pembayaran buat order confirmation screen dart di bawah lib/screens/ // lib/screens/order confirmation screen dart import 'package\ flutter/material dart'; class orderconfirmationscreen extends statelesswidget { @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('order confirmed'), automaticallyimplyleading false, ), body center( child text('thank you for your purchase!'), ), ); } } 6 6 menyimpan pesanan ke back4app modifikasi processpayment metode untuk menyimpan detail pesanan // after successful payment final authservice = provider of\<authservice>(context, listen false); final user = authservice user!; // create order object final order = parseobject('order') set('user', user) set('totalamount', cartservice totalamount) set('status', 'paid') set('paymentintentid', clientsecret); // save order final orderresponse = await order save(); if (orderresponse success) { final orderobject = orderresponse result; // save orderitems for (var cartitem in cartservice items values) { final orderitem = parseobject('orderitem') set('order', orderobject) set('product', parseobject('product') objectid = cartitem product id) set('quantity', cartitem quantity) set('price', cartitem product price); await orderitem save(); } // clear cart and navigate cartservice clearcart(); navigator pushreplacement( context, materialpageroute(builder ( ) => orderconfirmationscreen()), ); } else { scaffoldmessenger of(context) showsnackbar( snackbar(content text('failed to save order')), ); } langkah 7 – pelacakan pesanan 7 1 buat layanan pesanan tambahkan order service dart di bawah lib/services/ // lib/services/order service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/order dart'; class orderservice with changenotifier { list\<order> orders = \[]; future\<void> fetchorders(parseuser user) async { final query = querybuilder\<parseobject>(parseobject('order')) whereequalto('user', user) orderbydescending('createdat'); final response = await query query(); if (response success && response results != null) { orders = response results! map((data) { return order fromparseobject(data); }) tolist(); notifylisteners(); } } } 7 2 buat model pesanan tambahkan order dart di bawah lib/models/ // lib/models/order dart import 'package\ parse server sdk flutter/parse server sdk dart'; class order { string id; double totalamount; string status; datetime createdat; order({ required this id, required this totalamount, required this status, required this createdat, }); factory order fromparseobject(parseobject object) { return order( id object objectid!, totalamount object get\<num>('totalamount')! todouble(), status object get\<string>('status')!, createdat object createdat!, ); } } 7 3 buat layar pesanan tambahkan orders screen dart di bawah lib/screens/ // lib/screens/orders screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/order service dart'; import ' /services/auth service dart'; import ' /models/order dart'; class ordersscreen extends statefulwidget { @override ordersscreenstate createstate() => ordersscreenstate(); } class ordersscreenstate extends state\<ordersscreen> { late orderservice orderservice; @override void initstate() { super initstate(); orderservice = provider of\<orderservice>(context, listen false); final authservice = provider of\<authservice>(context, listen false); orderservice fetchorders(authservice user!); } @override widget build(buildcontext context) { return scaffold( appbar appbar(title text('your orders')), body consumer\<orderservice>( builder (context, orderservice, child) { if (orderservice orders isempty) { return center(child text('no orders found ')); } return listview\ builder( itemcount orderservice orders length, itembuilder (context, index) { final order = orderservice orders\[index]; return listtile( title text('order #${order id}'), subtitle text('status ${order status}'), trailing text('\\$${order totalamount tostringasfixed(2)}'), ); }, ); }, ), ); } } langkah 8 – ulasan dan penilaian 8 1 buat layanan ulasan tambahkan review service dart di bawah lib/services/ // lib/services/review service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/review\ dart'; class reviewservice with changenotifier { list\<review> reviews = \[]; future\<void> fetchreviews(string productid) async { final query = querybuilder\<parseobject>(parseobject('review')) whereequalto('product', parseobject('product') objectid = productid) includeobject(\['user']); final response = await query query(); if (response success && response results != null) { reviews = response results! map((data) { return review\ fromparseobject(data); }) tolist(); notifylisteners(); } } future\<void> submitreview(string productid, parseuser user, int rating, string comment) async { final review = parseobject('review') set('product', parseobject('product') objectid = productid) set('user', user) set('rating', rating) set('comment', comment); await review\ save(); await fetchreviews(productid); } } 8 2 buat model ulasan tambahkan review\ dart di bawah lib/models/ // lib/models/review\ dart import 'package\ parse server sdk flutter/parse server sdk dart'; class review { string id; int rating; string comment; parseuser user; review({ required this id, required this rating, required this comment, required this user, }); factory review\ fromparseobject(parseobject object) { return review( id object objectid!, rating object get\<num>('rating')! toint(), comment object get\<string>('comment')!, user object get\<parseuser>('user')!, ); } } 8 3 perbarui layar detail produk di product detail screen dart , tambahkan bagian untuk menampilkan dan mengirim ulasan // at the end of the column in productdetailscreen expanded( child column( children \[ // display reviews expanded( child consumer\<reviewservice>( builder (context, reviewservice, child) { if (reviewservice reviews isempty) { return center(child text('no reviews yet ')); } return listview\ builder( itemcount reviewservice reviews length, itembuilder (context, index) { final review = reviewservice reviews\[index]; return listtile( title text(review\ user username ?? 'anonymous'), subtitle text(review\ comment), trailing text('${review\ rating}/5'), ); }, ); }, ), ), // submit review textfield( controller reviewcontroller, decoration inputdecoration(hinttext 'write a review'), ), row( children \[ text('rating '), dropdownbutton\<int>( value rating, onchanged (value) { setstate(() { rating = value!; }); }, items list generate(5, (index) => index + 1) map((e) => dropdownmenuitem(value e, child text('$e'))) tolist(), ), elevatedbutton( onpressed () { final authservice = provider of\<authservice>(context, listen false); reviewservice submitreview( product id, authservice user!, rating, reviewcontroller text trim(), ); reviewcontroller clear(); }, child text('submit'), ), ], ), ], ), ), kesimpulan dalam tutorial komprehensif ini, anda telah membangun aplikasi e commerce menggunakan flutter dan back4app, terintegrasi dengan stripe untuk pemrosesan pembayaran yang aman melalui cloud code anda menerapkan fitur kunci seperti daftar produk, fungsionalitas keranjang belanja, otentikasi pengguna, pelacakan pesanan, dan ulasan poin penting integrasi back4app menyederhanakan manajemen backend untuk aplikasi flutter anda integrasi stripe melalui cloud code memproses pembayaran dengan aman tanpa mengekspos kunci sensitif arsitektur modular memisahkan layanan dan model meningkatkan pemeliharaan langkah selanjutnya tingkatkan keamanan terapkan penanganan kesalahan yang tepat dan validasi input peningkatan ui/ux perbaiki antarmuka pengguna untuk pengalaman pengguna yang lebih baik manajemen inventaris perbarui inventaris produk setelah pembelian notifikasi email kirim email konfirmasi pesanan kepada pengguna panel admin buat antarmuka admin untuk mengelola produk dan pesanan sumber daya tambahan dokumentasi back4app https //www back4app com/docs panduan parse server https //docs parseplatform org/ dokumentasi resmi flutter https //flutter dev/docs referensi api stripe https //stripe com/docs/api paket flutter stripe https //pub dev/packages/flutter stripe selamat berkoding!