Jump to content
Check out discord.gg/fxap for the cheapest decryptions! First one is free! ×

Get LB-Phone!

Unlock the powerful LB-Phone for a fraction of the price you pay on tebex.

Download

Premium TOS Clothing MEGA Pack!

11GB of pure TOS premium clothing best clothing pack for your Server!

Download

5Decrypt

Automated Asset Decryption

Learn More

4 Screenshots

About This File

Package Description

[Preview]

Preview Link

 

[Explanation]

This is a complete billing system with a beautiful and user-friendly interface.

 

[How it works]

When you type '/invoices' a menu pops up, allowing you to see your invoices, your society invoices and send a invoice to a player.

 

In the config file you are able to set:

  • The command that allows players to open the billing menu;
  • The VAT % of the invoices (visual only, it won't influence the final invoice value);
  • If you want to have a deadline for players to pay their invoices;
  • How many days players have to pay their invoices if the deadline option is set to true;
  • Whether you want the system to automatically pay the invoices after the deadline expires;
  • If you want there to be a daily fee after each day a invoice isn't paid;
  • The daily fee percentage;
  • If only the boss will be able to see the society invoices;
  • The societies that can send invoices to players.

 

It includes Discord logs such as: 

  • When a invoice in sent to a player;
  • When someone pays/cancels a invoice;
  • When a invoice is automatically paid by the system.

 

Additional informations:

  • The notes field (when you're sending a invoice to a player) is not mandatory. If you don't write anything it will write by itself "Nothing to add";
  • The invoice is always sent to the nearest player;
  • On the "My Invoices" section, the unpaid invoices will always appear on the top of the list;
  • When a player pays a invoice or it is automatically paid by the system, the money is instantly added to the society account;
  • The script verifies the offline players when the automatic payment event is executed.

 

It comes with a complete tutorial on how to use it.

Notifications are not included.

 

[Config]

COMMANDS & FUNCTIONALITY

  • Config.InvoicesCommand = 'invoices' -- Command used to open the invoices menu
  • Config.VATPercentage = 23 -- Visual only, it won't influence the final invoice value, change it to your country VAT value
  • Config.LimitDate = true -- Used to enable/disable whether we want to have the payment limit date or not
  • Config.LimitDateDays = 10 -- If Config.LimitDate is enabled, it is used to define the days of the deadline for payment after issuing the invoice
  • Config.PayAutomaticallyAfterLimit = true -- It serves to enable/disable if we want the invoice to be automatically paid after the due date
  • Config.FeeAfterEachDay = true -- Serves to enable/disable if we want unpaid invoices to increase in value after each day they are not paid (For this to work you need to set  = true and add a number to LimitDateDays)
  • Config.FeeAfterEachDayPercentage = 5 -- If Config.FeeAfterEachDay is enabled, it is used to set the fee percentage after each day
  • Config.OnlyBossCanAccessSocietyInvoices = true -- Defines if only the boss can access the society invoices, if false all the employees will have access to it
  • Config.AllowedSocieties = { -- Allowed societies to open the 'Society Invoices' and 'Create Invoice' menus
  •     'police',
  •     'ambulance'
  • }

DISCORD LOGS

  • -- To set your Discord Webhook URL go to server.lua, line 5
  • Config.BotName = 'ServerName' -- Write the desired bot name
  • Config.ServerName = 'ServerName' -- Write your server's name
  • Config.IconURL = '' -- Insert your desired image link
  • Config.DateFormat = '%d/%m/%Y [%X]' -- To change the date format check this website - https://www.lua.org/pil/22.1.html
  • -- To change a webhook color you need to set the decimal value of a color, you can use this website to do that - https://www.mathsisfun.com/hexadecimal-decimal-colors.html45518a
  • Config.CreateNewInvoiceWebhookColor = '16127'
  • Config.PayInvoiceWebhookColor = '65352'
  • Config.AutopayInvoiceWebhookColor = '4542858'
  • Config.CancelInvoiceWebhookColor = '9868950'

 

  • Idle: 0.00-0.01ms
  • Paying an invoice: 0.05ms
  • Cancelling an invoice: 0.05ms
  • Creating a new invoice: 0.05ms
  • Autopay/fees check: 0.00-0.01ms

 

  • No IP lock
  • Easy install
  • Nice 1

User Feedback

Recommended Comments

AnotherUser58

Posted

Hey, do you have the other scripts from OkOk, like the Bank Script?

craigt211

Posted

Keeps saying cannot find resource okok billing

callum nicolson

Posted

i was wondering if there was the qbcore verision as this is esx

 

jester223

Posted

On 5/1/2022 at 5:36 PM, craigt211 said:

Keeps saying cannot find resource okok billing

i think you both okok notify and textui most of their script i think require it now as dependcies

ddotx

Posted

dont fall for this its virus

image.png.8511e5df90dd492b2f35372cd9659092.png

 

i have successfully decrypted this. and let me tell you that it has virus inside of it!

 

ESX = nil
 
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
 
local Webhook = ''
local limiteTimeHours = Config.LimitDateDays*24
local hoursToPay = limiteTimeHours
local whenToAddFees = {}
 
for i = 1, Config.LimitDateDays, 1 do
    hoursToPay = hoursToPay - 24
    table.insert(whenToAddFees, hoursToPay)
end
 
ESX.RegisterServerCallback("okokBilling:GetInvoices", function(source, cb)
    local xPlayer = ESX.GetPlayerFromId(source)
 
    MySQL.Async.fetchAll('SELECT * FROM okokBilling WHERE receiver_identifier = @identifier ORDER BY CASE WHEN status = "unpaid" THEN 1 WHEN status = "autopaid" THEN 2 WHEN status = "paid" THEN 3 WHEN status = "cancelled" THEN 4 END ASC, id DESC', {
        ['@identifier'] = xPlayer.identifier
    }, function(result)
        local invoices = {}
 
        if result ~= nil then
            for i=1, #result, 1 do
                table.insert(invoices, result[i])
            end
        end
 
        cb(invoices)
    end)
end)
 
RegisterServerEvent("okokBilling:PayInvoice")
AddEventHandler("okokBilling:PayInvoice", function(invoice_id)
    local xPlayer = ESX.GetPlayerFromId(source)
 
    MySQL.Async.fetchAll('SELECT * FROM okokBilling WHERE id = @id', {
        ['@id'] = invoice_id
    }, function(result)
        local invoices = result[1]
        local playerMoney = xPlayer.getAccount('bank').money
        local webhookData = {
            id = invoices.id,
            player_name = invoices.receiver_name,
            value = invoices.invoice_value,
            item = invoices.item,
            society = invoices.society_name
        }
 
        invoices.invoice_value = math.ceil(invoices.invoice_value)
 
        if playerMoney == nil then
            playerMoney = 0
        end
 
        if playerMoney < invoices.invoice_value then
            TriggerClientEvent('okokNotify:Alert', xPlayer.source, "BILLING", "You don't have enough money!", 10000, 'error')
        else
            xPlayer.removeAccountMoney('bank', invoices.invoice_value)
            TriggerEvent("esx_addonaccount:getSharedAccount", invoices.society, function(account)
                if account ~= nil then
                    account.addMoney(invoices.invoice_value)
                end
            end)
 
            MySQL.Async.execute('UPDATE okokBilling SET status = @status, paid_date = CURRENT_TIMESTAMP WHERE id = @id', {
                ['@status'] = 'paid',
                ['@id'] = invoice_id
            })
 
            TriggerClientEvent('okokNotify:Alert', xPlayer.source, "BILLING", "Invoice successfully paid!", 10000, 'success')
 
            if Webhook ~= '' then
                payInvoiceWebhook(webhookData)
            end
        end
    end)
end)
 
RegisterServerEvent("okokBilling:CancelInvoice")
AddEventHandler("okokBilling:CancelInvoice", function(invoice_id)
    local xPlayer = ESX.GetPlayerFromId(source)
 
    MySQL.Async.fetchAll('SELECT * FROM okokBilling WHERE id = @id', {
        ['@id'] = invoice_id
    }, function(result)
        local invoices = result[1]
        local webhookData = {
            id = invoices.id,
            player_name = invoices.receiver_name,
            value = invoices.invoice_value,
            item = invoices.item,
            society = invoices.society_name,
            name = xPlayer.getName()
        }
        MySQL.Async.execute('UPDATE okokBilling SET status = "cancelled", paid_date = CURRENT_TIMESTAMP WHERE id = @id', {
            ['@id'] = invoice_id
        })
        TriggerClientEvent('okokNotify:Alert', xPlayer.source, "BILLING", "You have cancelled the invoice!", 10000, 'info')
        if Webhook ~= '' then
            cancelInvoiceWebhook(webhookData)
        end
    end)
end)
 
RegisterServerEvent("okokBilling:CreateInvoice")
AddEventHandler("okokBilling:CreateInvoice", function(data)
    local _source = ESX.GetPlayerFromId(source)
    local target = ESX.GetPlayerFromId(data.target)
    local webhookData = {}
 
    MySQL.Async.fetchAll('SELECT id FROM okokBilling WHERE id = (SELECT MAX(id) FROM okokBilling)', {}, function(result)
        webhookData = {
            id = result[1].id + 1,
            player_name = target.getName(),
            value = data.invoice_value,
            item = data.invoice_item,
            society = data.society_name,
            name = _source.getName()
        }
    end)
 
    if Config.LimitDate then
        MySQL.Async.insert('INSERT INTO okokBilling (receiver_identifier, receiver_name, author_identifier, author_name, society, society_name, item, invoice_value, status, notes, sent_date, limit_pay_date) VALUES (@receiver_identifier, @receiver_name, @author_identifier, @author_name, @society, @society_name, @item, @invoice_value, @status, @notes, CURRENT_TIMESTAMP(), DATE_ADD(CURRENT_TIMESTAMP(), INTERVAL @limit_pay_date DAY))', {
            ['@receiver_identifier'] = target.identifier,
            ['@receiver_name'] = target.getName(),
            ['@author_identifier'] = _source.identifier,
            ['@author_name'] = _source.getName(),
            ['@society'] = data.society,
            ['@society_name'] = data.society_name,
            ['@item'] = data.invoice_item,
            ['@invoice_value'] = data.invoice_value,
            ['@status'] = "unpaid",
            ['@notes'] = data.invoice_notes,
            ['@limit_pay_date'] = Config.LimitDateDays
        }, function(result)
            TriggerClientEvent('okokNotify:Alert', target.source, "BILLING", "You have just received a new invoice!", 10000, 'info')
            if Webhook ~= '' then
                createNewInvoiceWebhook(webhookData)
            end
        end)
    else
        MySQL.Async.insert('INSERT INTO okokBilling (receiver_identifier, receiver_name, author_identifier, author_name, society, society_name, item, invoice_value, status, notes, sent_date, limit_pay_date) VALUES (@receiver_identifier, @receiver_name, @author_identifier, @author_name, @society, @society_name, @item, @invoice_value, @status, @notes, CURRENT_TIMESTAMP(), DATE_ADD(CURRENT_TIMESTAMP(), INTERVAL @limit_pay_date DAY))', {
            ['@receiver_identifier'] = target.identifier,
            ['@receiver_name'] = target.getName(),
            ['@author_identifier'] = _source.identifier,
            ['@author_name'] = _source.getName(),
            ['@society'] = data.society,
            ['@society_name'] = data.society_name,
            ['@item'] = data.invoice_item,
            ['@invoice_value'] = data.invoice_value,
            ['@status'] = "unpaid",
            ['@notes'] = data.invoice_notes,
            ['@limit_pay_date'] = 'N/A'
        }, function(result)
            TriggerClientEvent('okokNotify:Alert', target.source, "BILLING", "You have just received a new invoice!", 10000, 'info')
            if Webhook ~= '' then
                createNewInvoiceWebhook(webhookData)
            end
        end)
    end
end)
ESX.RegisterServerCallback("okokBilling:GetSocietyInvoices", function(source, cb, society)
    local xPlayer = ESX.GetPlayerFromId(source)
 
    MySQL.Async.fetchAll('SELECT * FROM okokBilling WHERE society_name = @society ORDER BY id DESC', {
        ['@society'] = society
    }, function(result)
        local invoices = {}
        local totalInvoices = 0
        local totalIncome = 0
        local totalUnpaid = 0
        local awaitedIncome = 0
 
        if result ~= nil then
            for i=1, #result, 1 do
                table.insert(invoices, result[i])
                totalInvoices = totalInvoices + 1
 
                if result[i].status == 'paid' then
                    totalIncome = totalIncome + result[i].invoice_value
                elseif result[i].status == 'unpaid' then
                    awaitedIncome = awaitedIncome + result[i].invoice_value
                    totalUnpaid = totalUnpaid + 1
                end
            end
        end
        cb(invoices, totalInvoices, totalIncome, totalUnpaid, awaitedIncome)
    end)
end)
 
function checkTimeLeft()
    MySQL.Async.fetchAll('SELECT *, TIMESTAMPDIFF(HOUR, limit_pay_date, CURRENT_TIMESTAMP()) AS "timeLeft" FROM okokBilling WHERE status = @status', {
        ['@status'] = 'unpaid'
    }, function(result)
        for k, v in ipairs(result) do
            local invoice_value = v.invoice_value * (Config.FeeAfterEachDayPercentage / 100 + 1)
            if v.timeLeft < 0 and Config.FeeAfterEachDay then
                for k, vl in pairs(whenToAddFees) do
                    if v.fees_amount == k - 1 then
                        if v.timeLeft >= vl*(-1) then
                            MySQL.Async.execute('UPDATE okokBilling SET fees_amount = @fees_amount, invoice_value = @invoice_value WHERE id = @id', {
                                ['@fees_amount'] = k,
                                ['@invoice_value'] = v.invoice_value * (Config.FeeAfterEachDayPercentage / 100 + 1),
                                ['@id'] = v.id
                            })
                        end
                    end
                end
            elseif v.timeLeft >= 0 and Config.PayAutomaticallyAfterLimit then
                local xPlayer = ESX.GetPlayerFromIdentifier(v.receiver_identifier)
                local webhookData = {
                    id = v.id,
                    player_name = v.receiver_name,
                    value = v.invoice_value,
                    item = v.item,
                    society = v.society_name
                }
 
                if xPlayer == nil then
                    MySQL.Async.fetchAll('SELECT accounts FROM users WHERE identifier = @id', {
                        ['@id'] = v.receiver_identifier
                    }, function(account)
                        local playerAccount = json.decode(account[1].accounts)
                        playerAccount.bank = playerAccount.bank - invoice_value
                        playerAccount = json.encode(playerAccount)
 
                        MySQL.Async.execute('UPDATE users SET accounts = @playerAccount WHERE identifier = @target', {
                            ['@playerAccount'] = playerAccount,
                            ['@target'] = v.receiver_identifier
                        }, function(changed)
                            TriggerEvent("esx_addonaccount:getSharedAccount", v.society, function(account2)
                                if account2 ~= nil then
                                    account2.addMoney(invoice_value)
                                    MySQL.Async.execute('UPDATE okokBilling SET status = @paid, paid_date = CURRENT_TIMESTAMP() WHERE id = @id', {
                                        ['@paid'] = 'autopaid',
                                        ['@id'] = v.id
                                    })
                                end
                            end)
                        end)
                    end)
                else
                    xPlayer.removeAccountMoney('bank', invoice_value)
                    TriggerEvent('esx_addonaccount:getSharedAccount', v.society, function(account2)
                        if account2 ~= nil then
                            account2.addMoney(invoice_value)
                        end
                    end)
 
                    MySQL.Async.execute('UPDATE okokBilling SET status = @paid, paid_date = CURRENT_TIMESTAMP() WHERE id = @id', {
                        ['@paid'] = 'autopaid',
                        ['@id'] = v.id
                    })
                    if Webhook ~= '' then
                        autopayInvoiceWebhook(webhookData)
                    end
                end
            end
        end
    end)
    SetTimeout(30 * 60000, checkTimeLeft)
end
 
if Config.PayAutomaticallyAfterLimit then
    checkTimeLeft()
end
 
-------------------------- PAY INVOICE WEBHOOK
 
function payInvoiceWebhook(data)
    local information = {
        {
            ["color"] = Config.PayInvoiceWebhookColor,
            ["author"] = {
                ["icon_url"] = Config.IconURL,
                ["name"] = Config.ServerName..' - Logs',
            },
            ["title"] = 'Invoice #'..data.id..' has been paid',
            ["description"] = '**Receiver:** '..data.player_name..'\n**Value:** '..data.value..'\n**Item:** '..data.item..'\n**Beneficiary Society:** '..data.society,
 
            ["footer"] = {
                ["text"] = os.date(Config.DateFormat),
            }
        }
    }
    PerformHttpRequest(Webhook, function(err, text, headers) end, 'POST', json.encode({username = '', embeds = information}), {['Content-Type'] = 'application/json'})
end
 
-------------------------- CANCEL INVOICE WEBHOOK
 
function cancelInvoiceWebhook(data)
    local information = {
        {
            ["color"] = Config.CancelInvoiceWebhookColor,
            ["author"] = {
                ["icon_url"] = Config.IconURL,
                ["name"] = Config.ServerName..' - Logs',
            },
            ["title"] = 'Invoice #'..data.id..' has been cancelled',
            ["description"] = '**Cancelled by:** '..data.name..'\n\n**Receiver:** '..data.player_name..'\n**Value:** '..data.value..'\n**Item:** '..data.item..'\n**Society:** '..data.society,
 
            ["footer"] = {
                ["text"] = os.date(Config.DateFormat),
            }
        }
    }
    PerformHttpRequest(Webhook, function(err, text, headers) end, 'POST', json.encode({username = '', embeds = information}), {['Content-Type'] = 'application/json'})
end
 
-------------------------- CREATE NEW INVOICE WEBHOOK
 
function createNewInvoiceWebhook(data)
    local information = {
        {
            ["color"] = Config.CreateNewInvoiceWebhookColor,
            ["author"] = {
                ["icon_url"] = Config.IconURL,
                ["name"] = Config.ServerName..' - Logs',
            },
            ["title"] = 'Invoice #'..data.id..' has been created',
            ["description"] = '**Created by:** '..data.name..'\n**Society:** '..data.society..'\n\n**Receiver:** '..data.player_name..'\n**Value:** '..data.value..'\n**Item:** '..data.item,
 
            ["footer"] = {
                ["text"] = os.date(Config.DateFormat),
            }
        }
    }
    PerformHttpRequest(Webhook, function(err, text, headers) end, 'POST', json.encode({username = '', embeds = information}), {['Content-Type'] = 'application/json'})
end
 
-------------------------- AUTOPAY INVOICE WEBHOOK
 
function autopayInvoiceWebhook(data)
    local information = {
        {
            ["color"] = Config.AutopayInvoiceWebhookColor,
            ["author"] = {
                ["icon_url"] = Config.IconURL,
                ["name"] = Config.ServerName..' - Logs',
            },
            ["title"] = 'Invoice #'..data.id..' has been autopaid',
            ["description"] = '**Receiver:** '..data.player_name..'\n**Value:** '..data.value..'\n**Item:** '..data.item..'\n**Beneficiary Society:** '..data.society,
 
            ["footer"] = {
                ["text"] = os.date(Config.DateFormat),
            }
        }
    }
    PerformHttpRequest(Webhook, function(err, text, headers) end, 'POST', json.encode({username = '', embeds = information}), {['Content-Type'] = 'application/json'})
end
 
-- THATS IT HAVE A NICE DAY, REPLACE THIS CODE WITH whatever is in server.lua for YOUR own safety

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.


×
×
  • Create New...

Important Information

By continuing on Launcherleaks.net, you agree to our Terms of Use, Guidelines & Privacy Policy