Update: 2026-08-07 00:36:27
This commit is contained in:
@@ -13,11 +13,22 @@ require_once __DIR__ . '/streak_helper.php';
|
||||
$rideId = filterRequest("ride_id");
|
||||
$driverId = filterRequest("driver_id");
|
||||
$reason = filterRequest("reason");
|
||||
$passengerToken = filterRequest("passenger_token");
|
||||
$penaltyFee = (float) filterRequest("penalty_fee");
|
||||
$passengerToken = filterRequest("passenger_token");
|
||||
|
||||
// مبلغ الغرامة لا يُقرأ من الطلب إطلاقاً. كان سابقاً filterRequest("penalty_fee")
|
||||
// فيُخصم من محفظة الراكب بلا سقف ولا تحقق. صار يُحسم من سياسة الخادم أدناه.
|
||||
// إن وصل المفتاح من عميل فهو إما نسخة قديمة أو محاولة عبث — نسجّله ونتجاهله.
|
||||
if (filterRequest("penalty_fee") !== null && filterRequest("penalty_fee") !== '') {
|
||||
error_log("[cancel_ride_by_driver] SECURITY: تجاهل penalty_fee من العميل"
|
||||
. " (ride=$rideId driver=$driverId) — السياسة تُقرأ من kazan فقط");
|
||||
}
|
||||
|
||||
// سقف صلب فوق أي قيمة في قاعدة البيانات — يمنع خطأ إدارياً أو صفاً تالفاً
|
||||
// من تحويل الغرامة إلى خصم كارثي.
|
||||
const CANCEL_PENALTY_ABSOLUTE_CAP = 50000.0;
|
||||
|
||||
// تثبيت الحالة
|
||||
$statusText = "CancelFromDriverAfterApply";
|
||||
$statusText = "CancelFromDriverAfterApply";
|
||||
|
||||
if (!$rideId || !$driverId) {
|
||||
jsonError("Missing parameters");
|
||||
@@ -27,6 +38,28 @@ if (!$rideId || !$driverId) {
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 0. التحقق من الملكية — الرحلة يجب أن تكون مُسندة لهذا السائق
|
||||
// بدون هذا الفحص كان أي driver_id يقدر يلغي أي رحلة ويغرّم راكبها.
|
||||
// ---------------------------------------------------------
|
||||
$stmtOwn = $con->prepare("SELECT driver_id FROM ride WHERE id = ? FOR UPDATE");
|
||||
$stmtOwn->execute([$rideId]);
|
||||
$assignedDriver = $stmtOwn->fetchColumn();
|
||||
|
||||
if ($assignedDriver === false) {
|
||||
$con->rollBack();
|
||||
jsonError("Ride not found");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ((string) $assignedDriver !== (string) $driverId) {
|
||||
$con->rollBack();
|
||||
error_log("[cancel_ride_by_driver] SECURITY: رفض إلغاء رحلة غير مُسندة"
|
||||
. " (ride=$rideId caller=$driverId assigned=$assignedDriver)");
|
||||
jsonError("Ride is not assigned to this driver");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 1. معالجة driver_orders (Insert or Update)
|
||||
// ---------------------------------------------------------
|
||||
@@ -99,17 +132,35 @@ try {
|
||||
notifyPassengerOnRideServer($passenger_id, $socketPayload);
|
||||
}
|
||||
|
||||
// 4.1. إضافة غرامة الإلغاء على الراكب (الدين) إذا كانت موجودة
|
||||
// 4.1. غرامة الإلغاء على الراكب — المبلغ من سياسة الخادم لا من العميل
|
||||
// Resolve country + penalty policy (kazan هو مصدر الحقيقة الوحيد)
|
||||
// قراءة متسامحة: لو نزل الكود قبل ترحيل cancelPenaltyFee، لا نُسقط
|
||||
// الإلغاء كله — نرجع لقراءة الدولة وحدها ونعتبر الغرامة صفراً.
|
||||
try {
|
||||
$stmtKazan = $con->prepare("SELECT country, cancelPenaltyFee FROM kazan LIMIT 1");
|
||||
$stmtKazan->execute();
|
||||
$kazan = $stmtKazan->fetch(PDO::FETCH_ASSOC) ?: [];
|
||||
} catch (PDOException $eKazan) {
|
||||
error_log("[cancel_ride_by_driver] cancelPenaltyFee غير موجود بعد"
|
||||
. " (شغّل migrations/2026_08_07_kazan_cancel_penalty_policy.sql): "
|
||||
. $eKazan->getMessage());
|
||||
$stmtKazan = $con->prepare("SELECT country FROM kazan LIMIT 1");
|
||||
$stmtKazan->execute();
|
||||
$kazan = $stmtKazan->fetch(PDO::FETCH_ASSOC) ?: [];
|
||||
}
|
||||
$country = $kazan['country'] ?? 'Jordan';
|
||||
|
||||
$penaltyFee = (float) ($kazan['cancelPenaltyFee'] ?? 0);
|
||||
if ($penaltyFee > CANCEL_PENALTY_ABSOLUTE_CAP) {
|
||||
error_log("[cancel_ride_by_driver] kazan.cancelPenaltyFee=$penaltyFee"
|
||||
. " تجاوز السقف الصلب — قُصّ إلى " . CANCEL_PENALTY_ABSOLUTE_CAP);
|
||||
$penaltyFee = CANCEL_PENALTY_ABSOLUTE_CAP;
|
||||
}
|
||||
|
||||
if ($penaltyFee > 0) {
|
||||
// إضافة القيمة كدين سالب في المحفظة
|
||||
$negativeDebt = -$penaltyFee;
|
||||
|
||||
// Resolve country and wallet server
|
||||
$stmtKazan = $con->prepare("SELECT country FROM kazan LIMIT 1");
|
||||
$stmtKazan->execute();
|
||||
$kazan = $stmtKazan->fetch(PDO::FETCH_ASSOC) ?: ["country" => "Jordan"];
|
||||
$country = $kazan['country'] ?? 'Jordan';
|
||||
|
||||
$walletServer = "https://walletintaleq.intaleq.xyz";
|
||||
if (strtolower($country) == 'jordan') {
|
||||
$walletServer = getenv('WALLET_SERVER_JORDAN') ?: "https://walletintaleq.intaleq.xyz";
|
||||
|
||||
Reference in New Issue
Block a user