|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:flutter_paytabs_bridge/BaseBillingShippingInfo.dart';
|
|
|
import 'package:flutter_paytabs_bridge/IOSThemeConfiguration.dart';
|
|
|
import 'package:flutter_paytabs_bridge/PaymentSDKNetworks.dart';
|
|
|
import 'package:flutter_paytabs_bridge/PaymentSdkApms.dart';
|
|
|
import 'package:flutter_paytabs_bridge/PaymentSdkConfigurationDetails.dart';
|
|
|
import 'package:flutter_paytabs_bridge/PaymentSdkLocale.dart';
|
|
|
import 'package:flutter_paytabs_bridge/PaymentSdkTokenFormat.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/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/paytabs_config.dart';
|
|
|
import 'package:hmg_patient_app_new/core/utils/utils.dart';
|
|
|
import 'package:hmg_patient_app_new/features/paytabs/models/paytabs_transaction_response_model.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/services/error_handler_service.dart';
|
|
|
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
|
|
|
|
|
|
class PayTabsViewModel extends ChangeNotifier {
|
|
|
late PaymentSdkConfigurationDetails paymentConfiguration;
|
|
|
final AppState appState;
|
|
|
final PayfortRepo payfortRepo;
|
|
|
final ErrorHandlerService errorHandlerService;
|
|
|
late PaytabsTransactionResponseModel paytabsTransactionResponseModel;
|
|
|
|
|
|
PayTabsViewModel({
|
|
|
required this.appState,
|
|
|
required this.payfortRepo,
|
|
|
required this.errorHandlerService,
|
|
|
});
|
|
|
|
|
|
setPaymentConfiguration(String paymentDescription, num amount, {bool isAddCard = false}) {
|
|
|
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,
|
|
|
locale: appState.isArabic() ? PaymentSdkLocale.AR : PaymentSdkLocale.EN,
|
|
|
merchantApplePayIndentifier: ApiConsts.appEnvironmentType == AppEnvironmentTypeEnum.uat
|
|
|
? PaymentSdkDefaultConfig.defaultMerchantAppleBundleIDUAT
|
|
|
: PaymentSdkDefaultConfig.defaultMerchantAppleBundleID,
|
|
|
// merchantApplePayIndentifier: PaymentSdkDefaultConfig.defaultMerchantAppleBundleIDUAT,
|
|
|
screentTitle: paymentDescription,
|
|
|
amount: amount.toDouble(),
|
|
|
showBillingInfo: false,
|
|
|
forceShippingInfo: false,
|
|
|
currencyCode: PaymentSdkDefaultConfig.defaultCurrency,
|
|
|
merchantCountryCode: PaymentSdkDefaultConfig.defaultMerchantCountryCode,
|
|
|
billingDetails: BillingDetails(
|
|
|
"${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}" ?? "HMG Patient",
|
|
|
"CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com",
|
|
|
appState.getAuthenticatedUser()!.mobileNumber ?? "0000000000",
|
|
|
"Riyadh",
|
|
|
"SA",
|
|
|
"Riyadh",
|
|
|
"Riyadh",
|
|
|
"12626"),
|
|
|
shippingDetails: ShippingDetails(
|
|
|
"${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}" ?? "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: "191919",
|
|
|
secondaryColorDark: "191919",
|
|
|
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",
|
|
|
inputsCornerRadius: 12
|
|
|
// buttonFont: "Poppins",
|
|
|
);
|
|
|
paymentConfiguration.tokeniseType = PaymentSdkTokeniseType.USER_OPTIONAL_DEFAULT_ON;
|
|
|
paymentConfiguration.tokenFormat = PaymentSdkTokenFormat.Hex32Format;
|
|
|
|
|
|
notifyListeners();
|
|
|
}
|
|
|
|
|
|
setAlternatePaymentConfiguration(String paymentDescription, num amount, {bool isAddCard = false}) {
|
|
|
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,
|
|
|
locale: appState.isArabic() ? PaymentSdkLocale.AR : PaymentSdkLocale.EN,
|
|
|
screentTitle: paymentDescription,
|
|
|
amount: amount.toDouble(),
|
|
|
showBillingInfo: false,
|
|
|
forceShippingInfo: false,
|
|
|
currencyCode: PaymentSdkDefaultConfig.defaultCurrency,
|
|
|
merchantCountryCode: PaymentSdkDefaultConfig.defaultMerchantCountryCode,
|
|
|
billingDetails: BillingDetails("${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}" ?? "HMG Patient",
|
|
|
"CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com", appState.getAuthenticatedUser()!.mobileNumber ?? "0000000000", "Riyadh", "SA", "Riyadh", "Riyadh", "12626"),
|
|
|
shippingDetails: ShippingDetails("${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}" ?? "HMG Patient",
|
|
|
"CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com", appState.getAuthenticatedUser()!.mobileNumber ?? "0000000000", "Riyadh", "SA", "Riyadh", "Riyadh", "12626"),
|
|
|
alternativePaymentMethods: [PaymentSdkAPms.TAMARA],
|
|
|
linkBillingNameWithCardHolderName: false,
|
|
|
simplifyApplePayValidation: true,
|
|
|
);
|
|
|
|
|
|
paymentConfiguration.iOSThemeConfigurations = IOSThemeConfigurations(
|
|
|
// logoImage: "assets/images/png/hmg_logo.png",
|
|
|
backgroundColor: "ffffff",
|
|
|
backgroundColorDark: "ffffff",
|
|
|
secondaryColor: "191919",
|
|
|
secondaryColorDark: "191919",
|
|
|
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",
|
|
|
inputsCornerRadius: 12
|
|
|
// buttonFont: "Poppins",
|
|
|
);
|
|
|
paymentConfiguration.tokeniseType = PaymentSdkTokeniseType.USER_OPTIONAL_DEFAULT_ON;
|
|
|
paymentConfiguration.tokenFormat = PaymentSdkTokenFormat.Hex32Format;
|
|
|
|
|
|
notifyListeners();
|
|
|
}
|
|
|
|
|
|
Future<void> 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<void> 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);
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
);
|
|
|
}
|
|
|
|
|
|
startApplePayPayment({Function(PaytabsTransactionResponseModel)? onSuccess, Function(String)? onError}) async {
|
|
|
bool _callbackFired = false; // prevent duplicate callback invocations
|
|
|
|
|
|
await FlutterPaytabsBridge.startApplePayPayment(paymentConfiguration, (event) {
|
|
|
if (_callbackFired) return; // ignore any subsequent callback calls
|
|
|
|
|
|
final transactionDetails = event["data"] as Map<Object?, Object?>?;
|
|
|
if (event["status"] == "success") {
|
|
|
_callbackFired = true;
|
|
|
// Cast Map<Object?, Object?> to Map<String, dynamic>
|
|
|
final data = Map<String, dynamic>.from(event["data"] as Map);
|
|
|
paytabsTransactionResponseModel = PaytabsTransactionResponseModel.fromJson(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.toString().isNotEmpty ? "Transaction failed (Code: $responseCode): $reason" : "Transaction failed: $reason";
|
|
|
onError!(errorMessage);
|
|
|
}
|
|
|
} else if (event["status"] == "error") {
|
|
|
_callbackFired = true;
|
|
|
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") {
|
|
|
// Intermediate SDK events – do NOT mark _callbackFired, just log
|
|
|
final eventMessage = event["message"] ?? "Event occurred";
|
|
|
debugPrint("Event occurred: $eventMessage");
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
startCardPayment({
|
|
|
required String paymentOption,
|
|
|
required String liveServiceID,
|
|
|
required String isScheduleLiveCare,
|
|
|
required String appointmentDate,
|
|
|
required String appointmentNo,
|
|
|
required String doctorID,
|
|
|
required String transactionID,
|
|
|
required String amount,
|
|
|
required String fileNumber,
|
|
|
required String orderDescription,
|
|
|
required String serviceID,
|
|
|
required String projectID,
|
|
|
Function(PaytabsTransactionResponseModel)? onSuccess,
|
|
|
Function(String)? onError,
|
|
|
}) async {
|
|
|
bool _callbackFired = false; // prevent duplicate callback invocations
|
|
|
|
|
|
try {
|
|
|
LoaderBottomSheet.showLoader();
|
|
|
|
|
|
// Create PayfortRequestInsertModel (same as Payfort implementation)
|
|
|
PayfortRequestInsertModel payfortRequestInsertModel = PayfortRequestInsertModel();
|
|
|
|
|
|
payfortRequestInsertModel.commandType = "SALE";
|
|
|
payfortRequestInsertModel.amount = num.parse(amount);
|
|
|
payfortRequestInsertModel.customerEmail = getIt.get<AppState>().getAuthenticatedUser()!.emailAddress;
|
|
|
payfortRequestInsertModel.orderDescription = orderDescription;
|
|
|
payfortRequestInsertModel.serviceID = serviceID;
|
|
|
payfortRequestInsertModel.paymentOption = paymentOption;
|
|
|
payfortRequestInsertModel.clientRequestID = transactionID;
|
|
|
payfortRequestInsertModel.projectID = projectID;
|
|
|
payfortRequestInsertModel.fileNumber = getIt.get<AppState>().getAuthenticatedUser()!.patientId.toString();
|
|
|
payfortRequestInsertModel.customerName = "${getIt.get<AppState>().getAuthenticatedUser()!.firstName} ${getIt.get<AppState>().getAuthenticatedUser()!.lastName}";
|
|
|
payfortRequestInsertModel.currency = getIt.get<AppState>().getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED";
|
|
|
payfortRequestInsertModel.liveServiceID = liveServiceID;
|
|
|
payfortRequestInsertModel.latitude = getIt.get<AppState>().userLat.toString();
|
|
|
payfortRequestInsertModel.longitude = getIt.get<AppState>().userLong.toString();
|
|
|
payfortRequestInsertModel.merchantReference = transactionID;
|
|
|
payfortRequestInsertModel.deviceToken = await Utils.getStringFromPrefs(CacheConst.pushToken);
|
|
|
payfortRequestInsertModel.language = getIt.get<AppState>().isArabic() ? "ar" : "en";
|
|
|
payfortRequestInsertModel.integrationId = "2"; // 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();
|
|
|
|
|
|
// Start PayTabs payment
|
|
|
FlutterPaytabsBridge.startCardPayment(paymentConfiguration, (event) async {
|
|
|
if (_callbackFired) return; // ignore any subsequent callback calls
|
|
|
|
|
|
final transactionDetails = event["data"] as Map<Object?, Object?>?;
|
|
|
if (event["status"] == "success") {
|
|
|
_callbackFired = true;
|
|
|
|
|
|
LoaderBottomSheet.showLoader();
|
|
|
|
|
|
// Cast Map<Object?, Object?> to Map<String, dynamic>
|
|
|
final data = Map<String, dynamic>.from(event["data"] as Map);
|
|
|
paytabsTransactionResponseModel = PaytabsTransactionResponseModel.fromJson(data);
|
|
|
|
|
|
// Create PayfortResponseInsertModel (same as Payfort implementation)
|
|
|
PayfortResponseInsertModel payfortResponseInsertModel = PayfortResponseInsertModel();
|
|
|
|
|
|
payfortResponseInsertModel.fortId = paytabsTransactionResponseModel.transactionReference ?? "";
|
|
|
payfortResponseInsertModel.commandType = paytabsTransactionResponseModel.transactionType ?? "SALE";
|
|
|
// payfortResponseInsertModel.amount = paytabsTransactionResponseModel.tranTotal ?? 0;
|
|
|
payfortResponseInsertModel.amount = num.parse(amount);
|
|
|
payfortResponseInsertModel.sadadOLP = "";
|
|
|
payfortResponseInsertModel.paymentOption = paytabsTransactionResponseModel.paymentInfo?.paymentMethod ?? "";
|
|
|
payfortResponseInsertModel.customerIP = "";
|
|
|
payfortResponseInsertModel.eCI = "";
|
|
|
payfortResponseInsertModel.responseMessage = paytabsTransactionResponseModel.payResponseReturn ?? "";
|
|
|
payfortResponseInsertModel.cardNumber = paytabsTransactionResponseModel.paymentInfo!.paymentDescription;
|
|
|
payfortResponseInsertModel.cardBin = "";
|
|
|
payfortResponseInsertModel.installmentsNumber = 0;
|
|
|
payfortResponseInsertModel.status = paytabsTransactionResponseModel.isSuccess! ? "success" : "failed";
|
|
|
payfortResponseInsertModel.merchantRef = transactionID;
|
|
|
payfortResponseInsertModel.isRefund = false;
|
|
|
payfortResponseInsertModel.remmeberMe = true;
|
|
|
payfortResponseInsertModel.reconciliationReference = "";
|
|
|
|
|
|
// Call response insert API after payment
|
|
|
await paytabsResponseInsert(payfortResponseInsertModel: payfortResponseInsertModel);
|
|
|
|
|
|
LoaderBottomSheet.hideLoader();
|
|
|
|
|
|
if (paytabsTransactionResponseModel.isSuccess!) {
|
|
|
if (onSuccess != null) {
|
|
|
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.toString().isNotEmpty ? "Transaction failed (Code: $responseCode): $reason" : "Transaction failed: $reason";
|
|
|
if (onError != null) {
|
|
|
onError(errorMessage);
|
|
|
}
|
|
|
}
|
|
|
} else if (event["status"] == "error") {
|
|
|
_callbackFired = true;
|
|
|
final errorMessage = event["message"] ?? "An error occurred";
|
|
|
debugPrint("Error occurred in transaction: $errorMessage");
|
|
|
debugPrint("Full error event: $event");
|
|
|
if (onError != null) {
|
|
|
onError(errorMessage);
|
|
|
}
|
|
|
} else if (event["status"] == "event") {
|
|
|
// Intermediate SDK events – do NOT mark _callbackFired, just log
|
|
|
final eventMessage = event["message"] ?? "Event occurred";
|
|
|
debugPrint("Event occurred: $eventMessage");
|
|
|
}
|
|
|
});
|
|
|
} catch (error) {
|
|
|
debugPrint("PayTabs Payment Error: $error");
|
|
|
LoaderBottomSheet.hideLoader();
|
|
|
if (onError != null) {
|
|
|
onError("Payment initialization failed: $error");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
startAlternatePayment({Function(PaytabsTransactionResponseModel)? onSuccess, Function(String)? onError}) {
|
|
|
bool _callbackFired = false; // prevent duplicate callback invocations
|
|
|
|
|
|
FlutterPaytabsBridge.startAlternativePaymentMethod(paymentConfiguration, (event) {
|
|
|
if (_callbackFired) return; // ignore any subsequent callback calls
|
|
|
|
|
|
final transactionDetails = event["data"] as Map<Object?, Object?>?;
|
|
|
if (event["status"] == "success") {
|
|
|
_callbackFired = true;
|
|
|
// Cast Map<Object?, Object?> to Map<String, dynamic>
|
|
|
final data = Map<String, dynamic>.from(event["data"] as Map);
|
|
|
paytabsTransactionResponseModel = PaytabsTransactionResponseModel.fromJson(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.toString().isNotEmpty ? "Transaction failed (Code: $responseCode): $reason" : "Transaction failed: $reason";
|
|
|
onError!(errorMessage);
|
|
|
}
|
|
|
} else if (event["status"] == "error") {
|
|
|
_callbackFired = true;
|
|
|
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") {
|
|
|
// Intermediate SDK events – do NOT mark _callbackFired, just log
|
|
|
final eventMessage = event["message"] ?? "Event occurred";
|
|
|
debugPrint("Event occurred: $eventMessage");
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|