OrigenNetwork
Docs

Installation · origen_billing

1. Database

Run the following SQL in your database before starting the resource for the first time.

sql
CREATE TABLE IF NOT EXISTS `origen_billing_jobs` (
    `id`                    INT           NOT NULL AUTO_INCREMENT,
    `job_name`              VARCHAR(50)   NOT NULL,
    `label`                 VARCHAR(100)  NOT NULL DEFAULT '',
    `society_account`       VARCHAR(100)  NOT NULL DEFAULT '',
    `can_invoice`           TINYINT(1)    NOT NULL DEFAULT 1,
    `commission`            DECIMAL(5,2)  NOT NULL DEFAULT 0.00,
    `society_loss`          DECIMAL(5,2)  NOT NULL DEFAULT 0.00,
    `active`                TINYINT(1)    NOT NULL DEFAULT 1,
    `autopay_enabled`       TINYINT(1)    NOT NULL DEFAULT 0,
    `autopay_mode`          ENUM('immediate','delayed') NOT NULL DEFAULT 'immediate',
    `autopay_delay_hours`   INT           NOT NULL DEFAULT 0,
    `created_at`            TIMESTAMP     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`            TIMESTAMP     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uq_job_name` (`job_name`),
    KEY `idx_job_active` (`active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
CREATE TABLE IF NOT EXISTS `origen_billing_products` (
    `id`          INT           NOT NULL AUTO_INCREMENT,
    `job_name`    VARCHAR(50)   NOT NULL,
    `name`        VARCHAR(100)  NOT NULL,
    `description` VARCHAR(255)  NOT NULL DEFAULT '',
    `price`       DECIMAL(12,2) NOT NULL DEFAULT 0.00,
    `active`      TINYINT(1)    NOT NULL DEFAULT 1,
    `created_at`  TIMESTAMP     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `idx_product_job`    (`job_name`),
    KEY `idx_product_active` (`active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
CREATE TABLE IF NOT EXISTS `origen_billing_invoice_items` (
    `id`          INT           NOT NULL AUTO_INCREMENT,
    `invoice_id`  INT           NOT NULL,
    `product_id`  INT           DEFAULT NULL,
    `name`        VARCHAR(100)  NOT NULL,
    `price`       DECIMAL(12,2) NOT NULL DEFAULT 0.00,
    `quantity`    INT           NOT NULL DEFAULT 1,
    `subtotal`    DECIMAL(12,2) NOT NULL DEFAULT 0.00,
    PRIMARY KEY (`id`),
    KEY `idx_item_invoice` (`invoice_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
CREATE TABLE IF NOT EXISTS `origen_billing_invoices` (
    `id`                   INT           NOT NULL AUTO_INCREMENT,
    `target_identifier`    VARCHAR(100)  NOT NULL,
    `target_name`          VARCHAR(100)  NOT NULL DEFAULT '',
    `author_identifier`    VARCHAR(100)  NOT NULL,
    `author_name`          VARCHAR(100)  NOT NULL DEFAULT '',
    `job_name`             VARCHAR(50)   NOT NULL,
    `company_label`        VARCHAR(100)  NOT NULL DEFAULT '',
    `society_account`      VARCHAR(100)  NOT NULL,
    `amount`               DECIMAL(12,2) NOT NULL DEFAULT 0.00,
    `description`          VARCHAR(255)  NOT NULL DEFAULT '',
    `notes`                TEXT          DEFAULT NULL,
    `status`               ENUM('pending','paid','cancelled') NOT NULL DEFAULT 'pending',
    `commission_percent`   DECIMAL(5,2)  NOT NULL DEFAULT 0.00,
    `society_loss_percent` DECIMAL(5,2)  NOT NULL DEFAULT 0.00,
    `net_amount`           DECIMAL(12,2) NOT NULL DEFAULT 0.00,
    `commission_amount`    DECIMAL(12,2) NOT NULL DEFAULT 0.00,
    `society_amount`       DECIMAL(12,2) NOT NULL DEFAULT 0.00,
    `commission_status`    ENUM('none','pending','delivered') NOT NULL DEFAULT 'none',
    `commission_paid_at`   TIMESTAMP     NULL DEFAULT NULL,
    `paid_at`              TIMESTAMP     NULL DEFAULT NULL,
    `cancelled_by`         VARCHAR(100)  NULL DEFAULT NULL,
    `context_data`         TEXT          NULL DEFAULT NULL,
    `autopay_enabled`      TINYINT(1)    NOT NULL DEFAULT 0,
    `autopay_mode`         ENUM('immediate','delayed') NOT NULL DEFAULT 'immediate',
    `autopay_delay_hours`  INT           NOT NULL DEFAULT 0,
    `autopay_state`        ENUM('none','scheduled','retrying','retry_on_login','done') NOT NULL DEFAULT 'none',
    `autopay_attempts`     INT           NOT NULL DEFAULT 0,
    `autopay_next_try_at`  TIMESTAMP     NULL DEFAULT NULL,
    `autopay_last_error`   VARCHAR(64)   NULL DEFAULT NULL,
    `created_at`           TIMESTAMP     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `idx_target`     (`target_identifier`),
    KEY `idx_author`     (`author_identifier`),
    KEY `idx_job`        (`job_name`),
    KEY `idx_status`     (`status`),
    KEY `idx_commission` (`commission_status`),
    KEY `idx_autopay`    (`autopay_state`, `autopay_next_try_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

2. server.cfg

Add the resource after its dependencies:

cfg
ensure ox_lib
ensure oxmysql
ensure origen_billing

3. Initial job seed

The jobs listed in Config.AuthorizedJobs (inside config.lua) are seed data only. They are inserted into the database the first time the resource starts — if the job does not already exist.

After the first start, all job management is done through the in-game admin panel (/billingadmin). Changes to Config.AuthorizedJobs will not overwrite existing database records.

To reset a job to its seed values, delete its row from origen_billing_jobs and restart the resource.


4. Discord webhooks (optional)

Open svconfig.lua and set enabled = true along with your webhook URLs:

lua
return {
    enabled = true,
    webhooks = {
        ['invoice-created']   = 'https://discord.com/api/webhooks/...',
        ['invoice-paid']      = 'https://discord.com/api/webhooks/...',
        ['invoice-cancelled'] = 'https://discord.com/api/webhooks/...',
        ['commission-paid']   = 'https://discord.com/api/webhooks/...',
    },
}