fix(security): wallet balance check with FOR UPDATE, remove user-supplied ID in signup, hardcoded IP to env

This commit is contained in:
Hamza-Ayed
2026-06-17 06:53:00 +03:00
parent 3dad979eb5
commit 1d3ea597f4
3 changed files with 43 additions and 21 deletions

View File

@@ -41,13 +41,12 @@ $passengerId = filterRequest("passengerId");
$paymentAmount = filterRequest("paymentAmount");
$paymentMethod = filterRequest("paymentMethod");
$walletChecked = filterRequest("walletChecked"); // 'true' or 'false'
$passengerWalletBurc = filterRequest("passengerWalletBurc"); // passenger balance before operation
$authToken = filterRequest("authToken"); // kept for logging/audit, not used for auth
// --- Validate required fields ---
if (empty($rideId) || empty($driverId) || empty($passengerId) ||
!isset($paymentAmount) || empty($paymentMethod) ||
!isset($walletChecked) || !isset($passengerWalletBurc)) {
!isset($walletChecked)) {
printFailure("Missing required parameters for payment processing.");
exit;
}
@@ -79,33 +78,59 @@ try {
// 3b. Deduct from passenger wallet (if wallet payment)
if ($walletChecked === 'true') {
// Check actual balance with row lock
$stmtBalance = $con->prepare(
"SELECT COALESCE(SUM(balance), 0) AS current_balance
FROM passengerWallet
WHERE passenger_id = :passenger_id
FOR UPDATE"
);
$stmtBalance->execute([':passenger_id' => $passengerId]);
$balanceRow = $stmtBalance->fetch(PDO::FETCH_ASSOC);
$currentBalance = floatval($balanceRow['current_balance']);
$deductionAmount = floatval($paymentAmount);
if ($currentBalance < $deductionAmount) {
throw new Exception("Insufficient wallet balance. Required: $deductionAmount, Available: $currentBalance");
}
$stmtPassengerWallet = $con->prepare(
"INSERT INTO `passengerWallet` (`passenger_id`, `balance`)
VALUES (:passenger_id, :balance)"
);
$stmtPassengerWallet->execute([
':passenger_id' => $passengerId,
':balance' => (-1) * floatval($paymentAmount),
':balance' => (-1) * $deductionAmount,
]);
if ($stmtPassengerWallet->rowCount() <= 0) {
throw new Exception("Failed to deduct from passenger wallet.");
}
}
// 3c. Settle existing passenger debt (if balance was negative)
if (floatval($passengerWalletBurc) < 0) {
$stmtPassengerDebt = $con->prepare(
"INSERT INTO `passengerWallet` (`passenger_id`, `balance`)
VALUES (:passenger_id, :balance)"
// 3c. Settle existing debt (use actual balance after deduction)
$stmtBalanceAfter = $con->prepare(
"SELECT COALESCE(SUM(balance), 0) AS balance_after
FROM passengerWallet
WHERE passenger_id = :passenger_id
FOR UPDATE"
);
$stmtPassengerDebt->execute([
':passenger_id' => $passengerId,
':balance' => (-1) * floatval($passengerWalletBurc),
]);
$stmtBalanceAfter->execute([':passenger_id' => $passengerId]);
$balanceAfterRow = $stmtBalanceAfter->fetch(PDO::FETCH_ASSOC);
$balanceAfter = floatval($balanceAfterRow['balance_after']);
if ($stmtPassengerDebt->rowCount() <= 0) {
throw new Exception("Failed to settle passenger debt.");
if ($balanceAfter < 0) {
$stmtPassengerDebt = $con->prepare(
"INSERT INTO `passengerWallet` (`passenger_id`, `balance`)
VALUES (:passenger_id, :balance)"
);
$stmtPassengerDebt->execute([
':passenger_id' => $passengerId,
':balance' => (-1) * $balanceAfter,
]);
if ($stmtPassengerDebt->rowCount() <= 0) {
throw new Exception("Failed to settle passenger debt.");
}
}
}