Make a E-commerce App with Flutter
What This App Does
A E-commerce app serves a specific need in today's mobile-first world. Building one with Flutter means you ship to iOS, Android, and the web from a single codebase, cutting development time dramatically while keeping a native-quality experience.
Main Features
| Feature | Why It Matters |
|---|---|
| Product Catalogue | Grid with images, prices, categories; sort by popularity, price, or rating |
| Shopping Cart | Persistent cart with quantity controls and a live total |
| Checkout Flow | Multi-step checkout: address → shipping → payment → confirmation |
| Order Tracking | Real-time status updates and delivery estimate for each order |
| Wishlist | Save items for later with stock-available push notifications |
How to Make a E-commerce App with Flutter
Shopping Cart
class CartItem {
final String productId, name;
int quantity;
double price;
CartItem({required this.productId, required this.name,
this.quantity = 1, required this.price});
double get total => price * quantity;
}
class CartProvider extends ChangeNotifier {
final List _items = [];
List get items => UnmodifiableListView(_items);
int get count => _items.fold(0, (s, i) => s + i.quantity);
double get total => _items.fold(0.0, (s, i) => s + i.total);
void add(Product p) {
final idx = _items.indexWhere((i) => i.productId == p.id);
if (idx >= 0) {
_items[idx].quantity++;
} else {
_items.add(CartItem(productId: p.id, name: p.name, price: p.price));
}
notifyListeners();
}
void remove(String productId) {
_items.removeWhere((i) => i.productId == productId);
notifyListeners();
}
}
Checkout Flow
class CheckoutPage extends StatefulWidget {
@override State createState() => _CheckoutPageState();
}
class _CheckoutPageState extends State {
int _step = 0;
final _addressKey = GlobalKey();
final _paymentKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Stepper(
currentStep: _step,
onStepContinue: () {
if (_step < 2) setState(() => _step++);
},
steps: [
Step(title: const Text('Address'), content: _buildAddressForm()),
Step(title: const Text('Shipping'), content: _buildShippingOptions()),
Step(title: const Text('Payment'), content: _buildPaymentForm()),
],
);
}
Widget _buildPaymentForm() {
return Column(
children: [
TextField(decoration: const InputDecoration(labelText: 'Card number')),
Row(children: [
Expanded(child: TextField(decoration: const InputDecoration(labelText: 'MM/YY'))),
const SizedBox(width: 16),
Expanded(child: TextField(decoration: const InputDecoration(labelText: 'CVC'))),
]),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () async {
await Stripe.instance.initPaymentSheet(...);
await Stripe.instance.presentPaymentSheet();
},
child: const Text('Pay Now'),
),
],
);
}
}
Recommended Libraries
| Package | Purpose |
|---|---|
| stripe | Payment processing with Apple Pay and Google Pay |
| flutter_local_notifications | Order status and stock alerts |
| provider | Cart and wishlist state management |
UI & UX Suggestions
Use a white bg, blue CTA, orange sale badges, green in-stock colour palette to match the app's purpose. Keep the navigation simple — a bottom nav bar or a single-scroll layout works best for this type of app. Make sure every interaction provides haptic or visual feedback so the app feels responsive and polished.