-- Register callback for sending bills lib.callback.register('billing:server:sendBill', function(source, data) local src = source local player = QBCore.Functions.GetPlayer(src) local target = QBCore.Functions.GetPlayer(data.playerId) if not player or not target then return false end local senderName = player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname local description = data.reason .. ' (From: ' .. senderName .. ')' -- Create the bill exports["ps-banking"]:createBill({ identifier = target.PlayerData.citizenid, description = description, type = "Invoice", amount = data.amount, }) -- Store additional data about the bill if needed -- You could create a separate table to track which account the payment should go to MySQL.insert.await('INSERT INTO billing_accounts (bill_description, sender_id, receiver_id, account_id, amount, created_at) VALUES (?, ?, ?, ?, ?, NOW())', { description, player.PlayerData.citizenid, target.PlayerData.citizenid, data.account, data.amount }) -- Notify the target player TriggerClientEvent('QBCore:Notify', data.playerId, 'You received a bill for $' .. data.amount .. ' - ' .. data.reason, 'primary', 7500) return true end) -- Event handler for when a bill is paid RegisterNetEvent('billing:server:billPaid', function(billId) local src = source local player = QBCore.Functions.GetPlayer(src) if not player then return end -- Find the bill in our custom table local billData = MySQL.query.await('SELECT * FROM billing_accounts WHERE bill_id = ?', {billId}) if billData and #billData > 0 then local bill = billData[1] local receiverId = bill.sender_id local accountId = bill.account_id local amount = bill.amount -- If it's a personal account if accountId == 'personal' then local receiver = QBCore.Functions.GetPlayerByCitizenId(receiverId) if receiver then -- Add money directly to the receiver's bank account receiver.Functions.AddMoney('bank', amount, 'bill-payment') TriggerClientEvent('QBCore:Notify', receiver.PlayerData.source, 'You received $' .. amount .. ' from a bill payment', 'success') else -- Handle offline player (could store in a separate table for when they log in) MySQL.insert.await('INSERT INTO offline_payments (citizen_id, amount, reason) VALUES (?, ?, ?)', { receiverId, amount, 'Bill payment' }) end else -- Add money to the specified account MySQL.update.await('UPDATE ps_banking_accounts SET balance = balance + ? WHERE id = ?', { amount, accountId }) end -- Update the bill status MySQL.update.await('UPDATE billing_accounts SET paid = 1, paid_at = NOW() WHERE bill_id = ?', {billId}) end end) -- Create the necessary database tables if they don't exist MySQL.ready(function() MySQL.query.await([[ CREATE TABLE IF NOT EXISTS billing_accounts ( id INT AUTO_INCREMENT PRIMARY KEY, bill_id INT, bill_description VARCHAR(255), sender_id VARCHAR(50), receiver_id VARCHAR(50), account_id VARCHAR(50), amount DECIMAL(10,2), created_at DATETIME, paid TINYINT DEFAULT 0, paid_at DATETIME ) ]]) MySQL.query.await([[ CREATE TABLE IF NOT EXISTS offline_payments ( id INT AUTO_INCREMENT PRIMARY KEY, citizen_id VARCHAR(50), amount DECIMAL(10,2), reason VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, processed TINYINT DEFAULT 0 ) ]]) end) -- Handle offline payments when a player logs in RegisterNetEvent('QBCore:Server:PlayerLoaded', function() local src = source local player = QBCore.Functions.GetPlayer(src) if not player then return end local citizenId = player.PlayerData.citizenid local offlinePayments = MySQL.query.await('SELECT * FROM offline_payments WHERE citizen_id = ? AND processed = 0', {citizenId}) if offlinePayments and #offlinePayments > 0 then local totalAmount = 0 for _, payment in ipairs(offlinePayments) do totalAmount = totalAmount + payment.amount end if totalAmount > 0 then player.Functions.AddMoney('bank', totalAmount, 'offline-bill-payments') TriggerClientEvent('QBCore:Notify', src, 'You received $' .. totalAmount .. ' from bill payments while offline', 'success') -- Mark payments as processed MySQL.update.await('UPDATE offline_payments SET processed = 1 WHERE citizen_id = ? AND processed = 0', {citizenId}) end end end) -- Listen for bill payment events from ps-banking RegisterNetEvent('ps-banking:server:billPaid', function(billId) TriggerEvent('billing:server:billPaid', billId) end)