Installation
How to install and set up legacy-billing
Dependencies#
| Resource | Purpose |
|---|---|
| ox_lib | Callbacks, notifications, UI utilities |
| oxmysql | Database operations |
| legacy-lib | Framework abstraction (QBCore, ESX, etc.) |
All dependencies must be started before legacy-billing in your server.cfg.
Database Setup#
Run the following SQL in your database. This creates all required tables and seeds default billing jobs (police, ambulance, mechanic).
Warning: The schema contains
DROP TABLEstatements. If you have existing data, remove those lines before importing.
DROP TABLE IF EXISTS `legacy_bill_payments`;
DROP TABLE IF EXISTS `legacy_bill_disputes`;
DROP TABLE IF EXISTS `legacy_bills`;
DROP TABLE IF EXISTS `legacy_bill_templates`;
DROP TABLE IF EXISTS `legacy_billing_jobs`;
CREATE TABLE `legacy_billing_jobs` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`job_name` VARCHAR(60) NOT NULL UNIQUE,
`job_label` VARCHAR(100) NOT NULL,
`can_bill` TINYINT(1) DEFAULT 1,
`late_fee_pct` DECIMAL(5,2) DEFAULT 0.00,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_job_name` (`job_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `legacy_bills` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`sender_id` VARCHAR(60) NOT NULL,
`sender_name` VARCHAR(100) NOT NULL,
`sender_job` VARCHAR(60) NOT NULL,
`sender_job_label` VARCHAR(100) NOT NULL,
`target_id` VARCHAR(60) NOT NULL,
`target_name` VARCHAR(100) NOT NULL,
`amount` INT NOT NULL,
`amount_paid` INT DEFAULT 0,
`description` VARCHAR(500) NOT NULL,
`status` VARCHAR(20) DEFAULT 'unpaid',
`due_date` TIMESTAMP NULL DEFAULT NULL,
`late_fee_applied` TINYINT(1) DEFAULT 0,
`late_fee_amount` INT DEFAULT 0,
`metadata` JSON DEFAULT ('{}'),
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`paid_at` TIMESTAMP NULL DEFAULT NULL,
`cancelled_at` TIMESTAMP NULL DEFAULT NULL,
INDEX `idx_target_id` (`target_id`),
INDEX `idx_sender_id` (`sender_id`),
INDEX `idx_sender_job` (`sender_job`),
INDEX `idx_status` (`status`),
INDEX `idx_due_date` (`due_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `legacy_bill_payments` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`bill_id` INT NOT NULL,
`payer_id` VARCHAR(60) NOT NULL,
`amount` INT NOT NULL,
`method` VARCHAR(20) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_bill_id` (`bill_id`),
FOREIGN KEY (`bill_id`) REFERENCES `legacy_bills`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `legacy_bill_disputes` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`bill_id` INT NOT NULL,
`disputer_id` VARCHAR(60) NOT NULL,
`disputer_name` VARCHAR(100) NOT NULL,
`reason` VARCHAR(500) NOT NULL,
`status` VARCHAR(20) DEFAULT 'open',
`resolved_by` VARCHAR(60) DEFAULT NULL,
`resolved_by_name` VARCHAR(100) DEFAULT NULL,
`resolution` VARCHAR(500) DEFAULT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`resolved_at` TIMESTAMP NULL DEFAULT NULL,
INDEX `idx_bill_id` (`bill_id`),
FOREIGN KEY (`bill_id`) REFERENCES `legacy_bills`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `legacy_bill_templates` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`job_name` VARCHAR(60) NOT NULL,
`name` VARCHAR(100) NOT NULL,
`amount` INT NOT NULL,
`description` VARCHAR(500) NOT NULL,
`created_by` VARCHAR(60) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_job_name` (`job_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `legacy_billing_jobs` (`job_name`, `job_label`, `late_fee_pct`) VALUES
('police', 'Police Department', 5.00),
('ambulance', 'Emergency Medical Services', 0.00),
('mechanic', 'Mechanic', 0.00);
server.cfg#
Add the following to your server.cfg, ensuring the dependencies are started first:
ensure legacy-lib
ensure ox_lib
ensure oxmysql
ensure legacy-billing