> For the complete documentation index, see [llms.txt](https://docs.dsyncstudios.store/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dsyncstudios.store/products/dsync-banking/configuration-reference.md).

# Configuration Reference

## Configuration Reference

Every setting lives in `config.lua`. This page documents each section in the order it appears in the file.

### Why money is stored in cents

Every monetary value — in the database, in exports, in every config option that takes an amount — is an **integer number of cents**. `$10.00` is `1000`.

This isn't arbitrary. FiveM's Lua runtime has no true integer type; every number is a 64-bit float. Floats cannot represent most decimal fractions exactly (`0.1 + 0.2 ~= 0.30000000000000004` in Lua, same as JavaScript or any other IEEE-754 language). If balances were stored as dollars-with-cents floats, repeated additions/subtractions across thousands of transactions would accumulate rounding error, and ledgers would eventually stop reconciling. Storing everything as whole-number cents sidesteps the problem entirely — integer arithmetic on cents is always exact. The UI divides by 100 only at the final display step.

### General

```lua
multiJob = false,      -- QBCore only — see the note below
progressbar = 'circle', -- 'circle' or 'rectangle'
currency = 'USD',       -- USD, EUR, GBP, etc. — display only
```

`multiJob` enables support for the multi-job pattern used by some QBCore phone resources, where a player can hold more than one job simultaneously. Leave this `false` unless your server specifically supports multiple concurrent jobs.

### ATM models

```lua
atms = {
    `prop_atm_01`,
    `prop_atm_02`,
    `prop_atm_03`,
    `prop_fleeca_atm`
},
```

The list of prop models that get an ATM interaction. Add or remove models to match the map you're running.

### Bank ped locations

```lua
peds = {
    [1] = { model = 'u_m_m_bankman', coords = vector4(x, y, z, heading), createAccounts = true },
    ...
}
```

Each entry spawns a bank teller NPC. `createAccounts = true` additionally lets players create **shared accounts** at that specific ped — useful for restricting shared-account creation to a small number of "main branch" locations rather than every bank ped.

### Cache

```lua
cache = {
    maxPlayers = 600,
    maxAccounts = 200,
    ttl = 900,
    dashboardTtl = 300,
},
```

An in-memory LRU cache collapses the \~12 queries fired on every bank-UI open down to zero on a cache hit. **The player's own bank/cash balance is never served from this cache** — it's always read live from the framework on every open, so a player's own money is never stale. The cache only governs how quickly *external* changes (a colleague's society deposit, a job change) become visible; `dashboardTtl` is that window in seconds. Any mutation a player makes themselves busts their own cache entry immediately.

### Loans

```lua
loans = {
    enabled = true,
    tiers = {
        { minScore = 750, apr = 3.5,  maxAmount = 50000000 },
        { minScore = 650, apr = 5.0,  maxAmount = 25000000 },
        { minScore = 500, apr = 8.5,  maxAmount = 10000000 },
        { minScore = 400, apr = 12.0, maxAmount = 5000000  },
    },
    terms = { 1, 6, 12, 24 },

    autoDeduct = true,
    deductionGap = 30,
    deductionCheckInterval = 300,
    maxMissedPayments = 3,
    missedPaymentPenalty = 25,
    bounceCharge = 50000,

    debugMode = false,
},
```

* **`tiers`** — checked top-to-bottom; the first tier whose `minScore` the player's credit score meets or exceeds determines their APR and maximum loan amount (in cents).
* **`terms`** — the list of installment-count options offered when applying.
* **`autoDeduct`** — when `true`, a background worker automatically debits each active loan's installment from the borrower's **bank balance** every `deductionGap` (days), advancing the due date. The borrower must be online and solvent for the deduction to succeed.
* **`deductionCheckInterval`** — how often (seconds) the worker scans for due installments. This query is cheap and indexed; it's safe to leave at 300s even on a busy server.
* **`maxMissedPayments`** — consecutive missed installments before a loan is marked `defaulted` (credit score penalty of −100 on top of the per-miss penalty).
* **`missedPaymentPenalty`** — credit-score points lost for each missed installment.
* **`bounceCharge`** — cents added to what the borrower owes every time an installment bounces (can't be collected). Shown separately in the Loans tab as an itemized charge, and collected alongside the next successful payment — similar to a real bank's bounced-payment fee. `0` disables this entirely.
* **`debugMode`** — **testing only.** When `true`, `deductionGap` is interpreted as **minutes** instead of days, and the scan interval is clamped to 15 seconds, so you can watch a full loan lifecycle (installment → miss → bounce charge → default) play out in minutes rather than waiting for real days to pass. **Always set this to `false` before going live** — it will otherwise deduct installments every few minutes in production.

### Savings

```lua
savings = {
    enabled = true,
    interestRate = 0.02,
    interestInterval = 86400,
    taxRate = 0,
    maxAccounts = 3,
},
```

`enabled = false` hides the Savings tab entirely and rejects every related server callback — a clean way to disable the feature without touching data. Interest accrues every `interestInterval` seconds at `interestRate` (a fraction, so `0.02` = 2% annual), optionally taxed by `taxRate` before it's credited.

### Bank cards

```lua
cards = {
    enabled = true,
    mode = 'item',
    metadata = false,
    maxCardsPerPlayer = 1,
    defaultDailyLimit = 1000000,
    types = { 'debit', 'gold', 'platinum' },
    itemName = 'bank_card',
    reissueFee = 50000,
    freezeCooldown = 30,
},
```

* **`mode`** — `'virtual'` means cards exist only in the UI (no inventory item; ATM access is gated purely by ownership + PIN). `'item'` additionally requires holding a physical `bank_card` item — see the Bank Card Item page under Integrations.
* **`metadata`** — item mode only. `false` (default): only the original owner's card authenticates at an ATM. `true`: **any** holder of the item can authenticate, and a successful login opens the **card owner's** account — i.e. a "borrowed card" scenario (gifting, theft roleplay, joint access).
* **`defaultDailyLimit`** — cents a newly issued card may withdraw per day at ATMs. `0` means unlimited. This cap is enforced server-side on every ATM withdrawal and resets automatically at the start of a new calendar day.
* **`reissueFee`** — cents charged when a player reissues a lost/stolen card (cancels the old card, issues a new number, same PIN prompt).
* **`freezeCooldown`** — seconds a player must wait between freezing and unfreezing (or vice-versa) the *same* card. Prevents rapid toggle-spam hitting the database; purely an anti-abuse guard, not a security boundary.

### Credit score

```lua
creditScore = {
    startingScore = 650,
    minScore = 300,
    maxScore = 850,
    ratings = {
        { min = 750, label = 'Excellent', color = '#2ECC71' },
        { min = 700, label = 'Very Good', color = '#27AE60' },
        { min = 650, label = 'Good',      color = '#F39C12' },
        { min = 550, label = 'Fair',       color = '#E67E22' },
        { min = 300, label = 'Poor',       color = '#E74C3C' },
    },
},
```

A FICO-style 300–850 score. `ratings` maps score ranges to the label/color shown in the UI (checked top-to-bottom, first match wins).

### Bills & payments

```lua
bills = {
    enabled = true,
    overdueCheckInterval = 3600,
},
```

Governs fines, invoices, and tax bills issued via the server exports. `overdueCheckInterval` is how often (seconds) the system checks for bills that have passed their due date.

### Society accounts

```lua
society = {
    defaultPermissions = {
        canView = 0, canDeposit = 0, canWithdraw = 3, canManage = 4, canViewLogs = 2,
    },
    jobs = { --[[ police = { canWithdraw = 4, canManage = 4 }, ]] },
    gangs = { --[[ ballas = { canWithdraw = 4 }, ]] },
    respectFreeze = true,
    withdrawLimits = {
        perTransaction = { --[[ [3] = 5000000, [8] = -1, ]] },
        perDay         = { --[[ [3] = 20000000, [8] = -1, ]] },
    },
},
```

Society accounts are job/gang treasuries. Permission values are **minimum job grade required** for each action (`0` = every grade, `4` = grade 4+ only).

* **`defaultPermissions`** — applied to every job/gang unless overridden.
* **`jobs` / `gangs` — the allowlist.** If either table is **non-empty**, only the jobs/gangs listed inside it get a society account at all; every other job/gang gets none, and no one can pay into them. Leave a table **empty** (the default) to keep the original behavior: every job/gang automatically gets a treasury using `defaultPermissions`. The two lists are independent — you can restrict jobs while leaving gangs unrestricted, or vice versa. Each entry may override just the permission keys it needs to change; anything omitted falls back to `defaultPermissions`.
* **`respectFreeze`** — when `true`, a frozen society account (`is_frozen = 1` in the database) blocks all withdrawals regardless of grade.
* **`withdrawLimits`** — optional spending caps layered on top of the grade gate. `perTransaction` and `perDay` are keyed by grade; the cap of the highest configured grade at or below the member's own grade applies, so higher ranks can be given higher (or unlimited, `-1`) limits. Leave a table empty to disable that particular check.

### Shared accounts

```lua
shared = {
    enabled = true,
    maxAccountsPerPlayer = 3,
    requireAcceptance = true,
    acceptanceTimeout = 30,
    defaultMemberPermissions = {
        canDeposit = true,
        canWithdraw = false,
        canViewLogs = true,
    },
},
```

Shared accounts are player-created pooled accounts (family funds, business accounts). `enabled = false` disables the entire feature (hides the tab, rejects every related callback) without touching existing data. Invites require acceptance within `acceptanceTimeout` seconds unless `requireAcceptance` is `false`. New members receive `defaultMemberPermissions` until the owner adjusts them individually.

### Scheduled transfers

```lua
scheduledTransfers = {
    minIntervalDays = 1,
    maxIntervalDays = 30,
    maxPerPlayer    = 10,
    checkInterval   = 60,
    testMode        = false,
},
```

Recurring peer-to-peer payments (rent, payroll). A schedule only fires when **both** the owner and recipient are online. `minIntervalDays`/`maxIntervalDays` bound what a player can configure; `checkInterval` is how often (seconds) the executor scans for due schedules. `testMode` (testing only) reinterprets the configured interval as **minutes** instead of days — set back to `false` before going live.

### Anti-spam

```lua
financialCooldownMs = 500,
```

Minimum milliseconds between a single player's money-moving actions (deposit, withdraw, transfer, card changes, etc.). This is enforced **in memory before any database query runs**, so an autoclicker or a crafted repeated NUI call gets dropped instantly instead of flooding the database. `0` disables it — not recommended.

### Audit logging

See the dedicated Audit Logging page under Integrations for the full `logging` block (driver selection, Datadog setup, Discord webhook routing, and category filtering).

### Transaction pagination

```lua
transactionsPerPage = 20,
```

Rows per page in the Transactions tab and paginated log views.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.dsyncstudios.store/products/dsync-banking/configuration-reference.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
