diff --git a/android/app/build.gradle b/android/app/build.gradle
index 8562203..e7fc4f0 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -47,8 +47,8 @@ android {
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 29
targetSdk = 36
- versionCode = 22
- versionName = '1.0.22'
+ versionCode = 25
+ versionName = '1.0.25'
multiDexEnabled = true
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 189283c..300fb74 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -33,11 +33,11 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 10
+ 12
CFBundleSignature
????
CFBundleVersion
- 1.0.10
+ 1.0.12
FirebaseAppDelegateProxyEnabled
NO
GMSApiKey
diff --git a/lib/constant/notification.dart b/lib/constant/notification.dart
index 0a69066..5da2bf8 100644
--- a/lib/constant/notification.dart
+++ b/lib/constant/notification.dart
@@ -1,31 +1,31 @@
List passengerMessages = [
// --- رسائل العروض والتوفير ---
- "مشاويرك علينا بأحلى الأسعار! 🚗 فوت على تطبيق انطلق وشوف العروض الجديدة اللي ناطرتك. 🌟",
- "بدك توفّر بمشاويرك؟ 🤔 افتح تطبيق انطلق هلأ! أسعارنا ما بتلاقي متلها.",
- "خصم خاص الك اليوم! 🎁 افتح تطبيق انطلق واحجز مشوارك الجاي بسعر أقل.",
- "لا تحمل هم المصاريف! 💸 مع انطلق، كل مشاويرك اقتصادية ومريحة.",
+ "وفر على حالك: 🚗 أسعار انطلق نازلة كتير! شوف العروض الجديدة وفوت هلأ قبل ما تخلص. 🌟",
+ "خصم اليوم: 🤔 لا تفوّت الفرصة! افتح تطبيق انطلق وشوف الأسعار يلي ما بتنعاد.",
+ "عروض نارية: 🎁 اليوم خصم خاص إلك، احجز مشوارك الجاي بسعر ولا أروع!",
+ "مشاوير اقتصادية: 💸 مع انطلق بتتحرك براحتك وبتدفع أقل، جرب وشوف الفرق!",
// --- رسائل السهولة والراحة ---
- "كبسة زر ومشوارك صار عندك! 📲 افتح تطبيق انطلق واحجز بسهولة.",
- "ليش معجوق بالمواصلات؟ 🤔 انطلق بيوصلك وين ما بدك براحة وسرعة.",
- "سيارتك ناطرتك! 🚕 وين ما كنت، اطلب من انطلق وبنوصلك بأسرع وقت.",
- "مشوارك الجاي مع انطلق! 🛣️ استرخي واستمتع بالطريق، نحنا بنهتم بالتفاصيل.",
+ "مشوار بكبسة زر: 📲 افتح تطبيق انطلق، وخلِّي السيارة توصلك لعندك بثواني.",
+ "ارتاح من المواصلات: 🤔 خلّي انطلق يريحك من الانتظار والزحمة، وانطلق وين ما بدك.",
+ "سيارتك جاهزة: 🚕 الكابتن ناطر طلبك، حدد وجهتك وخلّي الطريق علينا.",
+ "رحلة مريحة: 🛣️ ارتاح بالكرسي، نحنا منهتم بكل التفاصيل من الباب للباب.",
// --- رسائل الأمان والثقة ---
- "مشوارك آمن ومريح مع انطلق. 🙏 كباتنّا محترفين و بيهمنا توصل بالسلامة.",
- "انطلق بقلب مطمن! 🔒 سلامتك أولويتنا بكل رحلة بتطلعها معنا.",
- "مع انطلق، فيك تشارك تفاصيل رحلتك مع اللي بتحبن ليضل بالك مرتاح. ❤️",
- "كل رحلاتنا مسجّلة لضمان أمانك. سافر بثقة مع انطلق. ✅",
+ "رحلتك بأمان: 🙏 كل كباتنّا مدرّبين وملتزمين، وسلامتك أولويتنا.",
+ "سافر وانت مطمّن: 🔒 مع انطلق كل شي موثوق ومسجّل لتكون مرتاح البال.",
+ "شارك رحلتك: ❤️ فيك تبعت تفاصيل المشوار لأهلك أو رفقاتك بخطوة وحدة.",
+ "انطلق بثقة: ✅ كل الرحلات مراقبة لتضمن تجربة آمنة ومريحة 100%.",
- // --- رسائل تفاعلية ومناسبات خاصة ---
- "الويكند بلّش! 🥳 مشاويرك مع الصحبة صارت أسهل وأوفر. اطلب انطلق.",
- "رايح عالشغل؟ 💼 خلي انطلق يوصلك بلا عجقة السير وخليك مرتاح.",
- "الدنيا شوب؟ ☀️ اطلب من انطلق والكابتن بيوصل لعندك.",
- "تأخرت؟ لا تاكل هم! 🏃♂️ تطبيق انطلق هو أسرع طريق لتوصل عبكير.",
+ // --- رسائل تفاعلية ومناسبات ---
+ "الويكند بلّش: 🥳 خلي مشاويرك مع الأصحاب علينا، وفر وقتك وفلوسك مع انطلق.",
+ "رايح عالشغل: 💼 لا تتأخر، افتح التطبيق وخلي الكابتن يوصلك بلا تعب.",
+ "الشمس مولّعة: ☀️ لا تمشي تحت الحر، خلي السيارة تجي لعندك.",
+ "مستعجل: 🏃♂️ لا تقلق، انطلق أسرع طريق لتوصل عموعدك.",
// --- رسائل تشجيعية عامة ---
- "وين وجهتك اليوم؟ 🗺️ مدينة كاملة بانتظارك، وخلي مشوارك على انطلق.",
- "جرّبت فئات سيارات انطلق الجديدة؟ 🚘 دلّل حالك بتجربة مميزة اليوم.",
- "شكراً لاختيارك انطلق! ⭐ منتمنى الك دايماً رحلات سعيدة ومريحة.",
- "عند انطلق كل شي جديد! ✨ فوت عالبرنامج وضلّك على اطلاع بآخر خدماتنا وعروضنا."
+ "وين رايح اليوم؟ 🗺️ وين ما كانت وجهتك، انطلق بيخدمك بكل مكان وبأي وقت.",
+ "جرب شي جديد: 🚘 شوف فئات السيارات الجديدة وخلي رحلتك أريح وأجمل.",
+ "شكراً لاختيارك: ⭐ وجودك معنا بيفرحنا، ونتمنى دايماً تكون رحلتك مريحة وسعيدة.",
+ "كل يوم جديد: ✨ فوت عالتطبيق وتابع آخر التحديثات والعروض يلي نازلة خصيصاً إلك."
];
diff --git a/lib/controller/auth/login_controller.dart b/lib/controller/auth/login_controller.dart
index 4068bed..c2847e6 100644
--- a/lib/controller/auth/login_controller.dart
+++ b/lib/controller/auth/login_controller.dart
@@ -48,7 +48,7 @@ class LoginController extends GetxController {
var dev = '';
@override
void onInit() async {
- // await getAppTester();
+ await getJWT();
// Log.print('box.read(BoxName.isTest): ${box.read(BoxName.isTest)}');
box.write(BoxName.countryCode, 'Syria');
FirebaseMessagesController().getToken();
diff --git a/lib/controller/auth/otp_controller.dart b/lib/controller/auth/otp_controller.dart
index cc0aa2c..185b2a5 100644
--- a/lib/controller/auth/otp_controller.dart
+++ b/lib/controller/auth/otp_controller.dart
@@ -22,26 +22,29 @@ class PhoneAuthHelper {
/// Sends an OTP to the provided phone number.
static Future sendOtp(String phoneNumber) async {
try {
+ // Log.print('_sendOtpUrl: ${_sendOtpUrl}');
+ // Log.print('phoneNumber: ${phoneNumber}');
+
final response = await CRUD().post(
link: _sendOtpUrl,
payload: {'receiver': phoneNumber},
);
- Log.print('response: ${response}');
+ // Log.print('response: ${response}');
if (response != 'failure') {
final data = (response);
- // if (data['status'] == 'success') {
- mySnackbarSuccess('An OTP has been sent to your WhatsApp number.'.tr);
- return true;
- // } else {
- // mySnackeBarError(data['message'] ?? 'Failed to send OTP.');
- // return false;
- // }
+ if (data['status'] == 'success') {
+ mySnackbarSuccess('An OTP has been sent to your WhatsApp number.'.tr);
+ return true;
+ } else {
+ mySnackeBarError(data['message'] ?? 'Failed to send OTP.');
+ return false;
+ }
} else {
mySnackeBarError('Server error. Please try again.'.tr);
return false;
}
} catch (e) {
- Log.print('e: ${e}');
+ // Log.print('e: ${e}');
// mySnackeBarError('An error occurred: $e');
return false;
}
diff --git a/lib/controller/payment/payment_controller.dart b/lib/controller/payment/payment_controller.dart
index fef6975..7cd292d 100644
--- a/lib/controller/payment/payment_controller.dart
+++ b/lib/controller/payment/payment_controller.dart
@@ -673,312 +673,305 @@ class PaymentController extends GetxController {
/// شاشة جديدة ومبسطة خاصة بدفع السائقين عبر ecash
- Future payWithMTNWallet(
- BuildContext context, String amount, String currency) async {
- // خزن سياق علوي آمن من البداية
- final BuildContext safeContext =
- Get.overlayContext ?? Get.context ?? context;
+ // Future payWithMTNWallet(
+ // BuildContext context, String amount, String currency) async {
+ // // خزن سياق علوي آمن من البداية
+ // final BuildContext safeContext =
+ // Get.overlayContext ?? Get.context ?? context;
- // سبينر تحميل
- if (!(Get.isDialogOpen ?? false)) {
- Get.dialog(const Center(child: CircularProgressIndicator()),
- barrierDismissible: false);
+ // // سبينر تحميل
+ // if (!(Get.isDialogOpen ?? false)) {
+ // Get.dialog(const Center(child: CircularProgressIndicator()),
+ // barrierDismissible: false);
+ // }
+
+ // try {
+ // final phone = box.read(BoxName.phoneWallet) as String;
+ // final passengerID = box.read(BoxName.passengerID).toString();
+ // final formattedAmount = double.parse(amount).toStringAsFixed(0);
+
+ // print("🚀 بدء عملية دفع MTN");
+ // print(
+ // "📦 Payload: passengerID: $passengerID, amount: $formattedAmount, phone: $phone");
+
+ // // التحقق بالبصمة (اختياري) + حماية من الـ await
+ // final localAuth = LocalAuthentication();
+ // final isAuthSupported = await localAuth.isDeviceSupported();
+ // if (isAuthSupported) {
+ // final didAuth = await localAuth.authenticate(
+ // localizedReason: 'استخدم بصمة الإصبع أو الوجه لتأكيد الدفع',
+ // );
+ // if (!didAuth) {
+ // if (Get.isDialogOpen == true) Get.back();
+ // print("❌ المستخدم لم يؤكد بالبصمة/الوجه");
+ // return;
+ // }
+ // }
+
+ // // 1) بدء الدفع
+ // final responseData = await CRUD().postWalletMtn(
+ // link: AppLink.payWithMTNStart,
+ // payload: {
+ // "amount": formattedAmount,
+ // "passengerId": passengerID,
+ // "phone": phone,
+ // "lang": box.read(BoxName.lang) ?? 'ar',
+ // },
+ // );
+
+ // // print("✅ استجابة الخادم (mtn_start_payment.php):");
+ // // print(responseData);
+ // Log.print('responseData: ${responseData}');
+
+ // // فحص الاستجابة بقوة
+ // late final Map startRes;
+ // if (responseData is Map) {
+ // startRes = responseData;
+ // } else if (responseData is String) {
+ // startRes = json.decode(responseData) as Map;
+ // } else {
+ // throw Exception("تم استلام نوع بيانات غير متوقع من الخادم.");
+ // }
+
+ // if (startRes['status'] != 'success') {
+ // final errorMsg = startRes['message']['Error']?.toString().tr ??
+ // "فشل بدء عملية الدفع. حاول مرة أخرى.";
+ // throw Exception(errorMsg);
+ // }
+
+ // final messageData = startRes["message"] as Map;
+ // final invoiceNumber = messageData["invoiceNumber"].toString();
+ // final operationNumber = messageData["operationNumber"].toString();
+ // final guid = messageData["guid"].toString();
+
+ // // print(
+ // // "📄 invoiceNumber: $invoiceNumber, 🔢 operationNumber: $operationNumber, 🧭 guid: $guid");
+
+ // // أغلق السبينر قبل إظهار حوار OTP
+ // if (Get.isDialogOpen == true) Get.back();
+
+ // // 2) إدخال OTP بـ Get.defaultDialog (لا يستخدم context قابل للتلف)
+ // String otpInput = "";
+ // await Get.defaultDialog(
+ // title: "أدخل كود التحقق",
+ // barrierDismissible: false,
+ // content: TextField(
+ // keyboardType: TextInputType.number,
+ // decoration: const InputDecoration(hintText: "كود OTP"),
+ // onChanged: (v) => otpInput = v,
+ // ),
+ // confirm: TextButton(
+ // onPressed: () {
+ // if (otpInput.isEmpty ||
+ // otpInput.length < 4 ||
+ // otpInput.length > 8) {
+ // Get.snackbar("تنبيه", "أدخل كود OTP صحيح (4–8 أرقام)");
+ // return;
+ // }
+ // Get.back(result: otpInput);
+ // },
+ // child: const Text("تأكيد"),
+ // ),
+ // cancel: TextButton(
+ // onPressed: () => Get.back(result: null),
+ // child: const Text("إلغاء"),
+ // ),
+ // ).then((res) => otpInput = (res ?? "") as String);
+
+ // if (otpInput.isEmpty) {
+ // print("❌ لم يتم إدخال OTP");
+ // return;
+ // }
+ // print("🔐 تم إدخال OTP: $otpInput");
+
+ // // سبينر أثناء التأكيد
+ // Get.dialog(const Center(child: CircularProgressIndicator()),
+ // barrierDismissible: false);
+
+ // // 3) تأكيد الدفع
+ // final confirmRes = await CRUD().postWalletMtn(
+ // link: AppLink.payWithMTNConfirm,
+ // payload: {
+ // "invoiceNumber": invoiceNumber,
+ // "operationNumber": operationNumber,
+ // "guid": guid,
+ // "otp": otpInput,
+ // "phone": phone,
+ // "lang": box.read(BoxName.lang) ?? 'ar',
+ // },
+ // );
+
+ // if (Get.isDialogOpen == true) Get.back();
+
+ // // print("✅ استجابة mtn_confirm.php:");
+ // // Log.print('confirmRes: ${confirmRes}');
+
+ // final ok = (confirmRes is Map && confirmRes['status'] == 'success');
+ // if (ok) {
+ // Get.defaultDialog(
+ // title: "✅ نجاح",
+ // content: const Text("تمت عملية الدفع وإضافة الرصيد إلى محفظتك."),
+ // );
+ // await getPassengerWallet();
+ // } else {
+ // final errorMsg = (confirmRes['message']['message']?.toString()) ??
+ // "فشل في تأكيد الدفع";
+ // Get.defaultDialog(title: "❌ فشل", content: Text(errorMsg.tr));
+ // }
+ // } catch (e, s) {
+ // print("🔥 خطأ أثناء الدفع عبر MTN:");
+ // print(e);
+ // print(s);
+ // if (Get.isDialogOpen == true) Get.back();
+ // Get.defaultDialog(
+ // title: 'حدث خطأ',
+ // content: Text(e.toString().replaceFirst("Exception: ", "")),
+ // );
+ // }
+ // }
+
+ Future payWithSyriaTelWallet(String amount, String currency) async {
+ // helper لفتح لودينغ بأمان
+ Future _showLoading() async {
+ if (!(Get.isDialogOpen ?? false)) {
+ Get.dialog(const Center(child: CircularProgressIndicator()),
+ barrierDismissible: false);
+ }
}
+ // helper لإغلاق أي حوار مفتوح
+ void _closeAnyDialog() {
+ if (Get.isDialogOpen ?? false) {
+ Get.back();
+ }
+ }
+
+ await _showLoading();
try {
final phone = box.read(BoxName.phoneWallet) as String;
- final passengerID = box.read(BoxName.passengerID).toString();
+ final passengerId = box.read(BoxName.passengerID).toString();
final formattedAmount = double.parse(amount).toStringAsFixed(0);
- print("🚀 بدء عملية دفع MTN");
+ print("🚀 Syriatel payment start");
print(
- "📦 Payload: passengerID: $passengerID, amount: $formattedAmount, phone: $phone");
+ "📦 Payload => passengerId:$passengerId amount:$formattedAmount phone:$phone");
- // التحقق بالبصمة (اختياري) + حماية من الـ await
- final localAuth = LocalAuthentication();
- final isAuthSupported = await localAuth.isDeviceSupported();
- if (isAuthSupported) {
- final didAuth = await localAuth.authenticate(
+ // مصادقة حيوية (اختياري)
+ final auth = LocalAuthentication();
+ if (await auth.isDeviceSupported()) {
+ final ok = await auth.authenticate(
localizedReason: 'استخدم بصمة الإصبع أو الوجه لتأكيد الدفع',
);
- if (!didAuth) {
- if (Get.isDialogOpen == true) Get.back();
- print("❌ المستخدم لم يؤكد بالبصمة/الوجه");
+ if (!ok) {
+ _closeAnyDialog();
+ print("❌ User did not authenticate");
return;
}
}
- // 1) بدء الدفع
- final responseData = await CRUD().postWalletMtn(
- link: AppLink.payWithMTNStart,
+ // 1) بدء عملية الدفع
+ final startRaw = await CRUD().postWalletMtn(
+ link: AppLink.payWithSyriatelStart,
payload: {
"amount": formattedAmount,
- "passengerId": passengerID,
+ "passengerId": passengerId,
"phone": phone,
"lang": box.read(BoxName.lang) ?? 'ar',
},
);
- // print("✅ استجابة الخادم (mtn_start_payment.php):");
- // print(responseData);
- Log.print('responseData: ${responseData}');
+ print("✅ Server response (start): $startRaw");
- // فحص الاستجابة بقوة
+ // تحويل الاستجابة إلى Map
late final Map startRes;
- if (responseData is Map) {
- startRes = responseData;
- } else if (responseData is String) {
- startRes = json.decode(responseData) as Map;
+ if (startRaw is Map) {
+ startRes = startRaw;
+ } else if (startRaw is String) {
+ startRes = json.decode(startRaw) as Map;
} else {
- throw Exception("تم استلام نوع بيانات غير متوقع من الخادم.");
+ throw Exception("Unexpected start response type");
}
if (startRes['status'] != 'success') {
- final errorMsg = startRes['message']['Error']?.toString().tr ??
- "فشل بدء عملية الدفع. حاول مرة أخرى.";
- throw Exception(errorMsg);
+ final msg =
+ (startRes['message'] ?? 'Failed to start payment').toString();
+ throw Exception(msg);
}
- final messageData = startRes["message"] as Map;
- final invoiceNumber = messageData["invoiceNumber"].toString();
- final operationNumber = messageData["operationNumber"].toString();
- final guid = messageData["guid"].toString();
+ final messageData = startRes['message'] as Map;
+ final transactionID = messageData['transactionID'].toString();
+ print("📄 transactionID: $transactionID");
- // print(
- // "📄 invoiceNumber: $invoiceNumber, 🔢 operationNumber: $operationNumber, 🧭 guid: $guid");
-
- // أغلق السبينر قبل إظهار حوار OTP
- if (Get.isDialogOpen == true) Get.back();
-
- // 2) إدخال OTP بـ Get.defaultDialog (لا يستخدم context قابل للتلف)
- String otpInput = "";
- await Get.defaultDialog(
- title: "أدخل كود التحقق",
- barrierDismissible: false,
- content: TextField(
- keyboardType: TextInputType.number,
- decoration: const InputDecoration(hintText: "كود OTP"),
- onChanged: (v) => otpInput = v,
- ),
- confirm: TextButton(
- onPressed: () {
- if (otpInput.isEmpty ||
- otpInput.length < 4 ||
- otpInput.length > 8) {
- Get.snackbar("تنبيه", "أدخل كود OTP صحيح (4–8 أرقام)");
- return;
- }
- Get.back(result: otpInput);
- },
- child: const Text("تأكيد"),
- ),
- cancel: TextButton(
- onPressed: () => Get.back(result: null),
- child: const Text("إلغاء"),
- ),
- ).then((res) => otpInput = (res ?? "") as String);
-
- if (otpInput.isEmpty) {
- print("❌ لم يتم إدخال OTP");
- return;
- }
- print("🔐 تم إدخال OTP: $otpInput");
-
- // سبينر أثناء التأكيد
- Get.dialog(const Center(child: CircularProgressIndicator()),
- barrierDismissible: false);
-
- // 3) تأكيد الدفع
- final confirmRes = await CRUD().postWalletMtn(
- link: AppLink.payWithMTNConfirm,
- payload: {
- "invoiceNumber": invoiceNumber,
- "operationNumber": operationNumber,
- "guid": guid,
- "otp": otpInput,
- "phone": phone,
- "lang": box.read(BoxName.lang) ?? 'ar',
- },
- );
-
- if (Get.isDialogOpen == true) Get.back();
-
- // print("✅ استجابة mtn_confirm.php:");
- // Log.print('confirmRes: ${confirmRes}');
-
- final ok = (confirmRes is Map && confirmRes['status'] == 'success');
- if (ok) {
- Get.defaultDialog(
- title: "✅ نجاح",
- content: const Text("تمت عملية الدفع وإضافة الرصيد إلى محفظتك."),
- );
- await getPassengerWallet();
- } else {
- final errorMsg = (confirmRes['message']['message']?.toString()) ??
- "فشل في تأكيد الدفع";
- Get.defaultDialog(title: "❌ فشل", content: Text(errorMsg.tr));
- }
- } catch (e, s) {
- print("🔥 خطأ أثناء الدفع عبر MTN:");
- print(e);
- print(s);
- if (Get.isDialogOpen == true) Get.back();
- Get.defaultDialog(
- title: 'حدث خطأ',
- content: Text(e.toString().replaceFirst("Exception: ", "")),
- );
- }
- }
-
- Future payWithSyriaTelWallet(
- BuildContext context, String amount, String currency) async {
- // Show a loading indicator for better user experience
- Get.dialog(const Center(child: CircularProgressIndicator()),
- barrierDismissible: false);
-
- try {
- String phone = box.read(BoxName.phoneWallet);
- String driverID = box.read(BoxName.driverID).toString();
- String formattedAmount = double.parse(amount).toStringAsFixed(0);
-
- // --- CHANGE 1: Updated log messages for clarity ---
- print("🚀 Starting Syriatel payment process");
- print(
- "📦 Payload: driverID: $driverID, amount: $formattedAmount, phone: $phone");
-
- // Optional: Biometric authentication
- bool isAuthSupported = await LocalAuthentication().isDeviceSupported();
- if (isAuthSupported) {
- bool didAuthenticate = await LocalAuthentication().authenticate(
- localizedReason: 'استخدم بصمة الإصبع أو الوجه لتأكيد الدفع',
- );
- if (!didAuthenticate) {
- if (Get.isDialogOpen ?? false) Get.back();
- print("❌ User did not authenticate with biometrics");
- return;
- }
- }
-
- // --- CHANGE 2: Updated API link and payload for starting payment ---
- // Make sure you have defined `payWithSyriatelStart` in your AppLink class
- var responseData = await CRUD().postWalletMtn(
- link: AppLink.payWithSyriatelStart, // Use the new Syriatel start link
- payload: {
- "amount": formattedAmount,
- "driverId": driverID, // Key changed from 'passengerId' to 'driverId'
- "phone": phone,
- "lang": box.read(BoxName.lang) ?? 'ar',
- },
- );
-
- print("✅ Server response (start_payment.php):");
- print(responseData);
-
- // Robustly parse the server's JSON response
- Map startRes;
- if (responseData is Map) {
- startRes = responseData;
- } else if (responseData is String) {
- try {
- startRes = json.decode(responseData);
- } catch (e) {
- throw Exception(
- "Failed to parse server response. Response: $responseData");
- }
- } else {
- throw Exception("Received an unexpected data type from the server.");
- }
-
- if (startRes['status'] != 'success') {
- String errorMsg = startRes['message']?.toString() ??
- "Failed to start the payment process. Please try again.";
- throw Exception(errorMsg);
- }
-
- // --- CHANGE 3: Extract `transactionID` from the response ---
- // The response structure is now simpler. We only need the transaction ID.
- final messageData = startRes["message"];
- final transactionID = messageData["transactionID"].toString();
-
- print("📄 TransactionID: $transactionID");
-
- if (Get.isDialogOpen == true) Get.back(); // Close loading indicator
-
- // Show the OTP input dialog
- String? otp = await showDialog(
- context: context,
- barrierDismissible: false,
- builder: (context) {
- String input = "";
- return AlertDialog(
- title: const Text("أدخل كود التحقق"),
- content: TextField(
- keyboardType: TextInputType.number,
- decoration: const InputDecoration(hintText: "كود OTP"),
- onChanged: (val) => input = val,
+ // 2) اطلب من المستخدم إدخال OTP عبر Get.dialog (بدون context)
+ _closeAnyDialog(); // أغلق اللودينغ أولاً
+ final otpController = TextEditingController();
+ final otp = await Get.dialog(
+ AlertDialog(
+ title: const Text("أدخل كود التحقق"),
+ content: TextField(
+ controller: otpController,
+ keyboardType: TextInputType.number,
+ decoration: const InputDecoration(hintText: "كود OTP"),
+ ),
+ actions: [
+ TextButton(
+ child: const Text("تأكيد"),
+ onPressed: () => Get.back(result: otpController.text.trim()),
),
- actions: [
- TextButton(
- child: const Text("تأكيد"),
- onPressed: () => Navigator.of(context).pop(input),
- ),
- TextButton(
- child: const Text("إلغاء"),
- onPressed: () => Navigator.of(context).pop(),
- ),
- ],
- );
- },
+ TextButton(
+ child: const Text("إلغاء"),
+ onPressed: () => Get.back(result: null),
+ ),
+ ],
+ ),
+ barrierDismissible: false,
);
if (otp == null || otp.isEmpty) {
- print("❌ OTP was not entered.");
+ print("❌ OTP not provided");
return;
}
- print("🔐 OTP entered: $otp");
+ print("🔐 OTP: $otp");
- Get.dialog(const Center(child: CircularProgressIndicator()),
- barrierDismissible: false);
+ await _showLoading();
- // --- CHANGE 4: Updated API link and payload for confirming payment ---
- // Make sure you have defined `payWithSyriatelConfirm` in your AppLink class
- var confirmRes = await CRUD().postWallet(
- // Changed from postWalletMtn if they are different
- link:
- AppLink.payWithSyriatelConfirm, // Use the new Syriatel confirm link
+ // 3) تأكيد الدفع
+ final confirmRaw = await CRUD().postWallet(
+ link: AppLink.payWithSyriatelConfirm,
payload: {
- "transactionID": transactionID, // Use the transaction ID
+ "transactionID": transactionID,
"otp": otp,
- // The other parameters (phone, guid, etc.) are no longer needed
},
);
- if (Get.isDialogOpen ?? false) Get.back();
+ _closeAnyDialog(); // أغلق اللودينغ
- print("✅ Response from confirm_payment.php:");
- Log.print('confirmRes: ${confirmRes}');
+ print("✅ Response (confirm): $confirmRaw");
- if (confirmRes != null && confirmRes['status'] == 'success') {
+ late final Map confirmRes;
+ if (confirmRaw is Map) {
+ confirmRes = confirmRaw;
+ } else if (confirmRaw is String) {
+ confirmRes = json.decode(confirmRaw) as Map;
+ } else {
+ throw Exception("Unexpected confirm response type");
+ }
+
+ if (confirmRes['status'] == 'success') {
Get.defaultDialog(
title: "✅ نجاح",
content: const Text("تمت عملية الدفع وإضافة الرصيد إلى محفظتك."),
);
} else {
- // --- CHANGE 5: Simplified error message extraction ---
- // The new PHP script sends the error directly in the 'message' field.
- String errorMsg =
- confirmRes?['message']?.toString() ?? "فشل في تأكيد الدفع";
+ final msg = (confirmRes['message'] ?? 'فشل في تأكيد الدفع').toString();
Get.defaultDialog(
title: "❌ فشل",
- content: Text(errorMsg.tr),
+ content: Text(msg),
);
}
} catch (e, s) {
- // --- CHANGE 6: Updated general error log message ---
- print("🔥 Error during Syriatel Wallet payment:");
- print(e);
- print(s);
- if (Get.isDialogOpen ?? false) Get.back();
+ print("🔥 Error during Syriatel Wallet payment:\n$e\n$s");
+ _closeAnyDialog();
Get.defaultDialog(
title: 'حدث خطأ',
content: Text(e.toString().replaceFirst("Exception: ", "")),
diff --git a/lib/views/home/my_wallet/passenger_wallet_dialoge.dart b/lib/views/home/my_wallet/passenger_wallet_dialoge.dart
index d71d6e9..01a67f8 100644
--- a/lib/views/home/my_wallet/passenger_wallet_dialoge.dart
+++ b/lib/views/home/my_wallet/passenger_wallet_dialoge.dart
@@ -338,68 +338,69 @@ void showPaymentOptions(BuildContext context, PaymentController controller) {
// );
// },
// ),
- GestureDetector(
- onTap: () async {
- Get.back();
- Get.defaultDialog(
- barrierDismissible: false,
- title: 'Insert Wallet phone number'.tr,
- content: Form(
- key: controller.formKey,
- child: MyTextForm(
- controller: controller.walletphoneController,
- label: 'Insert Wallet phone number'.tr,
- hint: '963941234567',
- type: TextInputType.phone)),
- confirm: MyElevatedButton(
- title: 'OK'.tr,
- onPressed: () async {
- Get.back();
- if (controller.formKey.currentState!.validate()) {
- if (controller.selectedAmount != 0) {
- controller.isLoading = true;
- controller.update();
- box.write(BoxName.phoneWallet,
- (controller.walletphoneController.text));
- Get.back();
- await controller.payWithMTNWallet(
- context,
- controller.selectedAmount.toString(),
- 'SYP',
- );
- await controller.getPassengerWallet();
+ // GestureDetector(
+ // onTap: () async {
+ // Get.back();
+ // Get.defaultDialog(
+ // barrierDismissible: false,
+ // title: 'Insert Wallet phone number'.tr,
+ // content: Form(
+ // key: controller.formKey,
+ // child: MyTextForm(
+ // controller: controller.walletphoneController,
+ // label: 'Insert Wallet phone number'.tr,
+ // hint: '963941234567',
+ // type: TextInputType.phone)),
+ // confirm: MyElevatedButton(
+ // title: 'OK'.tr,
+ // onPressed: () async {
+ // Get.back();
+ // if (controller.formKey.currentState!.validate()) {
+ // if (controller.selectedAmount != 0) {
+ // controller.isLoading = true;
+ // controller.update();
+ // box.write(BoxName.phoneWallet,
+ // (controller.walletphoneController.text));
+ // Get.back();
+ // await controller.payWithMTNWallet(
+ // context,
+ // controller.selectedAmount.toString(),
+ // 'SYP',
+ // );
+ // await controller.getPassengerWallet();
+
+ // controller.isLoading = false;
+ // controller.update();
+ // } else {
+ // Toast.show(
+ // context,
+ // '⚠️ You need to choose an amount!'.tr,
+ // AppColor.redColor,
+ // );
+ // }
+ // }
+ // }));
+ // },
+ // child: Padding(
+ // padding: const EdgeInsets.all(8.0),
+ // child: Row(
+ // mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ // children: [
+ // Text(
+ // 'Pay by MTN Wallet'.tr,
+ // style: AppStyle.title,
+ // ),
+ // const SizedBox(width: 10),
+ // Image.asset(
+ // 'assets/images/cashMTN.png',
+ // width: 70,
+ // height: 70,
+ // fit: BoxFit.contain,
+ // ),
+ // ],
+ // ),
+ // )),
- controller.isLoading = false;
- controller.update();
- } else {
- Toast.show(
- context,
- '⚠️ You need to choose an amount!'.tr,
- AppColor.redColor,
- );
- }
- }
- }));
- },
- child: Padding(
- padding: const EdgeInsets.all(8.0),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- 'Pay by MTN Wallet'.tr,
- style: AppStyle.title,
- ),
- const SizedBox(width: 10),
- Image.asset(
- 'assets/images/cashMTN.png',
- width: 70,
- height: 70,
- fit: BoxFit.contain,
- ),
- ],
- ),
- )),
GestureDetector(
onTap: () async {
Get.back();
@@ -420,7 +421,7 @@ void showPaymentOptions(BuildContext context, PaymentController controller) {
if (controller.formKey.currentState!.validate()) {
box.write(BoxName.phoneWallet,
controller.walletphoneController.text);
- await controller.payWithSyriaTelWallet(context,
+ await controller.payWithSyriaTelWallet(
controller.selectedAmount.toString(), 'SYP');
}
}));