CheckoutState
models/checkout_state.dart
Overview
Immutable snapshot of the entire checkout flow: backend cart id + Cart, Stripe clientSecret, selected shipping option / payment provider, promo code, available providers, booking questions + answers, plus the global isLoading / error flags.
User Flow
- Constructed empty in CheckoutController.build().
- copyWith re-issues every field except error which is intentionally pass-through (so passing error: null clears it).
- Almost every controller method does state.copyWith(isLoading: true) on entry and ...(isLoading: false) on exit.
Cases & Edge Cases
- removePromoCode rebuilds the state via the full constructor (not copyWith) specifically so it can null out promoCode — copyWith's ?? would keep the old code.
- questionAnswers and bookingQuestions default to const [] / const {} so the screen can render before initCheckout returns.
- availableShippingOptions and availablePaymentProviders are List<dynamic> — typed payment_provider.dart and shipping_option.dart exist but the controller still passes the raw maps through.
Code References
- lib/src/features/shared/checkout/models/checkout_state.dart:3 // CheckoutState
- lib/src/features/shared/checkout/models/checkout_state.dart:34 // copyWith
API Calls
Empty — fill this in later. Open the manifest and add content here.
Notes
Booking-questions live here rather than in a dedicated notifier because validating them must happen at the same instant as confirming payment — splitting state across notifiers would create a race.