'error', 'message' => 'Missing required fields or invalid amount']); exit; } try { $con->beginTransaction(); // 1. Fetch current budget $stmt = $con->prepare("SELECT SUM(amount) as diff FROM payments WHERE captain_id = :driverID FOR UPDATE"); $stmt->execute([':driverID' => $driverID]); $sumRow = $stmt->fetch(PDO::FETCH_ASSOC); $totalBudget = floatval($sumRow['diff']); if ($totalBudget < $amount) { $con->rollBack(); echo json_encode(['status' => 'error', 'message' => 'Insufficient budget']); exit; } // 2. Generate unique tokens $paymentID1 = "budget2pt_" . time() . rand(1000, 9999); $paymentID2 = "pt2budget_" . time() . rand(1000, 9999); $token1 = md5(uniqid("b1", true)); $token2 = md5(uniqid("b2", true)); // 3. Deduct from budget (payments) $deductAmount = -$amount; $stmt = $con->prepare("INSERT INTO payments (captain_id, amount, rideId, payment_method, passengerID, token) VALUES (:driverID, :amount, :rideId, 'myBudget', 'myBudgetToPoint', :token)"); $stmt->execute([ ':driverID' => $driverID, ':amount' => $deductAmount, ':rideId' => $paymentID1, ':token' => $token1 ]); // 4. Add to points (paymentsDriverPoints) $stmt = $con->prepare("INSERT INTO paymentsDriverPoints (captain_id, paymentID, amount, token, paymentMethod) VALUES (:driverID, :paymentID, :amount, :token, 'fromBudget')"); $stmt->execute([ ':driverID' => $driverID, ':paymentID' => $paymentID2, ':amount' => $amount, ':token' => $token2 ]); // Commit Transaction $con->commit(); echo json_encode(['status' => 'success', 'message' => 'Budget converted to points successfully']); } catch (Exception $e) { $con->rollBack(); echo json_encode(['status' => 'error', 'message' => 'Database transaction failed: ' . $e->getMessage()]); } ?>