Integration

Exports, events, and API reference

Integration

Client-Side Exports

OpenBilling

Opens the billing panel for the current player.

lua
exports['legacy-billing']:OpenBilling()

Usage Example:

lua
-- Open billing from another resource
TriggerEvent('some-event', function()
    exports['legacy-billing']:OpenBilling()
end)

Server-Side Exports

CreateBill

Programmatically create a bill from another resource.

lua
exports['legacy-billing']:CreateBill(src, targetId, amount, description, jobName, dueDate, metadata)

Parameters:

Parameter Type Required Description
src number Yes Player server ID of sender (use 0 for system bills)
targetId string Yes Target player's identifier
amount number Yes Bill amount in dollars
description string Yes Bill description text
jobName string Yes Job name (must exist in legacy_billing_jobs)
dueDate string No Due date in ISO format or nil
metadata table No Custom metadata (stored as JSON)

Returns: number - Bill ID on success, nil on failure

Examples:

lua
-- Police traffic fine
local billId = exports['legacy-billing']:CreateBill(
    source,
    targetIdentifier,
    5000,
    'Traffic Fine - Speeding in school zone',
    'police'
)

-- Hospital bill with metadata
local billId = exports['legacy-billing']:CreateBill(
    source,
    targetIdentifier,
    15000,
    'Emergency treatment and medication',
    'ambulance',
    '2025-06-15 23:59:59',
    { treatmentId = 'ER-4821', doctor = 'Dr. Smith' }
)

-- System-generated property tax
local billId = exports['legacy-billing']:CreateBill(
    0,  -- System sender
    playerIdentifier,
    2500,
    'Monthly property tax',
    'government'
)

Server Events

Bill Created

Fired when any bill is created.

lua
AddEventHandler('legacy-billing:billCreated', function(data)
    -- data.billId    (number) - The bill ID
    -- data.senderId  (string) - Sender identifier
    -- data.targetId  (string) - Target identifier
    -- data.amount    (number) - Bill amount
    -- data.jobName   (string) - Job that sent the bill
end)

Bill Paid

Fired when a bill receives a payment (full or partial).

lua
AddEventHandler('legacy-billing:billPaid', function(data)
    -- data.billId  (number) - The bill ID
    -- data.payerId (string) - Player who paid
    -- data.amount  (number) - Amount paid
    -- data.method  (string) - 'cash' or 'bank'
end)

Bill Cancelled

Fired when an admin cancels a bill.

lua
AddEventHandler('legacy-billing:billCancelled', function(data)
    -- data.billId      (number) - The bill ID
    -- data.cancelledBy (string) - Admin identifier
end)

Client Events

Bill Notifications

Receive real-time bill updates.

lua
RegisterNetEvent('legacy-billing:notify')
AddEventHandler('legacy-billing:notify', function(data)
    -- data.type      (string) - 'new_bill', 'bill_paid', 'bill_disputed'
    -- data.billId    (number) - Bill ID
    -- data.targetId  (string) - Target player identifier
    -- data.senderName (string) - Sender display name
    -- data.amount    (number) - Bill amount
end)

Bill Updates

Receive UI refresh signals.

lua
RegisterNetEvent('legacy-billing:billUpdated')
AddEventHandler('legacy-billing:billUpdated', function(data)
    -- data.billId (number) - Bill ID
    -- data.action (string) - 'payment', 'disputed', 'cancelled'
end)

Commands

Command Description Permission
/billing Opens the billing panel All players

Key binding is registered but unbound by default. Players can bind it in Settings > Key Bindings > FiveM.

Database Queries

For advanced integrations, you can query the database directly:

lua
-- Get unpaid bills for a player
local bills = MySQL.query.await(
    'SELECT * FROM legacy_bills WHERE target_id = ? AND status IN (?, ?, ?)',
    { identifier, 'unpaid', 'partial', 'overdue' }
)

-- Get total outstanding amount
local total = MySQL.scalar.await(
    'SELECT COALESCE(SUM(amount - amount_paid), 0) FROM legacy_bills WHERE target_id = ? AND status IN (?, ?, ?)',
    { identifier, 'unpaid', 'partial', 'overdue' }
)

-- Get job revenue statistics
local jobStats = MySQL.query.await(
    'SELECT status, COUNT(*) as count, SUM(amount) as total FROM legacy_bills WHERE sender_job = ? GROUP BY status',
    { jobName }
)

Job Management

Add billing jobs programmatically:

sql
INSERT INTO legacy_billing_jobs (job_name, job_label, can_bill, late_fee_pct)
VALUES ('mechanic', 'Mechanic Shop', 1, 2.50);

Or use the admin panel interface for easier management.

Webhook Integration

Configure Discord webhooks in config.lua for automated logging:

lua
Config.Webhooks = {
    BillCreated = 'https://discord.com/api/webhooks/YOUR_WEBHOOK_URL',
    BillPaid = 'https://discord.com/api/webhooks/YOUR_WEBHOOK_URL',
    -- ... other webhook types
}

Error Handling

All exports and callbacks include error handling:

lua
local billId = exports['legacy-billing']:CreateBill(
    source, targetId, amount, description, jobName
)

if billId then
    print('Bill created with ID: ' .. billId)
else
    print('Failed to create bill - check parameters and job configuration')
end

Enable `Config.Debug = true` for detailed error logging and troubleshooting information.