import 'dart:convert'; import 'package:sefer_driver/constant/api_key.dart'; import 'package:sefer_driver/constant/style.dart'; import 'package:sefer_driver/controller/functions/tts.dart'; import 'package:sefer_driver/controller/payment/paymob/paymob_response.dart'; import 'package:sefer_driver/views/widgets/elevated_btn.dart'; import 'package:sefer_driver/views/widgets/error_snakbar.dart'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'package:flutter_paypal/flutter_paypal.dart'; import 'package:flutter_stripe/flutter_stripe.dart'; import 'package:get/get.dart'; import 'package:local_auth/local_auth.dart'; import '../../constant/box_name.dart'; import '../../constant/colors.dart'; import '../../constant/info.dart'; import '../../constant/links.dart'; import '../../main.dart'; import '../../print.dart'; import '../functions/crud.dart'; import '../functions/encrypt_decrypt.dart'; import '../functions/toast.dart'; import 'paymob/paymob_wallet.dart'; class PaymentController extends GetxController { bool isLoading = false; bool isWalletChecked = true; bool isCashChecked = false; bool isWalletFound = false; bool isPromoSheetDialogue = false; final formKey = GlobalKey(); final promo = TextEditingController(); // double totalPassenger = // double.parse(Get.find().totalPricePassenger); int? selectedAmount = 0; List totalPassengerWalletDetails = []; final walletphoneController = TextEditingController(); String passengerTotalWalletAmount = ''; String ip = '1'; DateTime now = DateTime.now(); late int timestamp; void updateSelectedAmount(int value) { selectedAmount = value; update(); } void changePromoSheetDialogue() { isPromoSheetDialogue = !isPromoSheetDialogue; update(); } getPassengerWallet() async { isLoading = true; update(); await CRUD().get( link: AppLink.getWalletByPassenger, payload: {'passenger_id': box.read(BoxName.passengerID)}).then((value) { box.write(BoxName.passengerWalletTotal, jsonDecode(value)['message'][0]['total'].toString()); }); isLoading = false; update(); } addPassengerWallet() async { isLoading = true; update(); // double sallaryAccountNowBeforeAdding = // double.parse(box.read(BoxName.passengerWalletTotal).toString()); await CRUD().post(link: AppLink.addPassengersWallet, payload: { 'passenger_id': box.read(BoxName.passengerID).toString(), 'balance': selectedAmount.toString() }).then((value) { getPassengerWallet(); // sallaryAccountNowBeforeAdding = sallaryAccountNowBeforeAdding + // double.parse(selectedAmount.toString()); // box.write(BoxName.passengerWalletTotal, sallaryAccountNowBeforeAdding); }); isLoading = false; update(); } // void onChangedPaymentMethodWallet(bool? value) { // if (box.read(BoxName.passengerWalletTotal) == null || // double.parse(box.read(BoxName.passengerWalletTotal).toString()) < // totalPassenger) { // isWalletChecked = false; // isWalletChecked ? isCashChecked = true : isCashChecked = true; // update(); // } else { // isWalletChecked = !isWalletChecked; // isWalletChecked ? isCashChecked = false : isCashChecked = true; // update(); // } // } // void onChangedPaymentMethodCash(bool? value) { // if (box.read(BoxName.passengerWalletTotal) == null || // double.parse(box.read(BoxName.passengerWalletTotal)) < totalPassenger) { // isWalletChecked = false; // isCashChecked = !isCashChecked; // isCashChecked ? isWalletChecked = false : isWalletChecked = false; // update(); // } else { // isCashChecked = !isCashChecked; // isCashChecked ? isWalletChecked = false : isWalletChecked = true; // update(); // } // } late String clientSecret; Future makePaymentStripe( double amount, String currency, Function method) async { var newAmount = (amount * 100).toInt(); try { // Check if local authentication is available bool isAvailable = await LocalAuthentication().isDeviceSupported(); if (isAvailable) { // Authenticate the user bool didAuthenticate = await LocalAuthentication().authenticate( localizedReason: 'Use Touch ID or Face ID to confirm payment', ); if (didAuthenticate) { // User authenticated successfully, proceed with payment clientSecret = await getClientSecret(newAmount.toString(), currency); await initializePaymentSheet(clientSecret); await Stripe.instance.presentPaymentSheet(); method(); } else { // Authentication failed, handle accordingly } } else { // Local authentication not available, proceed with payment without authentication clientSecret = await getClientSecret(newAmount.toString(), currency); await initializePaymentSheet(clientSecret); await Stripe.instance.presentPaymentSheet(); method(); } } catch (e) { rethrow; } } Future initializePaymentSheet(String clientSecret) async { await Stripe.instance.initPaymentSheet( paymentSheetParameters: SetupPaymentSheetParameters( // intentConfiguration: IntentConfiguration.fromJson({}), // applePay: const PaymentSheetApplePay(merchantCountryCode: 'US'), // googlePay: const PaymentSheetGooglePay(merchantCountryCode: 'US'), paymentIntentClientSecret: clientSecret, merchantDisplayName: AppInformation.appName, billingDetails: BillingDetails( name: EncryptionHelper.instance .decryptData(box.read(BoxName.nameDriver)), email: EncryptionHelper.instance .decryptData(box.read(BoxName.emailDriver)), phone: EncryptionHelper.instance .decryptData(box.read(BoxName.phoneDriver)), address: Address( city: 'city', country: box.read(BoxName.countryCode), //'United States' line1: '', line2: '', postalCode: '12345', state: box.read(BoxName.countryCode) // 'Boston' )), allowsDelayedPaymentMethods: true, customerEphemeralKeySecret: Stripe.merchantIdentifier, appearance: const PaymentSheetAppearance( shapes: PaymentSheetShape(borderRadius: 12), colors: PaymentSheetAppearanceColors( background: AppColor.secondaryColor, ), ), billingDetailsCollectionConfiguration: const BillingDetailsCollectionConfiguration( name: CollectionMode.automatic, phone: CollectionMode.automatic, email: CollectionMode.automatic, // address: CollectionMode.automatic, ), ), ); } Future getClientSecret(String amount, currency) async { var res = await CRUD().postStripe( link: 'https://api.stripe.com/v1/payment_intents', payload: { 'amount': amount, 'currency': currency, 'payment_method_types[0]': 'card' }, ); // Convert the res object to a JSON object final jsonResponse = jsonDecode(res); // Check if the client_secret property exists and is not null if (jsonResponse.containsKey('client_secret') && jsonResponse['client_secret'] != null) { // Return the client_secret property return jsonResponse['client_secret'] as String; } else { throw Exception('Failed to fetch client secret'); } } Future configure3dSecureFuture() async { await Stripe.instance.openApplePaySetup(); } Future makePaymentPayPal(BuildContext context) async { try { // Check if local authentication is available bool isAvailable = await LocalAuthentication().isDeviceSupported(); if (isAvailable) { // Authenticate the user bool didAuthenticate = await LocalAuthentication().authenticate( localizedReason: 'Use Touch ID or Face ID to confirm payment', ); if (didAuthenticate) { // User authenticated successfully, proceed with payment if (selectedAmount != 0) { changePromoSheetDialogue(); Navigator.of(context).push( MaterialPageRoute( builder: (BuildContext context) => UsePaypal( sandboxMode: true, clientId: AK.payPalClientId, secretKey: AK.payPalSecret, returnURL: AppInformation.website, cancelURL: "${AppInformation.website}/cancel", transactions: [ { "amount": { //sb-opsju26682403@personal.example.com "total": '$selectedAmount', "currency": box.read(BoxName.countryCode) == 'Egypt' ? 'EGP' : "JOD", "details": { "subtotal": '$selectedAmount', "shipping": '0', "shipping_discount": 0 } }, "description": "The payment transaction description.", "payment_options": const { "allowed_payment_method": "INSTANT_FUNDING_SOURCE" }, "item_list": { "items": [ { "name": "${AppInformation.appName} Wallet ", "quantity": 1, "price": '$selectedAmount', "currency": "USD" } ], // shipping address is not required though "shipping_address": const { "recipient_name": "${AppInformation.appName} Wallet", "line1": "Shafa Badran", "line2": "", "city": "Amman", "country_code": "JO", "postal_code": "13112", "phone": "+962798583052", "state": "Amman" }, } } ], note: "Contact us for any questions on your order.".tr, onSuccess: (Map params) async { addPassengerWallet(); changePromoSheetDialogue(); await getPassengerWallet(); }, onError: (error) { Toast.show(context, ' $error'.tr, AppColor.redColor); }, onCancel: (params) { Toast.show(context, 'Pyament Cancelled .'.tr, AppColor.yellowColor); }), ), ); } else { Toast.show(context, 'You will choose one of above !'.tr, AppColor.redColor); } } else { // Authentication failed, handle accordingly } } } catch (e) { rethrow; } } Map licenseDetailsMap = {}; Future getLicenseInfo() async { var res = await CRUD().get( link: AppLink.getLicense, payload: {'driverID': box.read(BoxName.driverID)}); licenseDetailsMap = jsonDecode(res); } Future createConnectAccount() async { String url = 'https://api.stripe.com/v1/accounts'; await getLicenseInfo(); DateTime dob = DateTime.parse(licenseDetailsMap['message'][0]['dateOfBirth']); int currentTimestamp = (DateTime.now().millisecondsSinceEpoch / 1000).round(); int day = dob.day; int month = dob.month; int year = dob.year; await getIpAddress(); final body = { "type": "custom", "business_profile[name]": box.read(BoxName.nameDriver), "business_profile[product_description]": "Captain", "business_profile[support_address][city]": "San Francisco", "business_profile[support_address][country]": 'US', "business_profile[support_address][line1]": licenseDetailsMap['message'][0]['address'].toString().trim()[0], "business_profile[support_address][postal_code]": licenseDetailsMap['message'][0]['postalCode'], "business_profile[support_address][state]": "MA", "business_profile[support_email]": "support@sefer.live", "business_profile[support_phone]": "555-123-4567", "business_profile[url]": "https://sefer.live", "business_type": "individual", "capabilities[card_payments][requested]": "true", "capabilities[transfers][requested]": "true", "company[address][city]": "ATTLEBORO", "company[address][country]": "US", "company[address][line1]": "1249 NEWPORT AVE", "company[address][postal_code]": "02703 ", "company[address][state]": "MA", "company[name]": AppInformation.companyName, "country": "us", "default_currency": "usd", "email": "support@sefer.live", // "individual[ssn]": "123-45-6789", // "individual[id_number]": licenseDetailsMap['message'][0]['documentNo'], // "individual[id_type]": "drivers_license", // "individual[address][city]": "ATTLEBORO", "individual[address][country]": "US", "individual[address][line1]": licenseDetailsMap['message'][0]['address'], // "individual[address][postal_code]": licenseDetailsMap['message'][0] // ['postalCode'], "individual[address][state]": "MA", // "individual[ssn_last_4]": '1111', //////// "individual[dob][day]": day.toString(), "individual[dob][month]": month.toString(), "individual[dob][year]": year.toString(), "individual[email]": box.read(BoxName.emailDriver), "individual[first_name]": licenseDetailsMap['message'][0]['name'].toString().split(' ')[0], "individual[gender]": licenseDetailsMap['message'][0]['sex'] == 'M' ? 'male' : 'female', "individual[last_name]": licenseDetailsMap['message'][0]['name'].toString().split(' ')[1], // "individual[phone]": box.read(BoxName.phoneDriver),//////////// "tos_acceptance[date]": currentTimestamp.toString(), "tos_acceptance[ip]": ip.toString() }; final response = await CRUD().postStripe( link: url, payload: body, ); final responseData = jsonDecode(response); final accountId = responseData['id']; box.write(BoxName.accountIdStripeConnect, accountId); await updateCaptainAccountBank(); return accountId; } Future updateCaptainAccountBank() async { var res = await CRUD().post(link: AppLink.updateAccountBank, payload: { 'id': box.read(BoxName.driverID), 'accountBank': box.read(BoxName.accountIdStripeConnect), }); if (jsonDecode(res)['status'] == 'success') { mySnackbarSuccess('Account Updated'.tr); // Get.snackbar('Account Updated', ''); } } Future createTransactionToCaptain( String amount, String account) async { String url = 'https://api.stripe.com/v1/transfers'; final body = { 'amount': amount, //amount 'currency': 'usd', 'destination': account //'acct_1OKIjQRgcWrsdyDT' //account id }; final response = await CRUD().postStripe( link: url, payload: body, ); final responseData = jsonDecode(response); final transactionId = responseData['id']; return transactionId; } Future getIpAddress() async { var url = Uri.parse('https://api.ipify.org?format=json'); var response = await http.get(url); if (response.statusCode == 200) { ip = jsonDecode(response.body)['ip']; } else {} } // 'https://accept.paymob.com/unifiedcheckout/?publicKey=egy_pk_live_mbjDC9Ni6FSHKmsz8sOHiVk2xd7oWRve&clientSecret=egy_sk_live_c0904e9cf04506ae64f818d4e075b4a957e3713fdf7a22cb7da30a29e72442b5' Future payWithPayMob( BuildContext context, String amount, currency, Function method) async { String newAmount = (double.parse(amount) * 100).toStringAsFixed(2); try { bool isAvailable = await LocalAuthentication().isDeviceSupported(); if (isAvailable) { // Authenticate the user bool didAuthenticate = await LocalAuthentication().authenticate( localizedReason: 'Use Touch ID or Face ID to confirm payment', ); if (didAuthenticate) { final PaymobResponse? response = await PaymobPayment.instance.pay( context: context, currency: currency, //"EGP", amountInCents: newAmount, // 19.00 EGP billingData: PaymobBillingData(), onPayment: (PaymobResponse response) {}, ); if (response!.responseCode == 'APPROVED') { Get.defaultDialog( barrierDismissible: false, title: 'Payment Successful'.tr, titleStyle: AppStyle.title, content: Text( 'The payment was approved.'.tr, style: AppStyle.title, ), confirm: MyElevatedButton( title: 'OK'.tr, kolor: AppColor.greenColor, onPressed: () async { Get.back(); method(); }, ), ); } else { Get.defaultDialog( barrierDismissible: false, // backgroundColor: AppColor.redColor, title: 'Payment Failed'.tr, content: Text( 'The payment was not approved. Please try again.'.tr, textAlign: TextAlign.center, style: AppStyle.title, ), confirm: MyElevatedButton( title: 'OK'.tr, kolor: AppColor.redColor, onPressed: () async { Get.back(); }, ), ); } } else { // Authentication failed, handle accordingly } } else { final PaymobResponse? response = await PaymobPayment.instance.pay( context: context, currency: currency, //"EGP", amountInCents: newAmount, // 19.00 EGP billingData: PaymobBillingData(), onPayment: (PaymobResponse response) {}, ); if (response!.responseCode == 'APPROVED') { Get.defaultDialog( barrierDismissible: false, title: 'Payment Successful'.tr, titleStyle: AppStyle.title, // backgroundColor: AppColor.greenColor, content: Text( 'The payment was approved.'.tr, style: AppStyle.title, ), confirm: MyElevatedButton( kolor: AppColor.greenColor, title: 'OK'.tr, onPressed: () async { Get.back(); method(); }, ), ); } else { Get.defaultDialog( barrierDismissible: false, // backgroundColor: AppColor.redColor, title: 'Payment Failed'.tr, content: Column( children: [ IconButton( onPressed: () { Get.find().speakText( 'The payment was not approved. Please try again.'.tr, ); }, icon: const Icon(Icons.headphones), ), Text( 'The payment was not approved. Please try again.'.tr, textAlign: TextAlign.center, style: AppStyle.title, ), Text( '${'The reason is'.tr} ${response.message!.tr}', textAlign: TextAlign.center, style: AppStyle.title.copyWith(color: AppColor.redColor), ), ], ), confirm: MyElevatedButton( title: 'OK'.tr, kolor: AppColor.redColor, onPressed: () async { Get.back(); }, ), ); } } } catch (e) { Get.defaultDialog( title: 'Error'.tr, content: Text( 'An error occurred during the payment process.'.tr, style: AppStyle.title, ), ); rethrow; } } Future payWithPayMobWallet( BuildContext context, String amount, currency, Function method) async { String newAmount = (double.parse(amount) * 100).toStringAsFixed(2); try { bool isAvailable = await LocalAuthentication().isDeviceSupported(); if (isAvailable) { // Authenticate the user bool didAuthenticate = await LocalAuthentication().authenticate( localizedReason: 'Use Touch ID or Face ID to confirm payment', ); if (didAuthenticate) { final PaymobResponseWallet? response = await PaymobPaymentWallet.instance.pay( context: context, currency: currency, //"EGP", amountInCents: newAmount, // 19.00 EGP billingData: PaymobBillingDataWallet(), onPayment: (PaymobResponseWallet response) {}, ); // Log.print('message: ${response!.message}'); // Log.print('responseCode: ${response.responseCode}'); // Log.print('success: ${response.success}'); // Log.print('transactionID: ${response.transactionID}'); if (response!.success == true && response.message.toString() == 'Approved') { // Log.print('transactionID wewer: ${response.transactionID}'); Toast.show(context, 'Payment Successful'.tr, AppColor.greenColor); method(); // Get.defaultDialog( // barrierDismissible: false, // title: 'Payment Successful'.tr, // titleStyle: AppStyle.title, // content: Text( // 'The payment was approved.'.tr, // style: AppStyle.title, // ), // confirm: MyElevatedButton( // title: 'OK'.tr, // kolor: AppColor.greenColor, // onPressed: () async { // Get.back(); // method(); // }, // ), // ); } else { Get.defaultDialog( barrierDismissible: false, // backgroundColor: AppColor.redColor, title: 'Payment Failed'.tr, content: Column( children: [ IconButton( onPressed: () { Get.find().speakText( 'The payment was not approved. Please try again.'.tr, ); }, icon: const Icon(Icons.headphones), ), Text( 'The payment was not approved. Please try again.'.tr, textAlign: TextAlign.center, style: AppStyle.title, ), Text( '${'The reason is'.tr} ${response.message!.tr}', textAlign: TextAlign.center, style: AppStyle.title.copyWith(color: AppColor.redColor), ), ], ), confirm: MyElevatedButton( title: 'OK'.tr, kolor: AppColor.redColor, onPressed: () async { Get.back(); }, ), ); } } else { // Authentication failed, handle accordingly } } else { final PaymobResponse? response = await PaymobPayment.instance.pay( context: context, currency: currency, //"EGP", amountInCents: newAmount, // 19.00 EGP billingData: PaymobBillingData(), onPayment: (PaymobResponse response) {}, ); // if (response!.responseCode == 'APPROVED') { if (response!.responseCode == '200' && response.success == true) { Toast.show(context, 'Payment Successful'.tr, AppColor.greenColor); method(); // Get.defaultDialog( // barrierDismissible: false, // title: 'Payment Successful'.tr, // titleStyle: AppStyle.title, // // backgroundColor: AppColor.greenColor, // content: Text( // 'The payment was approved.'.tr, // style: AppStyle.title, // ), // confirm: MyElevatedButton( // kolor: AppColor.greenColor, // title: 'OK'.tr, // onPressed: () async { // Get.back(); // method(); // }, // ), // ); } else { Get.defaultDialog( barrierDismissible: false, // backgroundColor: AppColor.redColor, title: 'Payment Failed'.tr, content: Text( 'The payment was not approved. Please try again.'.tr, textAlign: TextAlign.center, style: AppStyle.title, ), confirm: MyElevatedButton( title: 'OK'.tr, kolor: AppColor.redColor, onPressed: () async { Get.back(); }, ), ); } } } catch (e) { Get.defaultDialog( title: 'Error'.tr, content: Text( 'An error occurred during the payment process.'.tr, style: AppStyle.title, ), ); rethrow; } } @override void onInit() { timestamp = now.millisecondsSinceEpoch; if (box.read(BoxName.passengerWalletTotal) == null) { box.write(BoxName.passengerWalletTotal, '0'); } // getPassengerWallet(); final localAuth = LocalAuthentication(); super.onInit(); } }