fix(security): wallet race conditions - FOR UPDATE + atomic claims on payments, webhooks, bonuses
This commit is contained in:
@@ -13,13 +13,16 @@ $phone = filterRequest("phone");
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// 1) CHECK IF DRIVER ALREADY RECEIVED THIS PAYMENT BEFORE
|
||||
// 1) ATOMIC CHECK + INSERT TO PREVENT RACE CONDITION
|
||||
// -------------------------------------------------------------
|
||||
$con->beginTransaction();
|
||||
|
||||
$check = $con->prepare("
|
||||
SELECT id
|
||||
FROM driverWallet
|
||||
WHERE driverID = :driverID AND paymentMethod = :paymentMethod
|
||||
LIMIT 1
|
||||
FOR UPDATE
|
||||
");
|
||||
|
||||
$check->execute([
|
||||
@@ -28,12 +31,11 @@ $check->execute([
|
||||
]);
|
||||
|
||||
if ($check->rowCount() > 0) {
|
||||
// Driver already received this "New Driver" payment
|
||||
$con->rollBack();
|
||||
printFailure("لقد تم منح هذا الدفع للسائق مسبقاً — لا يمكن تكراره.");
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// 2) INSERT INTO driverWallet
|
||||
// -------------------------------------------------------------
|
||||
@@ -57,6 +59,8 @@ $stmt->execute(array(
|
||||
':paymentMethod' => $paymentMethod
|
||||
));
|
||||
|
||||
$con->commit();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
|
||||
printSuccess("Record saved successfully");
|
||||
|
||||
Reference in New Issue
Block a user