6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 0a1a47fe
Changed files
comwell_key_app/assets/icons/ic_google.svg | 1 + comwell_key_app/assets/translations/da-DK.json | 4 +- comwell_key_app/assets/translations/en-US.json | 3 + .../ios/Runner/RunnerDebug-develop.entitlements | 10 ++ .../Runner/RunnerRelease-releasetest.entitlements | 10 ++ .../components/check_out_button.dart | 5 +- .../lib/check_out/bloc/check_out_cubit.dart | 95 ++++++++++--- .../lib/check_out/bloc/check_out_state.dart | 77 ++++++++--- comwell_key_app/lib/check_out/check_out_flow.dart | 34 ++--- .../check_out/components/accept_terms_toggle.dart | 47 ++++--- .../check_out/components/apply_club_points.dart | 2 +- .../components/change_payment_button.dart | 95 +++++++++++++ .../components/check_out_bottom_sheet.dart | 15 ++- .../components/check_out_payment_card.dart | 2 +- .../components/checkout_itemized_bill.dart | 6 +- .../lib/check_out/components/payment_button.dart | 39 ------ .../lib/check_out/models/check_out_item.dart | 2 +- .../models/checkout_processing_state.dart | 26 +++- .../check_out/models/payment_configurations.dart | 11 ++ .../lib/check_out/models/payment_method.dart | 21 +++ .../check_out/pages/check_out_processing_page.dart | 149 +++++++++++++++++++-- .../lib/check_out/pages/checkout_payment_page.dart | 6 +- .../overview/repository/overview_repository.dart | 18 +-- .../pregistration/pregistration_repository.dart | 93 +++++++++---- comwell_key_app/lib/routing/app_router.dart | 3 +- .../adyen/stored_payment_methods_response.dart | 1 - comwell_key_app/lib/services/api.dart | 7 +- .../interceptors/response_handle_interceptor.dart | 1 + comwell_key_app/lib/themes/dark_theme.dart | 27 ++-- 29 files changed, 612 insertions(+), 198 deletions(-)
Diff
diff --git a/comwell_key_app/assets/icons/ic_google.svg b/comwell_key_app/assets/icons/ic_google.svg
new file mode 100644
index 00000000..088288fa
--- /dev/null
+++ b/comwell_key_app/assets/icons/ic_google.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" fill="#4285F4"/><path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/><path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/><path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/><path d="M1 1h22v22H1z" fill="none"/></svg>
\ No newline at end of file
diff --git a/comwell_key_app/assets/translations/da-DK.json b/comwell_key_app/assets/translations/da-DK.json
index 472a4ca3..e88c3b24 100644
--- a/comwell_key_app/assets/translations/da-DK.json
+++ b/comwell_key_app/assets/translations/da-DK.json
@@ -4,6 +4,9 @@
"generic_information_required": "Dette felt er påkrævet",
"generic_confirm": "Bekræft",
"generic_done": "Færdig",
+ "generic_credit_card": "Kreditkort",
+ "generic_apple_pay": "Apple Pay",
+ "generic_google_pay": "Google Pay",
"welcome_headline": "Velkommen hos Comwell Hotels",
"welcome_button": "Fortsæt",
"welcome_error": "Der er sket en fejl. Genstart app.",
@@ -171,5 +174,4 @@
"checkout_page_payment_dialog_cancel": "Nej",
"checkout_page_processing_success_title": "Check-out bekræftet",
"checkout_page_processing_success_subtitle": "Det check-out er nu bekræftet og du har nu 30 minutter til at forlade dit værelse. Herefter vil du ikke længere kunne bruge dit nøglekort."
-
}
\ No newline at end of file
diff --git a/comwell_key_app/assets/translations/en-US.json b/comwell_key_app/assets/translations/en-US.json
index 0e188f95..b023f783 100644
--- a/comwell_key_app/assets/translations/en-US.json
+++ b/comwell_key_app/assets/translations/en-US.json
@@ -4,6 +4,9 @@
"generic_confirm": "Confirm",
"generic_done": "Done",
"generic_ok": "OK",
+ "generic_credit_card": "Credit Card",
+ "generic_apple_pay": "Apple Pay",
+ "generic_google_pay": "Google Pay",
"welcome_headline": "Welcome at Comwell Hotels",
"welcome_button": "Continue",
"welcome_error": "An error occurred. Please try again later.",
diff --git a/comwell_key_app/ios/Runner/RunnerDebug-develop.entitlements b/comwell_key_app/ios/Runner/RunnerDebug-develop.entitlements
new file mode 100644
index 00000000..4b666946
--- /dev/null
+++ b/comwell_key_app/ios/Runner/RunnerDebug-develop.entitlements
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.developer.in-app-payments</key>
+ <array>
+ <string>merchant.ComwellHotelsECOM</string>
+ </array>
+</dict>
+</plist>
diff --git a/comwell_key_app/ios/Runner/RunnerRelease-releasetest.entitlements b/comwell_key_app/ios/Runner/RunnerRelease-releasetest.entitlements
new file mode 100644
index 00000000..4b666946
--- /dev/null
+++ b/comwell_key_app/ios/Runner/RunnerRelease-releasetest.entitlements
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.developer.in-app-payments</key>
+ <array>
+ <string>merchant.ComwellHotelsECOM</string>
+ </array>
+</dict>
+</plist>
diff --git a/comwell_key_app/lib/booking_details/components/check_out_button.dart b/comwell_key_app/lib/booking_details/components/check_out_button.dart
index 0efd9266..7fe4c122 100644
--- a/comwell_key_app/lib/booking_details/components/check_out_button.dart
+++ b/comwell_key_app/lib/booking_details/components/check_out_button.dart
@@ -1,7 +1,9 @@
+import 'package:comwell_key_app/booking_details/bloc/booking_details_bloc.dart';
import 'package:comwell_key_app/routing/app_routes.dart';
import 'package:comwell_key_app/themes/light_theme.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
@@ -10,10 +12,11 @@ class CheckOutButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ final cubit = context.read<BookingDetailsBloc>();
return InkWell(
borderRadius: const BorderRadius.all(Radius.circular(15)),
onTap: () {
- context.pushNamed(AppRoutes.checkOut.name);
+ context.pushNamed(AppRoutes.checkOut.name, extra: cubit.booking);
},
child: Ink(
decoration: BoxDecoration(
diff --git a/comwell_key_app/lib/check_out/bloc/check_out_cubit.dart b/comwell_key_app/lib/check_out/bloc/check_out_cubit.dart
index 14e03239..45db2e53 100644
--- a/comwell_key_app/lib/check_out/bloc/check_out_cubit.dart
+++ b/comwell_key_app/lib/check_out/bloc/check_out_cubit.dart
@@ -1,33 +1,45 @@
+import 'package:adyen_checkout/adyen_checkout.dart';
import 'package:bloc/bloc.dart';
import 'package:comwell_key_app/check_out/bloc/check_out_state.dart';
import 'package:comwell_key_app/check_out/models/check_out_item.dart';
import 'package:comwell_key_app/check_out/models/checkout_processing_state.dart';
+import 'package:comwell_key_app/check_out/models/payment_method.dart';
import 'package:comwell_key_app/check_out/pages/check_out_page.dart';
+import 'package:comwell_key_app/overview/models/booking.dart';
+import 'package:comwell_key_app/pregistration/pregistration_repository.dart';
import 'package:comwell_key_app/profile_settings/repostiory/profile_settings_repository.dart';
+import 'package:comwell_key_app/services/adyen/adyen_amount.dart';
+import 'package:comwell_key_app/utils/locator.dart';
import 'package:flutter/material.dart';
class CheckoutCubit extends Cubit<CheckoutState> {
- late final ProfileSettingsRepository profileSettingsRepository;
+ final ProfileSettingsRepository profileSettingsRepository =
+ locator<ProfileSettingsRepository>();
+ final PreregistrationRepository preregistrationRepository =
+ locator<PreregistrationRepository>();
final pageController = PageController();
- final clubPoints = 200; // TODO Is this available on user object?
bool _isAnimating = false;
+ final Booking booking;
CheckoutPage get currentPage =>
CheckoutPage.fromIndex(pageController.page?.toInt() ?? 0);
- CheckoutCubit() : super(CheckoutState.initial());
+ CheckoutCubit(this.booking) : super(CheckoutState.initial());
void init() async {
try {
final user = await profileSettingsRepository.fetchProfileSettings();
- } catch (e) {}
+ emit(state.clubPointsFetched(user!.points ?? 0));
+ } catch (e) {
+ // Todo handle error
+ }
}
void onApplyClubPointsClicked(bool value) {
if (value) {
- emit(state.termsAccepted());
+ emit(state.clubPointsApplied());
} else {
- emit(state.termsDenied());
+ emit(state.clubPointsRemoved());
}
}
@@ -35,13 +47,9 @@ class CheckoutCubit extends Cubit<CheckoutState> {
emit(state.itemsUpdated(items));
}
- // TODO connect to checkout endpoint, handle error state (missing in figma)
void processCheckout() async {
- emit(state.processingStateUpdated(CheckoutProcessingState.processing));
- await Future<void>.delayed(const Duration(seconds: 2));
- emit(state.processingStateUpdated(CheckoutProcessingState.success));
- await Future<void>.delayed(const Duration(seconds: 2));
- emit(state.processingStateUpdated(CheckoutProcessingState.confirmed));
+ emit(state.processingStateUpdated(CheckoutProcessingStateProcessing()));
+ createSession();
}
void onContinueClicked() {
@@ -51,7 +59,16 @@ class CheckoutCubit extends Cubit<CheckoutState> {
case CheckoutPage.confirmation:
return _navigateTo(CheckoutPage.payment);
case CheckoutPage.payment:
- return processCheckout();
+ return _navigateToProcessing();
+ }
+ }
+
+ void _navigateToProcessing() {
+ _isAnimating = false;
+ if (!state.isTermsAccepted) {
+ emit(state.showAcceptTermsError());
+ } else {
+ processCheckout();
}
}
@@ -61,8 +78,8 @@ class CheckoutCubit extends Cubit<CheckoutState> {
_isAnimating = true;
pageController
.previousPage(
- duration: const Duration(milliseconds: 500),
- curve: Curves.fastOutSlowIn)
+ duration: const Duration(milliseconds: 500),
+ curve: Curves.fastOutSlowIn)
.then((_) {
_isAnimating = false;
emit(state.pageChanged(currentPage));
@@ -84,10 +101,6 @@ class CheckoutCubit extends Cubit<CheckoutState> {
return super.close();
}
- void onChangePaymentClicked() {
- // TODO finish adyen task
- }
-
void onAcceptTermsChanged(bool value) {
if (value) {
emit(state.termsAccepted());
@@ -95,4 +108,48 @@ class CheckoutCubit extends Cubit<CheckoutState> {
emit(state.termsDenied());
}
}
+
+ void createSession() async {
+ try {
+ final amount = AdyenAmount(
+ value: state.totalPriceAfterDiscount * 100,
+ currency: "DKK",
+ );
+ final paymentConfigurations = await preregistrationRepository
+ .sessionCheckout(amount, booking.hotelCode);
+ emit(state.processingStateUpdated(CheckoutProcessingStateSessionReceived(
+ paymentConfigurations: paymentConfigurations)));
+ } catch (e) {
+ print("qqq error=$e");
+ emit(state.processingStateUpdated(CheckoutProcessingStateError()));
+ }
+ }
+
+ Future<void> onPaymentResult(PaymentResult result) async {
+ switch (result) {
+ case PaymentAdvancedFinished():
+ case PaymentSessionFinished():
+ emit(state.processingStateUpdated(CheckoutProcessingStateSuccess()));
+ await Future<void>.delayed(const Duration(milliseconds: 1000));
+ emit(state.processingStateUpdated(CheckoutProcessingStateConfirmed()));
+ break;
+ case PaymentCancelledByUser():
+ case PaymentError():
+ emit(state.processingStateUpdated(CheckoutProcessingStateError()));
+ await Future<void>.delayed(const Duration(milliseconds: 1000));
+ emit(state.processingStateUpdated(CheckoutProcessingStateNotStarted()));
+ }
+ }
+
+ void onPaymentMethodChanged(CheckoutPaymentMethod method) {
+ emit(state.paymentMethodChanged(method));
+ }
+
+ void onUserDismissPaymentPopup() {
+ emit(state.processingStateUpdated(CheckoutProcessingStateNotStarted()));
+ }
+
+ void showTermsAndConditions() {
+ // TODO
+ }
}
diff --git a/comwell_key_app/lib/check_out/bloc/check_out_state.dart b/comwell_key_app/lib/check_out/bloc/check_out_state.dart
index ac2dd7b4..037f11a4 100644
--- a/comwell_key_app/lib/check_out/bloc/check_out_state.dart
+++ b/comwell_key_app/lib/check_out/bloc/check_out_state.dart
@@ -1,33 +1,43 @@
import 'package:comwell_key_app/check_out/models/check_out_item.dart';
import 'package:comwell_key_app/check_out/models/checkout_processing_state.dart';
+import 'package:comwell_key_app/check_out/models/payment_method.dart';
import 'package:comwell_key_app/check_out/pages/check_out_page.dart';
-import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
import 'package:equatable/equatable.dart';
class CheckoutState extends Equatable {
final Iterable<CheckoutItem> _items;
final bool isTermsAccepted;
final bool applyClubPoints;
+ final int clubPoints;
final CheckoutProcessingState processingState;
final CheckoutPage page;
- final StoredPaymentMethod? paymentMethod;
+ final CheckoutPaymentMethod? paymentMethod;
+ final bool showTermsError;
- num get totalPrice {
- if (_items.isEmpty) return 0;
- return _items
- .map((item) => item.price)
- .reduce((total, price) => total + price);
- }
+ int get totalPriceBeforeDiscount => _sumOfList(_items);
+
+ int get totalPriceAfterDiscount => _sumOfList(items);
Iterable<CheckoutItem> get items {
- if (applyClubPoints) return [..._items, CheckoutItem("Rabat", -200)];
+ if (applyClubPoints) {
+ return [..._items, CheckoutItem("Rabat", clubPoints * -1)];
+ }
return _items;
}
+ int _sumOfList(Iterable<CheckoutItem> list) {
+ if (list.isEmpty) return 0;
+ return list
+ .map((item) => item.price)
+ .reduce((total, price) => total + price);
+ }
+
const CheckoutState({
required Iterable<CheckoutItem> items,
required this.isTermsAccepted,
required this.page,
+ required this.showTermsError,
+ required this.clubPoints,
required this.applyClubPoints,
required this.processingState,
this.paymentMethod,
@@ -37,14 +47,16 @@ class CheckoutState extends Equatable {
: _items = _mockItems(),
isTermsAccepted = false,
page = CheckoutPage.confirmation,
- paymentMethod = const StoredPaymentMethod(expiryMonth: "12/12", expiryYear: "2004", holderName: "Mikke", id: "1234", lastFour: "1234", type: "visa"),
- processingState = CheckoutProcessingState.notStarted,
+ showTermsError = false,
+ clubPoints = 0,
+ paymentMethod = CheckoutPaymentMethod.creditCard,
+ processingState = CheckoutProcessingStateNotStarted(),
applyClubPoints = false;
CheckoutState itemsUpdated(Iterable<CheckoutItem> items) =>
_copyWith(items: items);
- CheckoutState termsAccepted() => _copyWith(termsAccepted: true);
+ CheckoutState termsAccepted() => _copyWith(termsAccepted: true, showTermsError: false);
CheckoutState termsDenied() => _copyWith(termsAccepted: false);
@@ -52,22 +64,36 @@ class CheckoutState extends Equatable {
CheckoutState clubPointsRemoved() => _copyWith(applyClubPoints: false);
+ CheckoutState paymentMethodChanged(CheckoutPaymentMethod payment) =>
+ _copyWith(paymentMethod: payment);
+
CheckoutState processingStateUpdated(
- CheckoutProcessingState processingState) =>
+ CheckoutProcessingState processingState) =>
_copyWith(updateProcessingState: processingState);
CheckoutState pageChanged(CheckoutPage page) => _copyWith(page: page);
- CheckoutState _copyWith(
- {Iterable<CheckoutItem>? items,
- bool? termsAccepted,
- bool? applyClubPoints,
- CheckoutProcessingState? updateProcessingState,
- CheckoutPage? page,
- StoredPaymentMethod? paymentMethod}) {
+ CheckoutState clubPointsFetched(int clubPoints) =>
+ _copyWith(clubPoints: clubPoints);
+
+ CheckoutState showAcceptTermsError() => _copyWith(showTermsError: true);
+
+
+ CheckoutState _copyWith({
+ Iterable<CheckoutItem>? items,
+ bool? termsAccepted,
+ bool? applyClubPoints,
+ CheckoutProcessingState? updateProcessingState,
+ CheckoutPage? page,
+ CheckoutPaymentMethod? paymentMethod,
+ int? clubPoints,
+ bool? showTermsError,
+ }) {
return CheckoutState(
items: items ?? _items,
page: page ?? this.page,
+ clubPoints: clubPoints ?? this.clubPoints,
+ showTermsError: showTermsError ?? this.showTermsError,
processingState: updateProcessingState ?? processingState,
isTermsAccepted: termsAccepted ?? isTermsAccepted,
applyClubPoints: applyClubPoints ?? this.applyClubPoints,
@@ -77,7 +103,16 @@ class CheckoutState extends Equatable {
static Iterable<CheckoutItem> _mockItems() =>
[1, 2, 3].map((i) => CheckoutItem("item $i", i * 100));
+
@override
List<Object?> get props =>
- [_items, isTermsAccepted, applyClubPoints, processingState, page];
+ [
+ _items,
+ isTermsAccepted,
+ applyClubPoints,
+ processingState,
+ page,
+ showTermsError,
+ paymentMethod
+ ];
}
diff --git a/comwell_key_app/lib/check_out/check_out_flow.dart b/comwell_key_app/lib/check_out/check_out_flow.dart
index 012fce9e..8f4d6b40 100644
--- a/comwell_key_app/lib/check_out/check_out_flow.dart
+++ b/comwell_key_app/lib/check_out/check_out_flow.dart
@@ -13,24 +13,26 @@ class CheckOutFlow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final cubit = context.read<CheckoutCubit>();
- if (cubit.state.processingState != CheckoutProcessingState.notStarted) {
+ if (cubit.state.processingState is! CheckoutProcessingStateNotStarted) {
return const CheckOutProcessingPage();
}
- return Scaffold(
- appBar: ComwellAppBar(
- shouldShowProfileButton: false,
- onBackPressed: () {
- final didScroll = cubit.onBackPressed();
- if (!didScroll) Navigator.of(context).pop();
- },
- ),
- bottomSheet: const CheckOutBottomSheet(),
- backgroundColor: Colors.white,
- body: PageView(
- controller: cubit.pageController,
- key: const PageStorageKey("check_out_flow"),
- physics: const NeverScrollableScrollPhysics(),
- children: CheckoutPage.getPages(ValueKey(cubit.state)).toList(),
+ return SafeArea(
+ child: Scaffold(
+ appBar: ComwellAppBar(
+ shouldShowProfileButton: false,
+ onBackPressed: () {
+ final didScroll = cubit.onBackPressed();
+ if (!didScroll) Navigator.of(context).pop();
+ },
+ ),
+ bottomSheet: const CheckOutBottomSheet(),
+ backgroundColor: Colors.white,
+ body: PageView(
+ controller: cubit.pageController,
+ key: const PageStorageKey("check_out_flow"),
+ physics: const NeverScrollableScrollPhysics(),
+ children: CheckoutPage.getPages(ValueKey(cubit.state)).toList(),
+ ),
),
);
}
diff --git a/comwell_key_app/lib/check_out/components/accept_terms_toggle.dart b/comwell_key_app/lib/check_out/components/accept_terms_toggle.dart
index 592ae0c6..7107c44c 100644
--- a/comwell_key_app/lib/check_out/components/accept_terms_toggle.dart
+++ b/comwell_key_app/lib/check_out/components/accept_terms_toggle.dart
@@ -10,23 +10,40 @@ class AcceptTermsToggle extends StatelessWidget {
@override
Widget build(BuildContext context) {
final cubit = context.read<CheckoutCubit>();
- return Row(
+ final showError = cubit.state.showTermsError;
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Checkbox(
- value: cubit.state.isTermsAccepted,
- visualDensity: VisualDensity.comfortable,
- checkColor: Colors.white,
- activeColor: sandColor[80],
- onChanged: (value) {
- cubit.onAcceptTermsChanged(value ?? false);
- },
+ if (showError)
+ Text("Please accept terms".tr(),
+ style: const TextStyle(color: colorError)),
+ Row(
+ children: [
+ Checkbox(
+ value: cubit.state.isTermsAccepted,
+ visualDensity: VisualDensity.comfortable,
+ checkColor: Colors.white,
+ activeColor: sandColor[80],
+ onChanged: (value) {
+ cubit.onAcceptTermsChanged(value ?? false);
+ },
+ ),
+ const SizedBox(width: 4),
+ TextButton(
+ onPressed: () {
+ cubit.showTermsAndConditions();
+ },
+ child: Text(
+ "checkout_page_payment_accept_terms".tr(),
+ style: TextStyle(
+ color: sandColor[80],
+ decoration: TextDecoration.underline,
+ ),
+ ),
+ ),
+ const SizedBox(height: 4),
+ ],
),
- const SizedBox(width: 4),
- TextButton(
- onPressed: () {
- cubit.onAcceptTermsChanged(!cubit.state.isTermsAccepted);
- },
- child: Text("checkout_page_payment_accept_terms".tr())),
],
);
}
diff --git a/comwell_key_app/lib/check_out/components/apply_club_points.dart b/comwell_key_app/lib/check_out/components/apply_club_points.dart
index 33c93f6f..d1b3c0d8 100644
--- a/comwell_key_app/lib/check_out/components/apply_club_points.dart
+++ b/comwell_key_app/lib/check_out/components/apply_club_points.dart
@@ -21,7 +21,7 @@ class ApplyClubPoints extends StatelessWidget {
Text("checkout_page_payment_club_points_title".tr()),
Text(
"checkout_page_payment_club_points_subtitle".tr(
- args: ["${cubit.clubPoints}", "${cubit.clubPoints}"],
+ args: ["${cubit.state.clubPoints}", "${cubit.state.clubPoints}"],
),
style: TextStyle(color: colorBlack[65]),
),
diff --git a/comwell_key_app/lib/check_out/components/change_payment_button.dart b/comwell_key_app/lib/check_out/components/change_payment_button.dart
new file mode 100644
index 00000000..803fcc00
--- /dev/null
+++ b/comwell_key_app/lib/check_out/components/change_payment_button.dart
@@ -0,0 +1,95 @@
+import 'package:comwell_key_app/check_out/bloc/check_out_cubit.dart';
+import 'package:comwell_key_app/check_out/models/payment_method.dart';
+import 'package:comwell_key_app/themes/light_theme.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:go_router/go_router.dart';
+
+class ChangePaymentButton extends StatelessWidget {
+ const ChangePaymentButton({super.key});
+
+ void _showPaymentPicker(BuildContext context) async {
+ final cubit = context.read<CheckoutCubit>();
+ final Iterable<CheckoutPaymentMethod?> listItems = [
+ CheckoutPaymentMethod.creditCard,
+ null,
+ CheckoutPaymentMethod.appleOrGooglePay
+ ];
+ final response = await showModalBottomSheet<dynamic>(
+ context: context,
+ builder: (context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(vertical: 16.0),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ ...listItems.map((item) {
+ if (item == null) {
+ return const Divider(
+ color: colorDivider,
+ indent: 16,
+ endIndent: 16,
+ );
+ }
+ return InkWell(
+ onTap: () {
+ context.pop(item);
+ },
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 16,
+ horizontal: 16,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ item.iconWidget,
+ const SizedBox(width: 32),
+ Text(item.stringId.tr()),
+ ],
+ ),
+ ),
+ );
+ }),
+ ],
+ ),
+ );
+ });
+ if (response is CheckoutPaymentMethod) {
+ cubit.onPaymentMethodChanged(response);
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final cubit = context.read<CheckoutCubit>();
+ final paymentMethod = cubit.state.paymentMethod!;
+ return InkWell(
+ onTap: () async {
+ _showPaymentPicker(context);
+ },
+ child: Container(
+ decoration: BoxDecoration(
+ border: Border.all(color: colorDivider),
+ ),
+ padding: const EdgeInsets.all(12),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ paymentMethod.iconWidget,
+ const SizedBox(width: 12),
+ Text(
+ "checkout_page_payment_payment_title"
+ .tr(args: [paymentMethod.stringId.tr()]),
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ const Expanded(child: SizedBox()),
+ SvgPicture.asset("assets/icons/arrow-left.svg"),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/comwell_key_app/lib/check_out/components/check_out_bottom_sheet.dart b/comwell_key_app/lib/check_out/components/check_out_bottom_sheet.dart
index 256a6e09..49b6cce2 100644
--- a/comwell_key_app/lib/check_out/components/check_out_bottom_sheet.dart
+++ b/comwell_key_app/lib/check_out/components/check_out_bottom_sheet.dart
@@ -44,17 +44,18 @@ class CheckOutBottomSheet extends StatelessWidget {
return OutlinedButton(
onPressed: () async {
await showDialog<void>(
- context: context,
- builder: (context) =>
- ConfirmCheckOutDialog(onConfirm: () {
- Navigator.of(context).pop();
- cubit.onContinueClicked();
- }));
+ context: context,
+ builder: (context) =>
+ ConfirmCheckOutDialog(onConfirm: () {
+ Navigator.of(context).pop();
+ cubit.onContinueClicked();
+ }),
+ );
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 17.0),
child: Text("checkout_page_payment_payment_title"
- .tr(args: [paymentMethod.type])),
+ .tr(args: [paymentMethod.stringId.tr()])),
));
}
}),
diff --git a/comwell_key_app/lib/check_out/components/check_out_payment_card.dart b/comwell_key_app/lib/check_out/components/check_out_payment_card.dart
index de5e8d0b..5ec905cf 100644
--- a/comwell_key_app/lib/check_out/components/check_out_payment_card.dart
+++ b/comwell_key_app/lib/check_out/components/check_out_payment_card.dart
@@ -33,7 +33,7 @@ class CheckOutPaymentCard extends StatelessWidget {
?.copyWith(color: colorBlack[65]),
),
const SizedBox(height: 4),
- Text("checkout_page_payment_price".tr(args: ["${cubit.state.totalPrice}"]),
+ Text("checkout_page_payment_price".tr(args: ["${cubit.state.totalPriceBeforeDiscount}"]),
style: Theme.of(context).textTheme.displaySmall),
],
),
diff --git a/comwell_key_app/lib/check_out/components/checkout_itemized_bill.dart b/comwell_key_app/lib/check_out/components/checkout_itemized_bill.dart
index 0fbe0108..6d0771b0 100644
--- a/comwell_key_app/lib/check_out/components/checkout_itemized_bill.dart
+++ b/comwell_key_app/lib/check_out/components/checkout_itemized_bill.dart
@@ -31,18 +31,18 @@ class CheckoutItemizedBill extends StatelessWidget {
Row(
children: [
Text(
- "${cubit.state.totalPrice}",
+ "${cubit.state.totalPriceBeforeDiscount}",
style: const TextStyle(
decoration: TextDecoration.lineThrough,
decorationColor: colorDivider,
color: colorDivider),
),
const SizedBox(width: 4),
- Text("${cubit.state.totalPrice - cubit.clubPoints}"),
+ Text("${cubit.state.totalPriceBeforeDiscount - cubit.state.clubPoints}"),
],
)
else
- Text("${cubit.state.totalPrice}"),
+ Text("${cubit.state.totalPriceBeforeDiscount}"),
],
),
const SizedBox(height: 12),
diff --git a/comwell_key_app/lib/check_out/components/payment_button.dart b/comwell_key_app/lib/check_out/components/payment_button.dart
deleted file mode 100644
index 4259e851..00000000
--- a/comwell_key_app/lib/check_out/components/payment_button.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-import 'package:comwell_key_app/check_out/bloc/check_out_cubit.dart';
-import 'package:comwell_key_app/themes/light_theme.dart';
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_svg/svg.dart';
-
-
-class PaymentButton extends StatelessWidget {
- const PaymentButton({super.key});
-
- @override
- Widget build(BuildContext context) {
- final cubit = context.read<CheckoutCubit>();
- final paymentMethod = cubit.state.paymentMethod!;
- return InkWell(
- onTap: cubit.onChangePaymentClicked,
- child: Container(
- decoration: BoxDecoration(
- border: Border.all(color: colorDivider),
- ),
- padding: const EdgeInsets.all(12),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SvgPicture.asset("assets/icons/visa.svg"),
- const SizedBox(width: 12),
- Text(
- "checkout_page_payment_payment_title".tr(args: [paymentMethod.type]),
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- const Expanded(child: SizedBox()),
- SvgPicture.asset("assets/icons/arrow-left.svg"),
- ],
- ),
- ),
- );
- }
-}
diff --git a/comwell_key_app/lib/check_out/models/check_out_item.dart b/comwell_key_app/lib/check_out/models/check_out_item.dart
index 0f94e445..a6dcdd44 100644
--- a/comwell_key_app/lib/check_out/models/check_out_item.dart
+++ b/comwell_key_app/lib/check_out/models/check_out_item.dart
@@ -1,6 +1,6 @@
class CheckoutItem {
final String name;
- final num price;
+ final int price;
CheckoutItem(this.name, this.price);
}
\ No newline at end of file
diff --git a/comwell_key_app/lib/check_out/models/checkout_processing_state.dart b/comwell_key_app/lib/check_out/models/checkout_processing_state.dart
index 953e3b08..dd351f00 100644
--- a/comwell_key_app/lib/check_out/models/checkout_processing_state.dart
+++ b/comwell_key_app/lib/check_out/models/checkout_processing_state.dart
@@ -1,7 +1,19 @@
-enum CheckoutProcessingState {
- notStarted,
- processing,
- success,
- confirmed,
- error;
-}
\ No newline at end of file
+import 'package:comwell_key_app/check_out/models/payment_configurations.dart';
+
+sealed class CheckoutProcessingState {}
+
+class CheckoutProcessingStateNotStarted extends CheckoutProcessingState {}
+
+class CheckoutProcessingStateProcessing extends CheckoutProcessingState {}
+
+class CheckoutProcessingStateSessionReceived extends CheckoutProcessingState {
+ final PaymentConfigurations paymentConfigurations;
+
+ CheckoutProcessingStateSessionReceived({required this.paymentConfigurations});
+}
+
+class CheckoutProcessingStateSuccess extends CheckoutProcessingState {}
+
+class CheckoutProcessingStateConfirmed extends CheckoutProcessingState {}
+
+class CheckoutProcessingStateError extends CheckoutProcessingState {}
diff --git a/comwell_key_app/lib/check_out/models/payment_configurations.dart b/comwell_key_app/lib/check_out/models/payment_configurations.dart
new file mode 100644
index 00000000..909e9702
--- /dev/null
+++ b/comwell_key_app/lib/check_out/models/payment_configurations.dart
@@ -0,0 +1,11 @@
+import 'package:adyen_checkout/adyen_checkout.dart';
+
+class PaymentConfigurations {
+
+ final SessionCheckout sessionCheckout;
+ final GooglePayComponentConfiguration googlePayConfiguration;
+ final DropInConfiguration cardConfiguration;
+ final ApplePayComponentConfiguration applePayConfiguration;
+
+ PaymentConfigurations({required this.sessionCheckout, required this.googlePayConfiguration, required this.cardConfiguration, required this.applePayConfiguration});
+}
\ No newline at end of file
diff --git a/comwell_key_app/lib/check_out/models/payment_method.dart b/comwell_key_app/lib/check_out/models/payment_method.dart
new file mode 100644
index 00000000..76ad72a4
--- /dev/null
+++ b/comwell_key_app/lib/check_out/models/payment_method.dart
@@ -0,0 +1,21 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+
+enum CheckoutPaymentMethod {
+ creditCard,
+ appleOrGooglePay;
+
+ Widget get iconWidget {
+ if (this == CheckoutPaymentMethod.creditCard) return SvgPicture.asset("assets/icons/ic_card.svg");
+ if (Platform.isIOS) return const Icon(Icons.apple);
+ return SvgPicture.asset("assets/icons/ic_google.svg");
+ }
+
+ String get stringId {
+ if (this == CheckoutPaymentMethod.creditCard) return "generic_credit_card";
+ if (Platform.isIOS) return "generic_apple_pay";
+ return "generic_google_pay";
+ }
+}
diff --git a/comwell_key_app/lib/check_out/pages/check_out_processing_page.dart b/comwell_key_app/lib/check_out/pages/check_out_processing_page.dart
index 0c44289e..f6adb8f7 100644
--- a/comwell_key_app/lib/check_out/pages/check_out_processing_page.dart
+++ b/comwell_key_app/lib/check_out/pages/check_out_processing_page.dart
@@ -1,10 +1,15 @@
+import 'dart:io';
+
+import 'package:adyen_checkout/adyen_checkout.dart';
import 'package:comwell_key_app/check_out/bloc/check_out_cubit.dart';
import 'package:comwell_key_app/check_out/models/checkout_processing_state.dart';
+import 'package:comwell_key_app/check_out/models/payment_method.dart';
import 'package:comwell_key_app/check_out/pages/check_out_success_page.dart';
import 'package:comwell_key_app/themes/dark_theme.dart';
import 'package:comwell_key_app/utils/lottie_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:go_router/go_router.dart';
import 'package:lottie/lottie.dart';
class CheckOutProcessingPage extends StatefulWidget {
@@ -36,8 +41,12 @@ class _CheckOutProcessingPageState extends State<CheckOutProcessingPage>
}
void playLoading() {
- loadingComposition.playBetween(animationController, "spinner",
- markerEnd: "success", repeat: true);
+ loadingComposition.playBetween(
+ animationController,
+ "spinner",
+ markerEnd: "success",
+ repeat: true,
+ );
}
void playError() {
@@ -54,6 +63,128 @@ class _CheckOutProcessingPageState extends State<CheckOutProcessingPage>
if (mounted) Navigator.of(context).pop();
}
+ void showAdyenModal(BuildContext context) async {
+ final cubit = context.read<CheckoutCubit>();
+ final processingState = cubit.state.processingState;
+ final paymentMethod = cubit.state.paymentMethod;
+ dynamic response;
+ if (processingState is! CheckoutProcessingStateSessionReceived) return;
+ final paymentConfig = processingState.paymentConfigurations;
+ if (!mounted) return;
+ if (paymentMethod == CheckoutPaymentMethod.creditCard) {
+ final dropInConfig = paymentConfig.cardConfiguration;
+ response = await AdyenCheckout.session.startDropIn(
+ dropInConfiguration: dropInConfig,
+ checkout: paymentConfig.sessionCheckout,
+ );
+ } else {
+ if (Platform.isIOS) {
+ await _showApplePay(context, paymentConfig.sessionCheckout,
+ paymentConfig.applePayConfiguration);
+ } else {
+ await _showGooglePlayComponent(context, paymentConfig.sessionCheckout,
+ paymentConfig.googlePayConfiguration);
+ }
+ }
+ if (!mounted) return;
+ if (response is PaymentResult) {
+ cubit.onPaymentResult(response);
+ } else {
+ cubit.onUserDismissPaymentPopup();
+ }
+ }
+
+ Future<void> _showApplePay(
+ BuildContext context,
+ SessionCheckout session,
+ ApplePayComponentConfiguration applePayComponentConfiguration,
+ ) async {
+ final cubit = context.read<CheckoutCubit>();
+ await Future<void>.delayed(const Duration(milliseconds: 500));
+ if (!context.mounted) return;
+ final response = await showModalBottomSheet<dynamic>(
+ context: context,
+ builder: (context) {
+ return Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ AdyenApplePayComponent(
+ configuration: applePayComponentConfiguration,
+ checkout: session,
+ width: 200,
+ loadingIndicator: const CircularProgressIndicator(),
+ paymentMethod: const {
+ "type": "applepay",
+ "name": "Apple Pay",
+ "brands": ["mc", "visa"]
+ },
+ onPaymentResult: (result) {
+ print("qqq result=$result");
+ context.pop(result);
+ },
+ onUnavailable: () {
+ print("qqq unavailable");
+ },
+ ),
+ const SizedBox(height: 100),
+ ],
+ ),
+ );
+ },
+ );
+ if (response is PaymentResult) {
+ cubit.onPaymentResult(response);
+ } else {
+ cubit.onUserDismissPaymentPopup();
+ }
+ }
+
+ Future<void> _showGooglePlayComponent(
+ BuildContext context,
+ SessionCheckout session,
+ GooglePayComponentConfiguration googlePayComponentConfiguration,
+ ) async {
+ final cubit = context.read<CheckoutCubit>();
+ await Future<void>.delayed(const Duration(milliseconds: 500));
+ if (!context.mounted) return;
+ final response = await showModalBottomSheet<dynamic>(
+ context: context,
+ builder: (context) {
+ return Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ AdyenGooglePayComponent(
+ configuration: googlePayComponentConfiguration,
+ loadingIndicator: const CircularProgressIndicator(),
+ paymentMethod: const {
+ "type": "googlepay",
+ "name": "Google Pay",
+ "configuration": {
+ "merchantId": 50,
+ "gatewayMerchantId": "ComwellHotelsECOM"
+ }
+ },
+ onPaymentResult: (result) {
+ context.pop(result);
+ },
+ checkout: session,
+ ),
+ ],
+ ),
+ );
+ },
+ );
+ if (response is PaymentResult) {
+ cubit.onPaymentResult(response);
+ } else {
+ cubit.onUserDismissPaymentPopup();
+ }
+ }
+
@override
Widget build(BuildContext context) {
final cubit = context.read<CheckoutCubit>();
@@ -62,8 +193,12 @@ class _CheckOutProcessingPageState extends State<CheckOutProcessingPage>
alignment: Alignment.center,
color: sandColor[80],
child: Builder(builder: (context) {
- if (cubit.state.processingState == CheckoutProcessingState.confirmed) {
+ final processingState = cubit.state.processingState;
+ if (processingState is CheckoutProcessingStateConfirmed) {
return const CheckOutSuccessPage();
+ } else if (processingState
+ is CheckoutProcessingStateSessionReceived) {
+ showAdyenModal(context);
}
return Lottie.asset(
'assets/animations/load_animation.json',
@@ -72,14 +207,12 @@ class _CheckOutProcessingPageState extends State<CheckOutProcessingPage>
loadingComposition = composition;
animationController.duration = composition.duration;
switch (cubit.state.processingState) {
- case CheckoutProcessingState.processing:
- playLoading();
- case CheckoutProcessingState.success:
+ case CheckoutProcessingStateSuccess _:
playSuccess();
- case CheckoutProcessingState.error:
+ case CheckoutProcessingStateError _:
playError();
default:
- // no-op
+ playLoading();
}
},
fit: BoxFit.cover,
diff --git a/comwell_key_app/lib/check_out/pages/checkout_payment_page.dart b/comwell_key_app/lib/check_out/pages/checkout_payment_page.dart
index f0bb9253..1ace62a3 100644
--- a/comwell_key_app/lib/check_out/pages/checkout_payment_page.dart
+++ b/comwell_key_app/lib/check_out/pages/checkout_payment_page.dart
@@ -1,7 +1,7 @@
import 'package:comwell_key_app/check_out/components/accept_terms_toggle.dart';
import 'package:comwell_key_app/check_out/components/apply_club_points.dart';
import 'package:comwell_key_app/check_out/components/checkout_itemized_bill.dart';
-import 'package:comwell_key_app/check_out/components/payment_button.dart';
+import 'package:comwell_key_app/check_out/components/change_payment_button.dart';
import 'package:comwell_key_app/themes/light_theme.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@@ -31,8 +31,8 @@ class CheckoutPaymentPage extends StatelessWidget {
const SizedBox(height: 20),
const Divider(color: colorDivider),
const SizedBox(height: 20),
- const PaymentButton(),
- const SizedBox(height: 100),
+ const ChangePaymentButton(),
+ const SizedBox(height: 30),
const AcceptTermsToggle(),
const SizedBox(height: 100),
],
diff --git a/comwell_key_app/lib/overview/repository/overview_repository.dart b/comwell_key_app/lib/overview/repository/overview_repository.dart
index 7f6c69ee..cad5eda7 100644
--- a/comwell_key_app/lib/overview/repository/overview_repository.dart
+++ b/comwell_key_app/lib/overview/repository/overview_repository.dart
@@ -61,7 +61,7 @@ final response = {
"status": "current",
"image": "assets/images/current_room.png",
"hotelName": "Seaside Resort",
- "hotelCode": "SR001",
+ "hotelCode": "CBO",
"roomType": "Deluxe",
"adults": 2,
"children": 1,
@@ -86,7 +86,7 @@ final response = {
"status": "current",
"image": "assets/images/current_room.png",
"hotelName": "Mountain View Hotel",
- "hotelCode": "MV002",
+ "hotelCode": "CBO",
"confirmationId": "",
"roomType": "Suite",
"adults": 1,
@@ -111,7 +111,7 @@ final response = {
"status": "current",
"image": "assets/images/current_room.png",
"hotelName": "City Center Inn",
- "hotelCode": "CCI003",
+ "hotelCode": "CBO",
"confirmationId": "",
"roomType": "Standard",
"adults": 2,
@@ -139,7 +139,7 @@ final response = {
"status": "past",
"image": "assets/images/portside.png",
"hotelName": "Luxury Suites",
- "hotelCode": "LS004",
+ "hotelCode": "CBO",
"roomType": "Executive",
"adults": 2,
"children": 1,
@@ -164,7 +164,7 @@ final response = {
"status": "past",
"image": "assets/images/portside.png",
"hotelName": "Forest Retreat",
- "hotelCode": "FR005",
+ "hotelCode": "CBO",
"roomType": "Cottage",
"adults": 1,
"children": 0,
@@ -189,7 +189,7 @@ final response = {
"status": "past",
"image": "assets/images/borupgaard.png",
"hotelName": "Beachfront Hotel",
- "hotelCode": "BF006",
+ "hotelCode": "CBO",
"roomType": "Suite",
"adults": 2,
"children": 0,
@@ -216,7 +216,7 @@ final response = {
"status": "cancelled",
"image": "assets/images/borupgaard.png",
"hotelName": "Urban Lodge",
- "hotelCode": "UL007",
+ "hotelCode": "CBO",
"roomType": "Standard",
"adults": 1,
"children": 0,
@@ -241,7 +241,7 @@ final response = {
"status": "cancelled",
"image": "assets/images/koegestrand.png",
"hotelName": "Hilltop Cabins",
- "hotelCode": "HC008",
+ "hotelCode": "CBO",
"roomType": "Cabin",
"adults": 2,
"children": 0,
@@ -266,7 +266,7 @@ final response = {
"status": "cancelled",
"image": "assets/images/bygholmpark.png",
"hotelName": "Lakeside Bungalows",
- "hotelCode": "LB009",
+ "hotelCode": "CBO",
"roomType": "Bungalow",
"adults": 1,
"children": 0,
diff --git a/comwell_key_app/lib/pregistration/pregistration_repository.dart b/comwell_key_app/lib/pregistration/pregistration_repository.dart
index e839a933..4144873b 100644
--- a/comwell_key_app/lib/pregistration/pregistration_repository.dart
+++ b/comwell_key_app/lib/pregistration/pregistration_repository.dart
@@ -1,54 +1,97 @@
-import 'dart:io';
-import 'dart:ui';
-
import 'package:adyen_checkout/adyen_checkout.dart';
+import 'package:comwell_key_app/check_out/models/payment_configurations.dart';
import 'package:comwell_key_app/profile_settings/repostiory/profile_settings_repository.dart';
import 'package:comwell_key_app/services/adyen/adyen_amount.dart';
import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
import 'package:comwell_key_app/services/api.dart';
import 'package:comwell_key_app/utils/locator.dart';
-import 'package:flutter_dotenv/flutter_dotenv.dart';
-
class PreregistrationRepository {
final Api _api = Api();
final ProfileSettingsRepository profileSettingsRepository =
- locator<ProfileSettingsRepository>();
+ locator<ProfileSettingsRepository>();
PreregistrationRepository();
- Future<SessionCheckout> sessionCheckout(AdyenAmount amount) async {
- final response = await _api.createAdyenSession(amount);
- final id = response["Id"] as String;
- final sessionData = response["SessionData"] as String;
- return AdyenCheckout.session.create(
+ Future<PaymentConfigurations> sessionCheckout(AdyenAmount amount, String hotelCode) async {
+ final response = await _api.createAdyenSession(amount, hotelCode);
+ final clientKey = response["ClientKey"] as String;
+ final sessionResponse = response["SessionResponse"];
+ final id = sessionResponse["Id"] as String;
+ final sessionData = sessionResponse["SessionData"] as String;
+ final session = await AdyenCheckout.session.create(
sessionId: id,
sessionData: sessionData,
- configuration: cardComponentConfiguration());
+ configuration: cardComponentConfiguration(amount, clientKey));
+ return PaymentConfigurations(
+ sessionCheckout: session,
+ googlePayConfiguration: _getGooglePayComponentConfig(clientKey),
+ cardConfiguration: cardComponentConfiguration(amount, clientKey),
+ applePayConfiguration: _applePayComponentConfiguration(clientKey, amount));
}
- CardComponentConfiguration cardComponentConfiguration() {
+ DropInConfiguration cardComponentConfiguration(
+ AdyenAmount amount, String clientKey) {
// TODO: missing endpoint to retrieve client key
- return CardComponentConfiguration(
+ return DropInConfiguration(
+ environment: Environment.test,
+ clientKey: clientKey,
+ countryCode: "DK",
+ googlePayConfiguration: _googlePayConfiguration,
+ applePayConfiguration: _getApplePlayConfig(amount),
+ cardConfiguration: null,
+ paymentMethodNames: {
+ "scheme": "Credit card",
+ },
+ );
+ }
+
+ GooglePayConfiguration get _googlePayConfiguration =>
+ const GooglePayConfiguration(googlePayEnvironment: GooglePayEnvironment.test);
+
+ GooglePayComponentConfiguration _getGooglePayComponentConfig(
+ String clientKey) {
+ return GooglePayComponentConfiguration(
+ environment: Environment.test,
+ countryCode: "DK",
+ clientKey: clientKey,
+ googlePayConfiguration: _googlePayConfiguration,
+ );
+ }
+
+ ApplePayComponentConfiguration _applePayComponentConfiguration(String clientKey, AdyenAmount amount) {
+ return ApplePayComponentConfiguration(
environment: Environment.test,
- clientKey: dotenv.env['ADYEN_CLIENT_KEY']!,
- countryCode: Locale(Platform.localeName).languageCode,
- cardConfiguration: const CardConfiguration(),
+ countryCode: "DK",
+ clientKey: clientKey,
+ applePayConfiguration: _getApplePlayConfig(amount),
);
}
+ ApplePayConfiguration _getApplePlayConfig(AdyenAmount amount) {
+ return ApplePayConfiguration(
+ merchantId: "merchant.ComwellHotelsECOM",
+ merchantName: "Comwell",
+ allowOnboarding: true,
+ allowShippingContactEditing: true,
+ applePaySummaryItems: [
+ ApplePaySummaryItem(
+ label: "Total",
+ amount: Amount(value: amount.value, currency: amount.currency),
+ type: ApplePaySummaryItemType.definite)
+ ]);
+ }
static final Iterable<StoredPaymentMethod> mockStoredPaymentData = [
1,
2,
3,
4
- ].map((i) =>
- StoredPaymentMethod(
- expiryMonth: "12",
- expiryYear: "2035",
- holderName: "holder name",
- id: "id $i",
- lastFour: "$i$i$i$i",
- type: "visa"));
+ ].map((i) => StoredPaymentMethod(
+ expiryMonth: "12",
+ expiryYear: "2035",
+ holderName: "holder name",
+ id: "id $i",
+ lastFour: "$i$i$i$i",
+ type: "visa"));
}
diff --git a/comwell_key_app/lib/routing/app_router.dart b/comwell_key_app/lib/routing/app_router.dart
index f4625ab9..6cf18b64 100644
--- a/comwell_key_app/lib/routing/app_router.dart
+++ b/comwell_key_app/lib/routing/app_router.dart
@@ -230,8 +230,9 @@ GoRouter goRouter(AuthenticationBloc authBloc) {
path: "/${AppRoutes.checkOut.name}",
name: AppRoutes.checkOut.name,
builder: (context, state) {
+ final booking = state.extra as Booking;
return BlocProvider(
- create: (context) => CheckoutCubit(),
+ create: (context) => CheckoutCubit(booking),
child: BlocBuilder<CheckoutCubit, CheckoutState>(
builder: (context, state) {
return CheckOutFlow(key: ValueKey(state));
diff --git a/comwell_key_app/lib/services/adyen/stored_payment_methods_response.dart b/comwell_key_app/lib/services/adyen/stored_payment_methods_response.dart
index 23da22cc..0998324b 100644
--- a/comwell_key_app/lib/services/adyen/stored_payment_methods_response.dart
+++ b/comwell_key_app/lib/services/adyen/stored_payment_methods_response.dart
@@ -1,4 +1,3 @@
-import 'package:comwell_key_app/services/adyen/payment_method.dart';
import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
import 'package:comwell_key_app/utils/json.dart';
import 'package:json_annotation/json_annotation.dart';
diff --git a/comwell_key_app/lib/services/api.dart b/comwell_key_app/lib/services/api.dart
index 135e87bc..ae981b90 100644
--- a/comwell_key_app/lib/services/api.dart
+++ b/comwell_key_app/lib/services/api.dart
@@ -34,12 +34,11 @@ class Api {
return StoredPaymentsResponse.fromJson(response.data!);
}
- Future<dynamic> createAdyenSession(AdyenAmount amount) async {
+ Future<dynamic> createAdyenSession(AdyenAmount amount, String hotelCode) async {
final body = {
- "currency": amount.currency,
+ "hotelCode": hotelCode,
"amount": amount.value,
- "returnUrl": "https://",
- "countryCode": "DK"
+ "returnUrl": "adyencheckout://com.comwell.phoenix.test/adyenPayment",
};
final json = jsonEncode(body);
final response = await dio.post<dynamic>(
diff --git a/comwell_key_app/lib/services/interceptors/response_handle_interceptor.dart b/comwell_key_app/lib/services/interceptors/response_handle_interceptor.dart
index f0ad8f18..ca37aa80 100644
--- a/comwell_key_app/lib/services/interceptors/response_handle_interceptor.dart
+++ b/comwell_key_app/lib/services/interceptors/response_handle_interceptor.dart
@@ -42,6 +42,7 @@ class ResponseHandleInterceptor extends Interceptor {
@override
Future<dynamic> onError(DioException err, ErrorInterceptorHandler handler) async {
final response = err.response;
+ print("qqq err=$err");
if (response == null) throw Exception("Missing response");
final statusCode = response.statusCode;
try {
diff --git a/comwell_key_app/lib/themes/dark_theme.dart b/comwell_key_app/lib/themes/dark_theme.dart
index 3117aaf1..3aef8ff2 100644
--- a/comwell_key_app/lib/themes/dark_theme.dart
+++ b/comwell_key_app/lib/themes/dark_theme.dart
@@ -13,14 +13,13 @@ ThemeData darkTheme = ThemeData(
circularTrackColor: Colors.grey,
),
textTheme: const TextTheme(
- displayLarge: TextStyle(fontSize: 36.0, fontWeight: FontWeight.w600),
- displayMedium: TextStyle(fontSize: 34.0, fontWeight: FontWeight.w600),
- headlineLarge: TextStyle(fontSize: 24.0, fontWeight: FontWeight.w600),
- headlineMedium: TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600),
- headlineSmall: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600),
- bodyMedium: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600),
- bodySmall: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500)
- ),
+ displayLarge: TextStyle(fontSize: 36.0, fontWeight: FontWeight.w600),
+ displayMedium: TextStyle(fontSize: 34.0, fontWeight: FontWeight.w600),
+ headlineLarge: TextStyle(fontSize: 24.0, fontWeight: FontWeight.w600),
+ headlineMedium: TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600),
+ headlineSmall: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600),
+ bodyMedium: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600),
+ bodySmall: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500)),
colorScheme: const ColorScheme(
primary: colorPrimary,
secondary: colorSecondary,
@@ -45,15 +44,15 @@ const colorPrimaryText = Color(0xFF000000);
const colorSecondaryText = Color(0xFF000000);
const colorOnPrimaryTextColor = Color(0xFFFFFFFF);
const colorPrimarySystem = Color(0xFF000000);
-const colorSecondarySystem =Color.fromARGB(237, 227, 216, 1);
+const colorSecondarySystem = Color.fromARGB(237, 227, 216, 1);
const colorTertiary = Color(0xFF000000);
const colorTertiaryText = Color(0xFF000000);
const colorTertiarySystem = Color(0xFF000000);
const colorShadow = Color(0xFF000000);
+const colorError = Color(0xFFEB0026);
const int _earthColor = 0xFF677169;
-const earthColor = MaterialColor(_earthColor, <int,Color>
-{
+const earthColor = MaterialColor(_earthColor, <int, Color>{
100: Color(_earthColor),
80: Color.fromRGBO(128, 139, 130, 1.0),
60: Color.fromRGBO(160, 171, 163, 1.0),
@@ -62,14 +61,12 @@ const earthColor = MaterialColor(_earthColor, <int,Color>
10: Color.fromRGBO(238, 239, 238, 1.0),
});
-
const int _sandColor = 0xFFAA8D65;
-const sandColor = MaterialColor(_sandColor, <int,Color>
-{
+const sandColor = MaterialColor(_sandColor, <int, Color>{
100: Color(_sandColor),
80: Color.fromRGBO(190, 161, 121, 1.0),
60: Color.fromRGBO(215, 201, 185, 1.0),
40: Color.fromRGBO(237, 227, 216, 1.0),
20: Color.fromRGBO(240, 234, 226, 1.0),
10: Color(0xFFF9F6F2),
-});
\ No newline at end of file
+});