Paytabs implementation contd.

pull/317/head
haroon amjad 1 month ago
parent 73066ba21a
commit 0db762fa2c

@ -44,6 +44,8 @@ class AppState {
AuthenticatedUser? _authenticatedRootUser;
AuthenticatedUser? _authenticatedChildUser;
bool isPaytabsEnabled = true;
int? _superUserID;
bool isChildLoggedIn = false;
bool isGMSAvailable = true;

@ -48,6 +48,7 @@ import 'package:hmg_patient_app_new/features/notifications/notifications_repo.da
import 'package:hmg_patient_app_new/features/notifications/notifications_view_model.dart';
import 'package:hmg_patient_app_new/features/payfort/payfort_repo.dart';
import 'package:hmg_patient_app_new/features/payfort/payfort_view_model.dart';
import 'package:hmg_patient_app_new/features/paytabs/paytabs_view_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_repo.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_repo.dart';
@ -327,5 +328,7 @@ class AppDependencies {
getIt.registerLazySingleton<ServicesPriceListViewModel>(() => ServicesPriceListViewModel(servicesPriceListRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<DateRangCalenderModel>(() => DateRangCalenderModel(appState: getIt(), navigationService: getIt(), dialogService: getIt()));
getIt.registerLazySingleton<PayTabsViewModel>(() => PayTabsViewModel(appState: getIt()));
}
}

@ -0,0 +1,12 @@
/// Default configuration values for PayTabs Payment SDK
class PaymentSdkDefaultConfig {
static const String profileID = "119730";
static const String serverKey = "SWJ9LD22MT-JLJZLBKTLK-WGWTLWGTWR";
static const String clientKey = "C7K2DQ-PDDN6B-69B2K7-P9GB9T";
static const String defaultCurrency = "SAR";
static const double defaultAmount = 10.0;
static const String defaultMerchantCountryCode = "SA";
static const String defaultMerchantName = "Sulaiman Al Habib Medical Group";
static const String defaultMerchantAppleBundleID = "merchant.com.hmgwebservices";
static const String defaultMerchantAppleBundleIDUAT = "merchant.com.hmgwebservices.uat";
}

@ -0,0 +1,133 @@
class PaytabsTransactionResponseModel {
int? tranTotal;
String? transactionReference;
String? cartCurrency;
String? cartDescription;
String? cartID;
String? tranCurrency;
String? payResponseReturn;
bool? isPending;
bool? isOnHold;
String? token;
String? transactionType;
bool? isAuthorized;
String? trace;
int? cartAmount;
int? merchantId;
int? profileId;
bool? isProcessed;
int? serviceId;
PaymentInfo? paymentInfo;
bool? isSuccess;
PaytabsTransactionResponseModel(
{this.tranTotal,
this.transactionReference,
this.cartCurrency,
this.cartDescription,
this.cartID,
this.tranCurrency,
this.payResponseReturn,
this.isPending,
this.isOnHold,
this.token,
this.transactionType,
this.isAuthorized,
this.trace,
this.cartAmount,
this.merchantId,
this.profileId,
this.isProcessed,
this.serviceId,
this.paymentInfo,
this.isSuccess});
PaytabsTransactionResponseModel.fromJson(Map<String, dynamic> json) {
tranTotal = json['tran_total'];
transactionReference = json['transactionReference'];
cartCurrency = json['cartCurrency'];
cartDescription = json['cartDescription'];
cartID = json['cartID'];
tranCurrency = json['tran_currency'];
payResponseReturn = json['payResponseReturn'];
isPending = json['isPending'];
isOnHold = json['isOnHold'];
token = json['token'];
transactionType = json['transactionType'];
isAuthorized = json['isAuthorized'];
trace = json['trace'];
cartAmount = json['cartAmount'];
merchantId = json['merchantId'];
profileId = json['profileId'];
isProcessed = json['isProcessed'];
serviceId = json['serviceId'];
paymentInfo = json['paymentInfo'] != null
? new PaymentInfo.fromJson(json['paymentInfo'])
: null;
isSuccess = json['isSuccess'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['tran_total'] = this.tranTotal;
data['transactionReference'] = this.transactionReference;
data['cartCurrency'] = this.cartCurrency;
data['cartDescription'] = this.cartDescription;
data['cartID'] = this.cartID;
data['tran_currency'] = this.tranCurrency;
data['payResponseReturn'] = this.payResponseReturn;
data['isPending'] = this.isPending;
data['isOnHold'] = this.isOnHold;
data['token'] = this.token;
data['transactionType'] = this.transactionType;
data['isAuthorized'] = this.isAuthorized;
data['trace'] = this.trace;
data['cartAmount'] = this.cartAmount;
data['merchantId'] = this.merchantId;
data['profileId'] = this.profileId;
data['isProcessed'] = this.isProcessed;
data['serviceId'] = this.serviceId;
if (this.paymentInfo != null) {
data['paymentInfo'] = this.paymentInfo!.toJson();
}
data['isSuccess'] = this.isSuccess;
return data;
}
}
class PaymentInfo {
String? cardScheme;
String? cardType;
int? expiryMonth;
int? expiryYear;
String? paymentDescription;
String? paymentMethod;
PaymentInfo(
{this.cardScheme,
this.cardType,
this.expiryMonth,
this.expiryYear,
this.paymentDescription,
this.paymentMethod});
PaymentInfo.fromJson(Map<String, dynamic> json) {
cardScheme = json['cardScheme'];
cardType = json['cardType'];
expiryMonth = json['expiryMonth'];
expiryYear = json['expiryYear'];
paymentDescription = json['paymentDescription'];
paymentMethod = json['payment_method'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['cardScheme'] = this.cardScheme;
data['cardType'] = this.cardType;
data['expiryMonth'] = this.expiryMonth;
data['expiryYear'] = this.expiryYear;
data['paymentDescription'] = this.paymentDescription;
data['payment_method'] = this.paymentMethod;
return data;
}
}

@ -0,0 +1,23 @@
import 'package:dartz/dartz.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
abstract class PaytabsService {
Future<Either<Failure, dynamic>> getAskDoctorAppointmentsList();
Future<Either<Failure, dynamic>> getDoctorResponse();
}
class PaytabsServiceImp implements PaytabsService {
@override
Future<Either<Failure, dynamic>> getAskDoctorAppointmentsList() {
// TODO: implement getAskDoctorAppointmentsList
throw UnimplementedError();
}
@override
Future<Either<Failure, dynamic>> getDoctorResponse() {
// TODO: implement getDoctorResponse
throw UnimplementedError();
}
}

@ -0,0 +1,103 @@
import 'package:flutter/material.dart';
import 'package:flutter_paytabs_bridge/BaseBillingShippingInfo.dart';
import 'package:flutter_paytabs_bridge/IOSThemeConfiguration.dart';
import 'package:flutter_paytabs_bridge/PaymentSdkConfigurationDetails.dart';
import 'package:flutter_paytabs_bridge/PaymentSdkLocale.dart';
import 'package:flutter_paytabs_bridge/PaymentSdkTokeniseType.dart';
import 'package:flutter_paytabs_bridge/PaymentSdkTransactionType.dart';
import 'package:flutter_paytabs_bridge/flutter_paytabs_bridge.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/enums.dart';
import 'package:hmg_patient_app_new/core/paytabs_config.dart';
import 'package:hmg_patient_app_new/features/paytabs/models/paytabs_transaction_response_model.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
class PayTabsViewModel extends ChangeNotifier {
late PaymentSdkConfigurationDetails paymentConfiguration;
final AppState appState;
late PaytabsTransactionResponseModel paytabsTransactionResponseModel;
PayTabsViewModel({
required this.appState,
});
setPaymentConfiguration(String paymentDescription, num amount) {
String cartID = DateTime.now().millisecondsSinceEpoch.toString();
paymentConfiguration = PaymentSdkConfigurationDetails(
profileId: PaymentSdkDefaultConfig.profileID,
serverKey: PaymentSdkDefaultConfig.serverKey,
clientKey: PaymentSdkDefaultConfig.clientKey,
transactionType: PaymentSdkTransactionType.SALE,
cartId: cartID.substring((cartID.length - 5), cartID.length),
cartDescription: paymentDescription,
merchantName: PaymentSdkDefaultConfig.defaultMerchantName,
merchantApplePayIndentifier:
ApiConsts.appEnvironmentType == AppEnvironmentTypeEnum.uat ? PaymentSdkDefaultConfig.defaultMerchantAppleBundleIDUAT : PaymentSdkDefaultConfig.defaultMerchantAppleBundleID,
screentTitle: paymentDescription,
amount: amount.toDouble(),
showBillingInfo: false,
forceShippingInfo: false,
currencyCode: PaymentSdkDefaultConfig.defaultCurrency,
merchantCountryCode: PaymentSdkDefaultConfig.defaultMerchantCountryCode,
billingDetails: BillingDetails(appState.getAuthenticatedUser()!.firstName ?? "HMG Patient", "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com",
appState.getAuthenticatedUser()!.mobileNumber ?? "0000000000", "Riyadh", "SA", "Riyadh", "Riyadh", "12626"),
shippingDetails: ShippingDetails(appState.getAuthenticatedUser()!.firstName ?? "HMG Patient", "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com",
appState.getAuthenticatedUser()!.mobileNumber ?? "0000000000", "Riyadh", "SA", "Riyadh", "Riyadh", "12626"),
alternativePaymentMethods: [],
linkBillingNameWithCardHolderName: true,
simplifyApplePayValidation: true);
paymentConfiguration.iOSThemeConfigurations = IOSThemeConfigurations(
// logoImage: "assets/images/png/hmg_logo.png",
backgroundColor: "ffffff",
backgroundColorDark: "ffffff",
secondaryColor: "ED1C2B",
secondaryColorDark: "ED1C2B",
primaryColor: "ffffff",
primaryColorDark: "ffffff",
primaryFont: "Poppins",
titleFontColor: "2E3039",
titleFontColorDark: "2E3039",
titleFont: "Poppins",
primaryFontColor: "2E3039",
primaryFontColorDark: "2E3039",
inputFieldBackgroundColor: "ffffff",
inputFieldBackgroundColorDark: "ffffff",
placeholderColor: "2E3039",
placeholderColorDark: "2E3039",
buttonColor: "ED1C2B",
buttonColorDark: "ED1C2B",
buttonFont: "Poppins",
);
paymentConfiguration.tokeniseType = PaymentSdkTokeniseType.MERCHANT_MANDATORY;
notifyListeners();
}
startCardPayment({Function(dynamic)? onSuccess, Function(String)? onError}) {
FlutterPaytabsBridge.startCardPayment(paymentConfiguration, (event) {
final transactionDetails = event["data"];
if (event["status"] == "success") {
paytabsTransactionResponseModel = PaytabsTransactionResponseModel.fromJson(event["data"]);
if (paytabsTransactionResponseModel.isSuccess!) {
onSuccess!(paytabsTransactionResponseModel);
} else {
// Transaction was processed but failed
final reason = transactionDetails["payResponseReturn"] ?? transactionDetails["responseMessage"] ?? transactionDetails["message"] ?? "Unknown error";
final responseCode = transactionDetails["responseCode"] ?? "";
final errorMessage = responseCode.isNotEmpty ? "Transaction failed (Code: $responseCode): $reason" : "Transaction failed: $reason";
onError!(errorMessage);
}
} else if (event["status"] == "error") {
final errorMessage = event["message"] ?? "An error occurred";
debugPrint("Error occurred in transaction: $errorMessage");
debugPrint("Full error event: $event");
onError!(errorMessage);
} else if (event["status"] == "event") {
final eventMessage = event["message"] ?? "Event occurred";
debugPrint("Event occurred: $eventMessage");
}
});
}
}

@ -29,6 +29,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/appointment_rating_
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/notifications/notifications_view_model.dart';
import 'package:hmg_patient_app_new/features/paytabs/paytabs_view_model.dart';
import 'package:hmg_patient_app_new/features/todo_section/todo_section_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/appointment_queue_page.dart';
@ -413,6 +414,9 @@ class _LandingPageState extends State<LandingPage> {
myAppointmentsViewModel.onTabChange(0);
myAppointmentsViewModel.updateListWRTTab(0);
Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage()));
// getIt.get<PayTabsViewModel>().setPaymentConfiguration("Appointment Payment", 15.5);
// getIt.get<PayTabsViewModel>().startCardPayment();
}),
Consumer3<MyAppointmentsViewModel, ImmediateLiveCareViewModel, TodoSectionViewModel>(
builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) {

@ -101,11 +101,11 @@ dependencies:
flutter_widget_from_html: ^0.17.1
huawei_map: ^6.12.0+301
flutter_image_compress: ^2.3.0
scrollable_positioned_list: ^0.3.8
in_app_review: ^2.0.11
flutter_paytabs_bridge: ^2.7.13
dev_dependencies:
flutter_test:
sdk: flutter

Loading…
Cancel
Save