This is an easy fix.
Let me explain so you can hopefully avoid this issue in the future. 
“toggle” is locally scoped to the client event “gnc_motels:toggleTimer”. It’s a parameter that is received by the event, and used in the event handler function. Parameters are locally scoped.
If you aren’t aware, the “scope” is the area something exists and can be accessed. In this case, just within that instance of the function. Unless you take a parameter and assign it to a variable OUTSIDE the scope of the function, it doesn’t exist anywhere else. It also doesn’t exist inside the same function if called again. Only for the time it was called. Each time you call it, a NEW version of “toggle” is created, so having a different value can’t change the value from a previous call.
The issue you are having is, you are calling the event handler function a second time, expecting it to change the previous value of toggle. But it’s a new instance of toggle. How do we avoid this? Easy! Assign “toggle” to a variable outside the scope of the function. And in this case, instead of checking that “toggle” is true in the loop, check the new variable, after we assign the new value.
local timerEnabled = false
RegisterNetEvent("gnc_motels:toggleTimer")
AddEventHandler("gnc_motels:toggleTimer", function(toggle)
local id = GetPlayerServerId(PlayerId())
timerEnabled = toggle
time = 10
Citizen.CreateThread(function()
Citizen.Wait(2000)
while time ~= 0 and timerEnabled do
Citizen.Wait(1000)
time = time - 1
print(time)
end
time = 10
TriggerServerEvent("gnc_motels:payKey", id)
end)
end)
What you can also do is check if the loop is already running, to avoid it running twice. Not sure if you need this, but if so, here you go. I also removed the “Citizen.” prefixes because they aren’t needed and I removed the “AddEventHandler” because you can put it’s event in RegisterNetEvent. It’s an old practice of separating them and this looks much neater but runs the same.
local timerEnabled = false
RegisterNetEvent("gnc_motels:toggleTimer", function(toggle)
local id = GetPlayerServerId(PlayerId())
timerEnabled = toggle
if toggle and not timerEnabled then
time = 10
CreateThread(function()
Wait(2000)
while time ~= 0 and timerEnabled do
Wait(1000)
time = time - 1
print(time)
end
time = 10
TriggerServerEvent("gnc_motels:payKey", id)
end)
end
end)
If this helped you, please mark it as a solution so others can learn about scoping too! 