local QBCore = exports['qb-core']:GetCoreObject() local isUiOpen = false local cooldown = false -- Command to open billing menu RegisterCommand('bill', function() OpenBillingMenu() end, false) -- Keybind registration RegisterKeyMapping('bill', 'Open Billing Menu', 'keyboard', 'F7') -- Default key is F7, can be changed in settings -- Function to open the billing menu function OpenBillingMenu() if cooldown then lib.notify({ title = 'Billing System', description = 'Please wait before using the billing system again', type = 'error' }) return end -- Get nearby players local players = GetNearbyPlayers() if #players == 0 then lib.notify({ title = 'Billing System', description = 'No players nearby to bill', type = 'error' }) return end -- Get player's accounts for receiving payment local accounts = lib.callback.await('ps-banking:server:getAccounts', false) or {} local accountOptions = {} -- Add default bank account table.insert(accountOptions, { value = 'personal', label = 'Personal Bank Account' }) -- Add other accounts for _, account in ipairs(accounts) do table.insert(accountOptions, { value = account.id, label = account.holder .. ' - ' .. account.cardNumber }) end -- Create player options for selection local playerOptions = {} for _, player in ipairs(players) do table.insert(playerOptions, { value = player.id, label = player.name .. ' (ID: ' .. player.id .. ')' }) end -- Create the input dialog local input = lib.inputDialog('Create Bill', { { type = 'select', label = 'Select Player', options = playerOptions, required = true }, { type = 'number', label = 'Amount ($)', description = 'Enter the bill amount', icon = 'dollar-sign', required = true, min = 1, max = 100000 }, { type = 'input', label = 'Reason', description = 'Enter the reason for the bill', placeholder = 'Services provided...', required = true }, { type = 'select', label = 'Receiving Account', options = accountOptions, required = true } }) if not input then return end -- Play animation PlayBillingAnimation() -- Send the bill local success = lib.callback.await('billing:server:sendBill', false, { playerId = input[1], amount = input[2], reason = input[3], account = input[4] }) if success then lib.notify({ title = 'Billing System', description = 'Bill sent successfully', type = 'success' }) -- Set cooldown cooldown = true SetTimeout(5000, function() cooldown = false end) else lib.notify({ title = 'Billing System', description = 'Failed to send bill', type = 'error' }) end end -- Function to view received bills function ViewBills() local bills = lib.callback.await('ps-banking:server:getBills', false) if not bills or #bills == 0 then lib.notify({ title = 'Billing System', description = 'You have no unpaid bills', type = 'info' }) return end local billOptions = {} for _, bill in ipairs(bills) do local timestamp = os.date('%Y-%m-%d %H:%M', bill.date) table.insert(billOptions, { title = bill.description, description = ('Amount: $%s | Date: %s'):format(bill.amount, timestamp), metadata = { {label = 'Bill ID', value = bill.id}, {label = 'Type', value = bill.type}, {label = 'Status', value = bill.isPaid and 'Paid' or 'Unpaid'} }, onSelect = function() local confirm = lib.alertDialog({ header = 'Pay Bill', content = ('Do you want to pay $%s for %s?'):format(bill.amount, bill.description), centered = true, cancel = true }) if confirm == 'confirm' then local success = lib.callback.await('ps-banking:server:payBill', false, bill.id) if success then lib.notify({ title = 'Billing System', description = 'Bill paid successfully', type = 'success' }) ViewBills() -- Refresh the list else lib.notify({ title = 'Billing System', description = 'Failed to pay bill. Insufficient funds.', type = 'error' }) end end end }) end lib.registerContext({ id = 'billing_menu', title = 'Your Bills', options = billOptions }) lib.showContext('billing_menu') end -- Command to view bills RegisterCommand('bills', function() ViewBills() end, false) -- Helper function to get nearby players function GetNearbyPlayers() local playerPed = PlayerPedId() local players = QBCore.Functions.GetPlayers() local nearbyPlayers = {} for _, player in ipairs(players) do local targetPed = GetPlayerPed(player) local targetCoords = GetEntityCoords(targetPed) local distance = #(GetEntityCoords(playerPed) - targetCoords) if distance <= 5.0 and targetPed ~= playerPed then local targetId = GetPlayerServerId(player) local targetName = GetPlayerName(player) table.insert(nearbyPlayers, {id = targetId, name = targetName}) end end return nearbyPlayers end -- Animation function function PlayBillingAnimation() lib.requestAnimDict("cellphone@") -- Request the prop model local propModel = 'bzzz_prop_payment_terminal' lib.requestModel(propModel) -- Create prop local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local prop = CreateObject(GetHashKey(propModel), coords.x, coords.y, coords.z, true, true, true) -- Attach prop to player AttachEntityToEntity(prop, playerPed, GetPedBoneIndex(playerPed, 57005), 0.18, 0.01, 0.0, -54.0, 220.0, 43.0, true, true, false, true, 1, true) -- Play animation TaskPlayAnim(playerPed, "cellphone@", "cellphone_text_read_base", 2.0, 3.0, -1, 49, 0, false, false, false) -- Wait for animation to complete Wait(5000) -- Clear animation and delete prop ClearPedTasks(playerPed) DeleteEntity(prop) end