fix(security): wallet balance check with FOR UPDATE, remove user-supplied ID in signup, hardcoded IP to env
This commit is contained in:
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user