Files
Siro/payment_server/v2/main/ride/driverWallet/driverStatistic.php
T
Hamza-AyedandClaude Opus 5 61d6380861 Fix SQL injection and stale status matching in the wallet endpoints
The three endpoints the driver app calls for its wallet built their queries by
interpolating the driver id straight into SQL. Anything the app sent went into
the statement, and these run against the payments database.

They also matched only status = 'Finished'. The current ride pipeline writes
'completed', so a driver's completed rides, pending payouts and weekly
earnings all read as zero regardless of how much they had driven — which is
what the wallet errors in the admin error log are sitting next to.

getAllPayment.php, driverStatistic.php and getCountRide.php now bind the id
and match either spelling. Verified no interpolated identifier remains and
every rewritten condition is balanced.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 17:57:52 +03:00

48 lines
1.8 KiB
PHP

<?php
include "../../connect.php";
$driverID = filterRequest("driverID");
$sql = "SELECT
YEAR(`driver_orders`.`created_at`) AS `year`,
MONTH(`driver_orders`.`created_at`) AS `month`,
COUNT(*) AS `total_orders`,
SUM(CASE WHEN LOWER(`ride`.`status`) IN ('finished','completed') THEN 1 ELSE 0 END) AS `completed_orders`,
SUM(CASE WHEN `ride`.`status` = 'Apply' THEN 1 ELSE 0 END) AS `pending_orders`,
SUM(CASE WHEN `ride`.`status` = 'Cancel' THEN 1 ELSE 0 END) AS `canceled_orders`,
ROUND(SUM(CASE WHEN LOWER(`ride`.`status`) IN ('finished','completed') THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_completed`,
ROUND(SUM(CASE WHEN `ride`.`status` = 'Apply' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_pending`,
ROUND(SUM(CASE WHEN `ride`.`status` = 'Cancel' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_canceled`,
SUM(CASE WHEN `ride`.`status` = 'Refused' THEN 1 ELSE 0 END) AS `rejected_orders`,
ROUND(SUM(CASE WHEN `ride`.`status` = 'Refused' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_rejected`
FROM
`driver_orders`
LEFT JOIN `ride` ON `ride`.`id` = `driver_orders`.`order_id`
WHERE
`driver_orders`.`driver_id` = :driverID
AND YEAR(`driver_orders`.`created_at`) = YEAR(CURDATE())
AND MONTH(`driver_orders`.`created_at`) = MONTH(CURDATE())
GROUP BY
YEAR(`driver_orders`.`created_at`),
MONTH(`driver_orders`.`created_at`)
ORDER BY
`year`,
`month`;
";
// كان المعرّف يُدمج في نص الاستعلام مباشرةً — حقن SQL.
$stmt = $con->prepare($sql);
$stmt->bindValue(':driverID', $driverID);
$stmt->execute();
if ($stmt->rowCount() > 0) {
// Fetch the record
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
printSuccess( $row);
}
else{
// Print a failure message
printFailure($message = "No wallet record found");
}
?>