diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index d6448e8f..da0954d4 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -211,7 +211,7 @@ class ApiClientImp implements ApiClient { } body['TokenID'] = "@dm!n"; - // body['PatientID'] = 1987471; + // body['PatientID'] = 7000792; // body['PatientID'] = 53320; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index a5093815..37fd936b 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -384,6 +384,7 @@ class AppDependencies { getIt.registerLazySingleton(() => MyFatoorahViewModel( appState: getIt(), errorHandlerService: getIt(), + payfortRepo: getIt(), )); getIt.registerLazySingleton( diff --git a/lib/features/myfatoorah/myfatoorah_view_model.dart b/lib/features/myfatoorah/myfatoorah_view_model.dart index 4e91f094..fb7a23fa 100644 --- a/lib/features/myfatoorah/myfatoorah_view_model.dart +++ b/lib/features/myfatoorah/myfatoorah_view_model.dart @@ -1,8 +1,18 @@ +import 'dart:developer'; + +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/cache_consts.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/myFatoorah_config.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/features/payfort/models/payfort_request_insert_model.dart'; +import 'package:hmg_patient_app_new/features/payfort/models/payfort_response_insert_model.dart'; +import 'package:hmg_patient_app_new/features/payfort/payfort_repo.dart'; +import 'package:hmg_patient_app_new/generated/codegen_loader.g.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; @@ -11,10 +21,12 @@ import 'package:myfatoorah_flutter/myfatoorah_flutter.dart'; class MyFatoorahViewModel extends ChangeNotifier { final AppState appState; final ErrorHandlerService errorHandlerService; + final PayfortRepo payfortRepo; MyFatoorahViewModel({ required this.appState, required this.errorHandlerService, + required this.payfortRepo, }); // Payment Method ID @@ -25,26 +37,94 @@ class MyFatoorahViewModel extends ChangeNotifier { num amount = 10.0, paymentDescription = "", String displayCurrencyIso = MFCurrencyISO.KUWAIT_KWD, + required String paymentOption, + required String liveServiceID, + required String isScheduleLiveCare, + required String appointmentDate, + required String appointmentNo, + required String doctorID, + required String fileNumber, + required String serviceID, + required String projectID, Function(MFGetPaymentStatusResponse)? onSuccess, Function(String)? onError, }) async { LoaderBottomSheet.showLoader(); - await MFSDK.init(MyFatoorahConfig.configAPIKey, ApiConsts.myFatoorahCountry, ApiConsts.myFatoorahEnvironmentType); MFSDK.setUpActionBar(toolBarTitle: paymentDescription, toolBarTitleColor: "#ffffff", toolBarBackgroundColor: '#ED1C2B', isShowToolBar: true); - var request = MFExecutePaymentRequest(paymentMethodId: 2, invoiceValue: amount); + var request = MFExecutePaymentRequest(paymentMethodId: paymentOption.toLowerCase() == "mada" ? 6 : 2, invoiceValue: amount); request.displayCurrencyIso = displayCurrencyIso; request.customerName = ApiConsts.appEnvironmentType == AppEnvironmentTypeEnum.uat ? "Test test" : "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}"; request.customerEmail = "CustID_${appState.getAuthenticatedUser()!.patientId}@HMG.com"; - await MFSDK.executePayment(request, appState.isArabic() ? MFLanguage.ARABIC : MFLanguage.ENGLISH, (invoiceId) { + await MFSDK.executePayment(request, appState.isArabic() ? MFLanguage.ARABIC : MFLanguage.ENGLISH, (invoiceId) async { + PayfortRequestInsertModel payfortRequestInsertModel = PayfortRequestInsertModel(); + + payfortRequestInsertModel.commandType = "SALE"; + payfortRequestInsertModel.amount = amount; + payfortRequestInsertModel.customerEmail = getIt.get().getAuthenticatedUser()!.emailAddress; + payfortRequestInsertModel.orderDescription = paymentDescription; + payfortRequestInsertModel.serviceID = serviceID; + payfortRequestInsertModel.paymentOption = paymentOption; + payfortRequestInsertModel.clientRequestID = invoiceId; + payfortRequestInsertModel.projectID = projectID; + payfortRequestInsertModel.fileNumber = getIt.get().getAuthenticatedUser()!.patientId.toString(); + payfortRequestInsertModel.customerName = "${getIt.get().getAuthenticatedUser()!.firstName} ${getIt.get().getAuthenticatedUser()!.lastName}"; + payfortRequestInsertModel.currency = getIt.get().getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED"; + payfortRequestInsertModel.liveServiceID = liveServiceID; + payfortRequestInsertModel.latitude = getIt.get().userLat.toString(); + payfortRequestInsertModel.longitude = getIt.get().userLong.toString(); + payfortRequestInsertModel.merchantReference = invoiceId; + payfortRequestInsertModel.deviceToken = await Utils.getStringFromPrefs(CacheConst.pushToken); + payfortRequestInsertModel.language = getIt.get().isArabic() ? "ar" : "en"; + payfortRequestInsertModel.integrationId = "6"; // PayTabs integration ID + payfortRequestInsertModel.isSchedule = isScheduleLiveCare; + payfortRequestInsertModel.appointmentDate = appointmentDate; + payfortRequestInsertModel.appointmentNo = appointmentNo; + payfortRequestInsertModel.doctorID = doctorID; + + // Call request insert API before payment + await paytabsRequestInsert(payfortRequestInsertModel: payfortRequestInsertModel); + LoaderBottomSheet.hideLoader(); - print(invoiceId); - }).then((value) { - if (onSuccess != null) { - onSuccess(value); + }).then((value) async { + var valJson = value.toString(); + print(valJson); + + // // Create PayfortResponseInsertModel (same as Payfort implementation) + PayfortResponseInsertModel payfortResponseInsertModel = PayfortResponseInsertModel(); + + payfortResponseInsertModel.fortId = value.invoiceTransactions!.first.transactionId ?? ""; + payfortResponseInsertModel.commandType = "SALE"; + // payfortResponseInsertModel.amount = paytabsTransactionResponseModel.tranTotal ?? 0; + payfortResponseInsertModel.amount = amount; + payfortResponseInsertModel.sadadOLP = ""; + payfortResponseInsertModel.paymentOption = value.invoiceTransactions!.first.paymentGateway ?? ""; + payfortResponseInsertModel.customerIP = ""; + payfortResponseInsertModel.eCI = ""; + payfortResponseInsertModel.responseMessage = value.invoiceTransactions!.first.transactionStatus ?? ""; + payfortResponseInsertModel.cardNumber = value.invoiceTransactions!.first.cardNumber ?? ""; + payfortResponseInsertModel.cardBin = ""; + payfortResponseInsertModel.installmentsNumber = 0; + payfortResponseInsertModel.status = (value.invoiceStatus ?? "").toLowerCase() == "paid" ? "14" : "00"; + payfortResponseInsertModel.merchantRef = value.invoiceId.toString(); + payfortResponseInsertModel.isRefund = false; + payfortResponseInsertModel.remmeberMe = true; + payfortResponseInsertModel.reconciliationReference = ""; + + // Call response insert API after payment + await paytabsResponseInsert(payfortResponseInsertModel: payfortResponseInsertModel); + + if ((value.invoiceStatus ?? "").toLowerCase() == "paid") { + if (onSuccess != null) { + onSuccess(value); + } + } else { + if (onError != null) { + onError(LocaleKeys.paymentFailedPleaseTryAgain.tr()); + } } }).catchError((error) { if (onError != null) { @@ -52,4 +132,60 @@ class MyFatoorahViewModel extends ChangeNotifier { } }); } + + initApplePayPayment(num invoiceValue, MFApplePayButton mfApplePayButton) async { + await MFSDK.init(MyFatoorahConfig.configAPIKey, ApiConsts.myFatoorahCountry, ApiConsts.myFatoorahEnvironmentType); + + await MFSDK.initSession(MFInitiateSessionRequest(), MFLanguage.ENGLISH).then((value) async { + var executePaymentRequest = MFExecutePaymentRequest(invoiceValue: 121, displayCurrencyIso: MFCurrencyISO.KUWAIT_KWD); + + await mfApplePayButton.executeApplePayButton( + executePaymentRequest, + (String invoiceId) { + print("Payment Success! Invoice ID: $invoiceId"); + }, + ).catchError((error) { + // If initialized properly, this error won't occur + print("Apple Pay Error: ${error.message}"); + }); + }).catchError((error) { + log(error.message); + }); + } + + Future paytabsRequestInsert({required PayfortRequestInsertModel payfortRequestInsertModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await payfortRepo.payfortRequestInsert(payfortRequestInsertModel: payfortRequestInsertModel); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + + Future paytabsResponseInsert({required PayfortResponseInsertModel payfortResponseInsertModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await payfortRepo.payfortResponseInsert(payfortResponseInsertModel: payfortResponseInsertModel); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } } diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart index dfb7497c..40a79370 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart @@ -11,6 +11,7 @@ import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/cache_consts.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; +import 'package:hmg_patient_app_new/core/myFatoorah_config.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; import 'package:hmg_patient_app_new/features/myfatoorah/myfatoorah_view_model.dart'; @@ -35,6 +36,7 @@ import 'package:hmg_patient_app_new/widgets/in_app_browser/InAppBrowser.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:myfatoorah_flutter/MFEnums.dart'; +import 'package:myfatoorah_flutter/myfatoorah_flutter.dart'; import 'package:provider/provider.dart'; import 'package:smooth_corner/smooth_corner.dart'; @@ -53,6 +55,8 @@ class _ImmediateLiveCarePaymentPageState extends State(); myAppointmentsViewModel = Provider.of(context, listen: false); immediateLiveCareViewModel = Provider.of(context, listen: false); @@ -135,7 +142,62 @@ class _ImmediateLiveCarePaymentPageState extends State false); + Navigator.of(context).push( + CustomPageRoute( + page: ImmediateLiveCarePendingRequestPage(), + ), + ); + } else { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Unknown error occurred..."), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } + }, + onError: (errMessage) { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: errMessage.toString()), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + } else if (appState.isPaytabsEnabled) { transID = Utils.getAppointmentTransID( immediateLiveCareViewModel.immediateLiveCareSelectedClinic.serviceID!, ApiConsts.appEnvironmentType == AppEnvironmentTypeEnum.uat ? 15 : 12, @@ -311,7 +373,43 @@ class _ImmediateLiveCarePaymentPageState extends State false); + Navigator.of(context).push( + CustomPageRoute( + page: ImmediateLiveCarePendingRequestPage(), + ), + ); + } else { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Unknown error occurred..."), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } + }, onError: (errMessage) { showCommonBottomSheetWithoutHeight( context, @@ -633,16 +731,31 @@ class _ImmediateLiveCarePaymentPageState extends State