prepare("INSERT INTO payment_tokens (token, passengerID, dateCreated, amount) VALUES (:token, :passengerID, NOW(), :amount)"); // لاحظ: استخدمنا passengerID هنا بدلاً من driverID بناء على الجدول، إذا كان الجدول موحداً استخدم العمود المناسب // غالباً الجدول يحتوي user_id أو يتم استخدام driverID للكل. // سأفترض هنا أن الجدول يقبل التوكن، وسأقوم بربطه بالراكب. // إذا كان عمود driverID هو الوحيد الموجود، يمكن تمرير الراكب فيه أو تعديل الجدول. // **للتوافق مع السائق:** سأستخدم الحقل العام أو أتجاوز الـ foreign key إذا وجد. // لكن الأضمن: $stmt->execute([':token' => $token, ':passengerID' => $userId, ':amount' => $amount]); return $stmt->rowCount() > 0 ? $token : null; } } // --- المدخلات --- $transactionID = filterRequest('transactionID'); // يقابل order_ref $otp = filterRequest('otp'); // كود التأكيد $lang = filterRequest('lang'); // اختياري mlog("Syriatel Confirm (Passenger): Start tx={$transactionID}"); if (!$transactionID || !$otp) { printFailure($lang === 'ar' ? "رقم العملية أو رمز OTP مفقود." : "Missing transaction ID or OTP."); exit; } // --- المتغيرات البيئية --- $baseUrl = rtrim(getenv('SYRIATEL_API_BASE_URL'), '/'); $merchantMSISDN = getenv('SYRIATEL_MERCHANT_MSISDN'); if (!$baseUrl || !$merchantMSISDN) { printFailure($lang === 'ar' ? "خطأ في إعدادات الخادم." : "Server configuration error."); exit; } try { // 1) توكن المصادقة من Syriatel $token = getSyriatelToken(); if (!$token) { printFailure($lang === 'ar' ? "تعذّر المصادقة مع مزوّد الدفع." : "Could not authenticate with the payment provider."); exit; } // 2) تحضير وإرسال طلب التأكيد لشركة سيريتل $body = [ "OTP" => $otp, "merchantMSISDN" => $merchantMSISDN, "transactionID" => $transactionID, "token" => $token ]; $ch = curl_init("{$baseUrl}/ePaymentExternalModule/paymentConfirmation"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE), CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_TIMEOUT => 25, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $res = json_decode($response ?: '{}', true); if (!is_array($res)) { $res = []; } $errCode = isset($res['errorCode']) ? (string)$res['errorCode'] : null; // التحقق من رد سيريتل if ($httpCode !== 200 || $errCode !== "0") { $errText = $res['errorDesc'] ?? $res['resultDescription'] ?? 'Payment failed'; mlog("Syriatel Confirm (Passenger): Failed - " . json_encode($res, JSON_UNESCAPED_UNICODE)); printFailure(['message' => $errText, 'syriatel' => $res]); exit; } // ============================================================ // ✅ هنا يبدأ التعديل: التحديث المباشر لقاعدة البيانات (بدون cURL) // ============================================================ global $con; // 4) التحقق من السجل في قاعدة البيانات $chk = $con->prepare("SELECT status, user_id, amount, payment_method FROM paymentsLogSyria WHERE order_ref = :ref LIMIT 1"); $chk->execute([':ref' => $transactionID]); $payment = $chk->fetch(PDO::FETCH_ASSOC); if (!$payment) { printFailure($lang === 'ar' ? "لم يتم العثور على السجل." : "Payment row not found"); exit; } if ((int)$payment['status'] === 1) { printSuccess(['message' => 'Already confirmed', 'data' => ['order_ref' => $transactionID]]); exit; } // بدء المعاملة (Transaction) $con->beginTransaction(); try { // أ) تحديث حالة الدفع في السجل $stmtUpdate = $con->prepare("UPDATE `paymentsLogSyria` SET status = 1, updated_at = NOW() WHERE order_ref = :ref"); $stmtUpdate->execute([':ref' => $transactionID]); $passengerId = $payment['user_id']; $originalAmount = floatval($payment['amount']); $paymentMethod = $payment['payment_method'] ?? 'syriatel'; // ب) حساب المكافأة (نفس المنطق القديم) $bonusAmount = match ((int)$originalAmount) { 500 => 530.0, 1000 => 1070.0, 2000 => 2180.0, 5000 => 5700.0, default => $originalAmount, }; // ج) إنشاء التوكنات مباشرة (بدون دالة خارجية) // 1. توكن لمحفظة الراكب (بالمبلغ مع البونص) $tokenPassenger = generateLocalToken($con, $passengerId, $bonusAmount); if (!$tokenPassenger) throw new Exception('Failed to generate passenger token'); // 2. توكن لمحفظة السفر/الإيرادات (بالمبلغ الأصلي) $tokenSiro = generateLocalToken($con, $passengerId, $originalAmount); if (!$tokenSiro) throw new Exception('Failed to generate siro token'); // د) الإضافة إلى passengerWallet مباشرة // ملاحظة: تأكد من أسماء الأعمدة في جدول passengerWallet $insertPassWallet = $con->prepare("INSERT INTO passengerWallet (passenger_id, balance, token, created_at) VALUES (:pid, :amount, :token, NOW())"); $insertPassWallet->execute([ ':pid' => $passengerId, ':amount' => $bonusAmount, ':token' => $tokenPassenger ]); if ($insertPassWallet->rowCount() === 0) throw new Exception('Insert to passengerWallet failed'); // هـ) الإضافة إلى siroWallet مباشرة // ملاحظة: في الراكب، يكون driverId عادة هو 'passenger' لتمييز أن الدفع جاء من تطبيق الراكب $insertSiro = $con->prepare("INSERT INTO siroWallet (driverId, passengerId, amount, paymentMethod, token, createdAt) VALUES (:did, :pid, :amount, :method, :token, NOW())"); $insertSiro->execute([ ':did' => 'passenger', // كما في السكربت القديم ':pid' => $passengerId, ':amount' => $originalAmount, ':method' => $paymentMethod, ':token' => $tokenSiro ]); if ($insertSiro->rowCount() === 0) throw new Exception('Insert to siroWallet failed'); // و) تحديث التوكنات لتصبح مستخدمة (isUsed = TRUE) $updateToken = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token"); $updateToken->execute([':token' => $tokenPassenger]); $updateToken->execute([':token' => $tokenSiro]); // ز) تثبيت المعاملة $con->commit(); mlog("Syriatel Confirm (Passenger): Success DB Transaction for user {$passengerId}"); // إرجاع رد النجاح printSuccess([ 'message' => 'Syriatel Confirm Success', 'data' => [ 'order_ref' => $transactionID, 'finalAmount' => $bonusAmount, 'syriatel' => $res ] ]); exit; } catch (Throwable $e) { // في حال حدوث خطأ، تراجع عن كل شيء $con->rollBack(); mlog("Syriatel Confirm (Passenger): Transaction Error - " . $e->getMessage()); printFailure($lang === 'ar' ? "فشل تحديث المحفظة." : "Wallet update failed."); exit; } } catch (Throwable $e) { mlog("Syriatel Confirm (Passenger): General Exception - " . $e->getMessage()); printFailure($lang === 'ar' ? "خطأ في الخادم." : "Server error"); exit; } ?>