Files
intaleq_driver/lib/views/home/my_wallet/points_captain.dart
Hamza-Ayed ea55a25af2 25-10-9/1
2025-10-09 23:30:59 +03:00

948 lines
34 KiB
Dart
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:local_auth/local_auth.dart';
import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/controller/home/payment/captain_wallet_controller.dart';
import 'package:sefer_driver/controller/payment/payment_controller.dart';
import 'package:sefer_driver/controller/payment/smsPaymnet/payment_services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import '../../../constant/box_name.dart';
import '../../../constant/links.dart';
import '../../../controller/functions/crud.dart';
import '../../../controller/payment/mtn_new/mtn_payment_new_screen.dart';
import '../../../main.dart';
import '../../../print.dart';
import '../../widgets/elevated_btn.dart';
import '../../widgets/my_textField.dart';
import 'ecash.dart';
class PointsCaptain extends StatelessWidget {
PaymentController paymentController = Get.put(PaymentController());
CaptainWalletController captainWalletController =
Get.put(CaptainWalletController());
PointsCaptain({
super.key,
required this.kolor,
required this.countPoint,
required this.pricePoint,
});
final Color kolor;
final String countPoint;
double pricePoint;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () async {
Get.defaultDialog(
title: 'Which method you will pay'.tr,
titleStyle: AppStyle.title,
content: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${'you can buy '.tr}$countPoint ${'L.S'.tr}${'by '.tr}${'$pricePoint'.tr}',
style: AppStyle.title,
),
// Add some spacing between buttons
GestureDetector(
onTap: () async {
Get.back();
payWithEcashDriver(context, pricePoint.toString());
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Pay with Debit Card'.tr),
const SizedBox(width: 10),
Icon(Icons.credit_card_sharp,
color: AppColor.blueColor, size: 70),
],
)),
// GestureDetector(
// onTap: () async {
// Get.back();
// Get.defaultDialog(
// barrierDismissible: false,
// title: 'Insert Wallet phone number'.tr,
// content: Form(
// key: paymentController.formKey,
// child: MyTextForm(
// controller:
// paymentController.walletphoneController,
// label: 'Insert Wallet phone number'.tr,
// hint: '963941234567',
// type: TextInputType.phone)),
// confirm: MyElevatedButton(
// title: 'OK'.tr,
// onPressed: () async {
// Get.back();
// if (paymentController.formKey.currentState!
// .validate()) {
// box.write(
// BoxName.phoneWallet,
// paymentController
// .walletphoneController.text);
// await payWithMTNWallet(
// context, pricePoint.toString(), 'SYP');
// }
// }));
// },
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text('Pay by MTN Wallet'.tr),
// const SizedBox(width: 10),
// Image.asset(
// 'assets/images/cashMTN.png',
// width: 70,
// height: 70,
// fit: BoxFit.fill,
// ),
// ],
// )),
GestureDetector(
onTap: () async {
Get.back();
Get.defaultDialog(
barrierDismissible: false,
title: 'Insert Wallet phone number'.tr,
content: Form(
key: paymentController.formKey,
child: MyTextForm(
controller:
paymentController.walletphoneController,
label: 'Insert Wallet phone number'.tr,
hint: '963991234567',
type: TextInputType.phone)),
confirm: MyElevatedButton(
title: 'OK'.tr,
onPressed: () async {
Get.back();
if (paymentController.formKey.currentState!
.validate()) {
box.write(
BoxName.phoneWallet,
paymentController
.walletphoneController.text);
await payWithSyriaTelWallet(
context, pricePoint.toString(), 'SYP');
}
}));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Pay by Syriatel Wallet'.tr),
const SizedBox(width: 10),
Image.asset(
'assets/images/syriatel.jpeg',
width: 70,
height: 70,
fit: BoxFit.fill,
),
],
)),
GestureDetector(
onTap: () async {
Get.back();
Get.defaultDialog(
barrierDismissible: false,
title: 'Insert Wallet phone number'.tr,
content: Form(
key: paymentController.formKey,
child: MyTextForm(
controller:
paymentController.walletphoneController,
label: 'Insert Wallet phone number'.tr,
hint: '963941234567',
type: TextInputType.phone)),
confirm: MyElevatedButton(
title: 'OK'.tr,
onPressed: () async {
Get.back();
if (paymentController.formKey.currentState!
.validate()) {
box.write(
BoxName.phoneWallet,
paymentController
.walletphoneController.text);
// await payWithSyriaTelWallet(
// context, pricePoint.toString(), 'SYP');
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;
}
}
Get.to(() => PaymentScreenSmsProvider(
amount: pricePoint));
}
}));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Pay by Sham Cash'.tr),
const SizedBox(width: 10),
Image.asset(
'assets/images/shamCash.png',
width: 70,
height: 70,
fit: BoxFit.fill,
),
],
)),
// GestureDetector(
// onTap: () async {
// Get.back();
// Get.defaultDialog(
// barrierDismissible: false,
// title: 'Insert Wallet phone number'.tr,
// content: Form(
// key: paymentController.formKey,
// child: MyTextForm(
// controller:
// paymentController.walletphoneController,
// label: 'Insert Wallet phone number'.tr,
// hint: '963941234567',
// type: TextInputType.phone)),
// confirm: MyElevatedButton(
// title: 'OK'.tr,
// onPressed: () async {
// Get.back();
// if (paymentController.formKey.currentState!
// .validate()) {
// box.write(
// BoxName.phoneWallet,
// paymentController
// .walletphoneController.text);
// // await payWithSyriaTelWallet(
// // context, pricePoint.toString(), 'SYP');
// 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;
// }
// }
// Get.to(() => PaymentScreenMtn(
// amount: pricePoint,
// userType: 'Driver',
// ));
// }
// }));
// },
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text('Pay by MTN Wallet'.tr),
// const SizedBox(width: 10),
// Image.asset(
// 'assets/images/cashMTN.png',
// width: 70,
// height: 70,
// fit: BoxFit.fill,
// ),
// ],
// )),
],
));
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 3, vertical: 8),
child: Container(
width: Get.width * .22,
height: Get.width * .22,
margin: const EdgeInsets.all(4),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
kolor.withOpacity(0.3),
kolor,
kolor.withOpacity(0.7),
kolor,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
border: Border.all(color: AppColor.accentColor),
borderRadius: BorderRadius.circular(12),
shape: BoxShape.rectangle,
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
'$countPoint ${'L.S'.tr}',
style: AppStyle.subtitle
.copyWith(color: AppColor.secondaryColor),
),
Text(
'$pricePoint ${'L.S'.tr}',
style:
AppStyle.title.copyWith(color: AppColor.secondaryColor),
textAlign: TextAlign.center,
),
],
),
),
),
),
);
}
}
class PaymentScreen extends StatefulWidget {
final String iframeUrl;
final String countPrice;
const PaymentScreen(
{required this.iframeUrl, Key? key, required this.countPrice})
: super(key: key);
@override
State<PaymentScreen> createState() => _PaymentScreenState();
}
class _PaymentScreenState extends State<PaymentScreen> {
late final WebViewController _controller;
final controller = Get.find<CaptainWalletController>();
@override
void initState() {
super.initState();
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onPageFinished: (url) {
if (url.contains("success")) {
_fetchPaymentStatus(); // ✅ استدعاء الويب هوك بعد نجاح الدفع
} else if (url.contains("failed")) {
showCustomDialog(
title: "Error".tr,
message: 'Payment Failed'.tr, // يتم جلب رسالة الخطأ من الخادم
isSuccess: false,
);
}
},
))
..loadRequest(Uri.parse(widget.iframeUrl));
}
Future<void> _fetchPaymentStatus() async {
final String userId = box.read(BoxName.phoneDriver);
await Future.delayed(const Duration(seconds: 2));
try {
final response = await CRUD().postWallet(
link: AppLink.paymetVerifyDriver,
payload: {
'user_id': userId,
'driverID': box.read(BoxName.driverID),
'paymentMethod': 'visa-in',
},
);
if (response != 'failure' && response != 'token_expired') {
if (response['status'] == 'success') {
final payment = response['message'];
final amount = payment['amount'].toString();
final bonus = payment['bonus'].toString();
final paymentID = payment['paymentID'].toString();
await controller.getCaptainWalletFromBuyPoints();
showCustomDialog(
title: "payment_success".tr,
message:
"${"transaction_id".tr}: $paymentID\n${"amount_paid".tr}: $amount EGP\n${"bonus_added".tr}: $bonus ${"points".tr}",
isSuccess: true,
);
} else {
showCustomDialog(
title: "transaction_failed".tr,
message: response['message'].toString(),
isSuccess: false,
);
}
} else {
showCustomDialog(
title: "connection_failed".tr,
message: response.toString(),
isSuccess: false,
);
}
} catch (e) {
showCustomDialog(
title: "server_error".tr,
message: "server_error_message".tr,
isSuccess: false,
);
}
}
void showCustomDialog({
required String title,
required String message,
required bool isSuccess,
}) {
showDialog(
barrierDismissible: false,
context: Get.context!,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
title: Row(
children: [
Icon(
isSuccess ? Icons.check_circle : Icons.error,
color: isSuccess ? Colors.green : Colors.red,
),
const SizedBox(width: 8),
Text(
title,
style: TextStyle(
color: isSuccess ? Colors.green : Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
content: Text(
message,
style: const TextStyle(fontSize: 16),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
style: TextButton.styleFrom(
backgroundColor: isSuccess ? Colors.green : Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
child: Text(
"OK",
style: const TextStyle(color: Colors.white),
),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('إتمام الدفع')),
body: WebViewWidget(controller: _controller),
);
}
}
class PaymentScreenWallet extends StatefulWidget {
final String iframeUrl;
final String countPrice;
const PaymentScreenWallet(
{required this.iframeUrl, Key? key, required this.countPrice})
: super(key: key);
@override
State<PaymentScreenWallet> createState() => _PaymentScreenWalletState();
}
class _PaymentScreenWalletState extends State<PaymentScreenWallet> {
late final WebViewController _controller;
final controller = Get.find<CaptainWalletController>();
@override
void initState() {
super.initState();
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onPageFinished: (url) {
if (url.contains("success")) {
_fetchPaymentStatus(); // ✅ استدعاء الويب هوك بعد نجاح الدفع
} else if (url.contains("failed")) {
showCustomDialog(
title: "Error".tr,
message: 'Payment Failed'.tr, // يتم جلب رسالة الخطأ من الخادم
isSuccess: false,
);
}
},
))
..loadRequest(Uri.parse(widget.iframeUrl));
}
Future<void> _fetchPaymentStatus() async {
final String userId = '+963' + box.read(BoxName.phoneWallet);
await Future.delayed(const Duration(seconds: 2));
try {
final response = await CRUD().postWallet(
link: AppLink.paymetVerifyDriver,
payload: {
'user_id': userId,
'driverID': box.read(BoxName.driverID),
'paymentMethod': 'visa-in',
},
);
if (response != 'failure' && response != 'token_expired') {
if (response['status'] == 'success') {
final payment = response['message'];
final amount = payment['amount'].toString();
final bonus = payment['bonus'].toString();
final paymentID = payment['paymentID'].toString();
await controller.getCaptainWalletFromBuyPoints();
showCustomDialog(
title: "payment_success".tr,
message:
"${"transaction_id".tr}: $paymentID\n${"amount_paid".tr}: $amount EGP\n${"bonus_added".tr}: $bonus ${"points".tr}",
isSuccess: true,
);
} else {
showCustomDialog(
title: "transaction_failed".tr,
message: response['message'].toString(),
isSuccess: false,
);
}
} else {
showCustomDialog(
title: "connection_failed".tr,
message: response.toString(),
isSuccess: false,
);
}
} catch (e) {
showCustomDialog(
title: "server_error".tr,
message: "server_error_message".tr,
isSuccess: false,
);
}
}
void showCustomDialog({
required String title,
required String message,
required bool isSuccess,
}) {
showDialog(
barrierDismissible: false,
context: Get.context!,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
title: Row(
children: [
Icon(
isSuccess ? Icons.check_circle : Icons.error,
color: isSuccess ? Colors.green : Colors.red,
),
const SizedBox(width: 8),
Text(
title,
style: TextStyle(
color: isSuccess ? Colors.green : Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
content: Text(
message,
style: const TextStyle(fontSize: 16),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
style: TextButton.styleFrom(
backgroundColor: isSuccess ? Colors.green : Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
child: Text(
"OK",
style: const TextStyle(color: Colors.white),
),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('إتمام الدفع')),
body: WebViewWidget(controller: _controller),
);
}
}
Future<void> payWithMTNWallet(
BuildContext context, String amount, String currency) async {
// استخدام مؤشر تحميل لتجربة مستخدم أفضل
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);
print("🚀 بدء عملية دفع MTN");
print(
"📦 Payload: driverID: $driverID, amount: $formattedAmount, phone: $phone");
// التحقق من البصمة (اختياري)
bool isAuthSupported = await LocalAuthentication().isDeviceSupported();
if (isAuthSupported) {
bool didAuthenticate = await LocalAuthentication().authenticate(
localizedReason: 'استخدم بصمة الإصبع أو الوجه لتأكيد الدفع',
);
if (!didAuthenticate) {
if (Get.isDialogOpen ?? false) Get.back();
print("❌ المستخدم لم يؤكد بالبصمة/الوجه");
return;
}
}
// 1⃣ استدعاء mtn_start_payment.php (الملف الجديد)
var responseData = await CRUD().postWalletMtn(
link: AppLink.payWithMTNStart,
payload: {
"amount": formattedAmount,
"passengerId": driverID,
"phone": phone,
"lang": box.read(BoxName.lang) ?? 'ar',
},
);
print("✅ استجابة الخادم (mtn_start_payment.php):");
print(responseData);
// --- بداية التعديل المهم ---
// التحقق القوي من الاستجابة لتجنب الأخطاء
Map<String, dynamic> startRes;
if (responseData is Map<String, dynamic>) {
// إذا كانت الاستجابة بالفعل Map، استخدمها مباشرة
startRes = responseData;
} else if (responseData is String) {
// إذا كانت نص، حاول تحليلها كـ JSON
try {
startRes = json.decode(responseData);
} catch (e) {
throw Exception(
"فشل في تحليل استجابة الخادم. الاستجابة: $responseData");
}
} else {
// نوع غير متوقع
throw Exception("تم استلام نوع بيانات غير متوقع من الخادم.");
}
if (startRes['status'] != 'success') {
final errorMsg = startRes['message']['Error']?.toString().tr ??
"فشل بدء عملية الدفع. حاول مرة أخرى.";
throw Exception(errorMsg);
}
// --- نهاية التعديل المهم ---
// استخراج البيانات بأمان
final messageData = startRes["message"];
final invoiceNumber = messageData["invoiceNumber"].toString();
final operationNumber = messageData["operationNumber"].toString();
final guid = messageData["guid"].toString();
print(
"📄 invoiceNumber: $invoiceNumber, 🔢 operationNumber: $operationNumber, 🧭 guid: $guid");
if (Get.isDialogOpen == true)
Get.back(); // إغلاق مؤشر التحميل قبل عرض حوار OTP
// 2⃣ عرض واجهة إدخال OTP
String? otp = await showDialog<String>(
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,
),
actions: [
TextButton(
child: const Text("تأكيد"),
onPressed: () => Navigator.of(context).pop(input),
),
TextButton(
child: const Text("إلغاء"),
onPressed: () => Navigator.of(context).pop(),
),
],
);
},
);
if (otp == null || otp.isEmpty) {
print("❌ لم يتم إدخال OTP");
return;
}
print("🔐 تم إدخال OTP: $otp");
Get.dialog(const Center(child: CircularProgressIndicator()),
barrierDismissible: false);
// 3⃣ استدعاء mtn_confirm.php
var confirmRes = await CRUD().postWalletMtn(
link: AppLink.payWithMTNConfirm,
payload: {
"invoiceNumber": invoiceNumber,
"operationNumber": operationNumber,
"guid": guid,
"otp": otp,
"phone": phone,
},
);
if (Get.isDialogOpen ?? false) Get.back();
print("✅ استجابة mtn_confirm.php:");
// print(confirmRes);
Log.print('confirmRes: ${confirmRes}');
if (confirmRes != null && confirmRes['status'] == 'success') {
Get.defaultDialog(
title: "✅ نجاح",
content: const Text("تمت عملية الدفع وإضافة الرصيد إلى محفظتك."),
);
} else {
String errorMsg =
confirmRes?['message']['message']?.toString() ?? "فشل في تأكيد الدفع";
Get.defaultDialog(
title: "❌ فشل",
content: Text(errorMsg.tr),
);
}
} catch (e, s) {
print("🔥 خطأ أثناء الدفع عبر MTN:");
print(e);
print(s);
if (Get.isDialogOpen ?? false) Get.back();
Get.defaultDialog(
title: 'حدث خطأ',
content: Text(e.toString().replaceFirst("Exception: ", "")),
);
}
}
Future<void> 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):");
Log.print('responseData: ${responseData}');
// Robustly parse the server's JSON response
Map<String, dynamic> startRes;
if (responseData is Map<String, dynamic>) {
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<String>(
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,
),
actions: [
TextButton(
child: const Text("تأكيد"),
onPressed: () => Navigator.of(context).pop(input),
),
TextButton(
child: const Text("إلغاء"),
onPressed: () => Navigator.of(context).pop(),
),
],
);
},
);
if (otp == null || otp.isEmpty) {
print("❌ OTP was not entered.");
return;
}
print("🔐 OTP entered: $otp");
Get.dialog(const Center(child: CircularProgressIndicator()),
barrierDismissible: false);
// --- CHANGE 4: Updated API link and payload for confirming payment ---
// Make sure you have defined `payWithSyriatelConfirm` in your AppLink class
var confirmRes = await CRUD().postWalletMtn(
// Changed from postWalletMtn if they are different
link: AppLink.payWithSyriatelConfirm, // Use the new Syriatel confirm link
payload: {
"transactionID": transactionID, // Use the transaction ID
"otp": otp,
// The other parameters (phone, guid, etc.) are no longer needed
},
);
if (Get.isDialogOpen ?? false) Get.back();
print("✅ Response from confirm_payment.php:");
Log.print('confirmRes: ${confirmRes}');
if (confirmRes != null && 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() ?? "فشل في تأكيد الدفع";
Get.defaultDialog(
title: "❌ فشل",
content: Text(errorMsg.tr),
);
}
} 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();
Get.defaultDialog(
title: 'حدث خطأ',
content: Text(e.toString().replaceFirst("Exception: ", "")),
);
}
}