X-Banking einrichten
Vollständiges Bankensystem für ESX Legacy: Konto mit IBAN, Sparkonto mit Zinsen, Festgeld und Sparzielen, Kredite mit Bonitätsprüfung, Aktienmarkt, Rechnungen, Firmenkonten, Justiz-Zugriff und ein nachgebauter Geldautomat. Diese Anleitung führt dich vom Download bis zum eingerichteten Server.
Die Oberfläche kannst du vorher in der Live-Demo im Browser durchklicken.
Voraussetzungen
- FiveM Server mit aktuellem Artifact
es_extended(ESX Legacy)oxmysql- MySQL oder MariaDB
Optional, jeweils über die Config zuschaltbar:
ox_inventoryfür die Bankkarte als Itemox_targetoderqtargetstatt der Taste am NPC und am AutomatenokokBillingals Rechnungssystem anstelle des eingebautenlb-phoneoderqs-smartphonefür die Handy-App (eigene Resource, siehe unten)esx_addonaccountfür Job-Konten. Fehlt es, greift X-Banking direkt aufaddon_account_datazu.
Installation
- Lade
x-bankingaus dem Cfx.re Portal herunter. - Entpacke den Ordner nach
resources/[x-solution]/x-banking. - Importiere
sql/install.sqlin deine Datenbank. Die Datei legt alle benötigten Tabellen an und ist wiederholbar ausführbar (CREATE TABLE IF NOT EXISTS). - Trage die Resource in deiner
server.cfgein, nach ESX und oxmysql:
ensure oxmysql
ensure es_extended
ensure x-banking
- Server neu starten.
Bankkarte als Item
Nur nötig, wenn du Config.Card.enabled nutzt. Öffne ox_inventory/data/items.lua und füge den Eintrag aus install/ox_inventory_items.lua ein:
['bankcard'] = {
label = 'Bankkarte',
weight = 10,
stack = false,
close = true,
description = 'Deine persönliche Bankkarte',
},
Optional legst du ein Bild bankcard.png nach ox_inventory/web/images/. Steht Config.Card.required auf true, kommt ohne Karte im Inventar weder der Schalter noch der Automat auf.
Update auf eine neue Version
Führe sql/install.sql nach jedem Update erneut aus. Neue Funktionen bringen regelmäßig neue Tabellen mit, und ohne sie startet das jeweilige Modul nicht.
Bedienung
| Ort | Bedienung | Was passiert |
|---|---|---|
| Bankschalter | Taste E am NPC |
Volle Bank-Oberfläche |
| Geldautomat | Taste E am Prop |
Automaten-Terminal |
| Geldautomat | Taste G am Prop |
ATM-Hacking, sofern freigeschaltet |
| Bankkarte | Item benutzen | Öffnet die Bank |
| Nummernkonto | Taste E am versteckten Kontakt |
Schweizer Konto |
Die Taste am Schalter und Automaten stellst du über Config.OpenKey ein (Standard 38, also E). Es gibt keinen /bank-Befehl — der Zugang läuft bewusst nur über NPC, Automat und Karte.
| Befehl | Rechte | Wirkung |
|---|---|---|
/xbank |
Admin | Verwaltung und Wirtschafts-Statistik |
/doj |
Justiz | Konten suchen, sperren, beschlagnahmen |
Beide Namen änderst du in Config.AdminCommand und Config.DOJ.command.
Wichtige Einstellungen
Alles liegt in shared/config.lua. Diese Dateien sind bewusst nicht verschlüsselt und bleiben deine:
| Datei | Wofür |
|---|---|
shared/config.lua |
Alle Einstellungen |
shared/locales.lua |
Sämtliche Texte, Deutsch und Englisch |
sql/install.sql |
Datenbankschema zum Nachlesen |
install/ox_inventory_items.lua |
Vorlage für die Bankkarte |
Der restliche Code ist über den Cfx.re-Escrow geschützt. Sicher deine angepassten Dateien vor einem Update trotzdem — ein überschriebener Ordner ist schnell passiert.
Sprache und Texte
Config.Locale = 'de'
Config.Debug = false
shared/locales.lua bringt de und en mit. Jeder Text steht dort als Schlüssel, du kannst also einzelne Sätze ändern, ohne etwas anderes anzufassen. Platzhalter wie %s müssen erhalten bleiben, sonst fehlt im Text der Betrag oder der Name. Eine eigene Sprache legst du als weiteren Block Locales['fr'] = { ... } an und trägst das Kürzel in Config.Locale ein.
Config.Debug = true schreibt zusätzliche Meldungen in die Serverkonsole. Für den Livebetrieb aus lassen.
Grundlagen
Config.BankAccount = 'bank'
Config.CashAccount = 'money'
Config.Currency = '$'
Config.IBANPrefix = 'XB'
Config.BankAccount ist der entscheidende Wert: X-Banking rechnet direkt auf dem ESX-Konto bank. Damit bleibt jedes andere Script, das dieses Konto liest oder schreibt, automatisch synchron. Spar-, Kredit- und Depotdaten liegen in eigenen Tabellen.
Standorte und Zugang
Config.TargetSystem = 'none'
Config.OpenKey = 38
Config.TargetSystem akzeptiert 'none', 'ox_target' oder 'qtarget'. Bei 'none' erscheint ein Hinweis mit Tastendruck, sonst wird der NPC beziehungsweise das ATM-Prop als Ziel registriert.
Config.Banks enthält die acht Standorte mit Koordinaten und Blip-Einstellungen, Config.NPC das Modell und Szenario des Bankangestellten, Config.Blip das Kartensymbol. Config.ATM.models listet die Props, an denen der Automat aufgeht.
Ein- und Auszahlungen
Config.Deposit = {
enabled = true,
min = 1,
max = 10000000,
}
Config.Withdraw = {
enabled = true,
min = 1,
max = 10000000,
}
min und max gelten pro Vorgang. Mit enabled = false blendet der Automat den jeweiligen Menüpunkt aus; am Bankschalter bleibt der Knopf sichtbar, der Server lehnt den Vorgang aber ab und meldet es dem Spieler. Nützlich, wenn Bargeld auf deinem Server nur über bestimmte Wege ins Konto soll.
Überweisungen
Config.Transfer = {
enabled = true,
min = 1,
max = 5000000,
fee = 0.0,
feeMin = 0,
byIBAN = true,
byId = true,
confirmAbove = 100000,
}
fee ist ein Prozentwert, feeMin eine Mindestgebühr in bar. Ab confirmAbove fragt die Oberfläche vor dem Absenden nach. Überweisungen per IBAN erreichen auch Offline-Spieler sowie Job-Konten (XJ) und Gemeinschaftskonten (XC).
Sparkonto
Config.Savings = {
enabled = true,
interestRate = 0.3,
intervalHours = 24,
maxBalance = 50000000,
maxInterestBalance = 1000000,
minDeposit = 100,
withdrawFee = 0.0,
}
interestRate ist der Zinssatz pro Intervall in Prozent. Zinsen laufen offline weiter und werden beim nächsten Login nachberechnet.
maxInterestBalance ist eine Sicherung, keine Schikane: nur bis zu diesem Guthaben wird verzinst. Ohne die Grenze können Spieler einen Großkredit aufnehmen, ihn aufs Sparkonto legen und mehr Zinsen kassieren als der Kredit kostet.
Der Sparplan unter Config.Savings.plan bucht automatisch in festen Intervallen vom Konto aufs Sparkonto. intervals sind die auswählbaren Abstände in Stunden (24 = täglich, 168 = wöchentlich, 720 = monatlich), maxPlans begrenzt, wie viele Pläne ein Spieler gleichzeitig laufen lassen darf.
Festgeld und Sparziele
Config.FixedDeposit = {
enabled = true,
dayHours = 24,
minAmount = 1000,
allowEarly = true,
options = {
{ days = 7, rate = 3.0 },
{ days = 14, rate = 7.0 },
{ days = 30, rate = 18.0 },
},
}
Config.SavingsGoals = {
enabled = true,
maxGoals = 6,
}
Festgeld ist fest angelegtes Geld: Der Spieler wählt eine Laufzeit aus options und bekommt am Ende rate Prozent Zinsen auf den gesamten Betrag — deutlich mehr als das normale Sparkonto, dafür ist das Geld bis zur Fälligkeit weg. dayHours legt fest, wie lang ein „Tag" in Stunden ist; damit stellst du die Laufzeiten auf deinen Servertakt ein. Steht allowEarly auf true, darf vorzeitig aufgelöst werden — dann gibt es die Einlage zurück, aber keine Zinsen.
Achte darauf, dass die Festgeld-Sätze zu deinen Kreditzinsen passen. Liegt die 30-Tage-Rendite über den Kosten eines Großkredits, ist die Kombination aus Kredit und Festgeld wieder ein Selbstläufer.
Sparziele sind reine Spardosen ohne Zinsen: Name, Zielbetrag, Fortschrittsbalken. maxGoals begrenzt die Anzahl pro Spieler. Beim Löschen eines Ziels geht das Guthaben zurück aufs Bankkonto, es kann also nichts verloren gehen.
Kredite
Config.Loans = {
offers = {
{ id = 'mikro', label = 'Mikrokredit', min = 1000, max = 50000, rate = 5.0, term = 7 },
{ id = 'standard', label = 'Standardkredit', min = 50000, max = 250000, rate = 8.0, term = 14 },
{ id = 'premium', label = 'Großkredit', min = 250000, max = 1000000, rate = 12.0, term = 30 },
},
installmentIntervalHours = 24,
maxActiveLoans = 1,
maxMissed = 3,
penaltyPerMiss = 5.0,
seizeOrder = { 'bank', 'savings' },
blockOnDefault = true,
}
term ist die Anzahl der Raten, installmentIntervalHours der Abstand dazwischen. Raten werden auch bei Offline-Spielern abgebucht.
Reicht das Geld nicht, zählt X-Banking eine Mahnstufe hoch und pfändet in der Reihenfolge aus seizeOrder. Nach maxMissed gilt der Kredit als geplatzt. Er wird weiter eingezogen, zählt weiter aufs Limit und sperrt neue Kredite, solange blockOnDefault aktiv ist. Ohne diese drei Punkte lohnt es sich, einen Kredit einfach nicht zu bezahlen.
Der Kreditrahmen ergibt sich aus Config.Loans.credit: flat plus factor mal Vermögen, abzüglich offener Schulden. Die Bonität samt Faktoren sieht der Spieler im Kredite-Tab.
Aktienmarkt
Config.Stocks = {
tickSeconds = 90,
persistSeconds = 600,
tradeFee = 0.5,
maxPriceFactor = 25,
symbols = { ... },
}
Die Kurse berechnet der Server (Random Walk je Symbol nach volatility) und schickt sie nur an offene Oberflächen. maxPriceFactor deckelt, wie weit ein Kurs vom Startwert weglaufen darf.
Dazu kommen Dividenden (Config.Stocks.dividends), Limit- und Stop-Orders (Config.Stocks.orders) sowie Marktnachrichten (Config.Stocks.news), die den Kurs tatsächlich bewegen — chance ist die Wahrscheinlichkeit pro Tick, impact die Kursänderung in Prozent.
Neue Werte trägst du einfach in symbols ein:
{ symbol = 'MEIN', name = 'Meine Firma AG', start = 100.00, volatility = 4.0, dividend = 0.3 },
Rechnungen, Anfragen und Daueraufträge
Config.Invoices = {
enabled = true,
maxOpen = 20,
okokBilling = true,
okokResource = 'okokBilling',
}
Steht okokBilling auf true und läuft die Resource, gehen erstellte Rechnungen dorthin, und der Rechnungen-Tab zeigt einen Knopf, der okokBilling öffnet. Läuft sie nicht, fällt X-Banking automatisch auf das eigene System zurück. Achtung: Für okokBilling muss der Empfänger online sein.
Config.Requests regelt Zahlungsanfragen zwischen Spielern, Config.StandingOrders wiederkehrende Überweisungen. checkMinutes bestimmt, wie oft der Server fällige Aufträge prüft.
Job- und Gemeinschaftskonten
Config.Society = {
ibanPrefix = 'XJ',
bossGrades = { 'boss' },
depositAnyMember = true,
withdrawBossOnly = true,
allowTransferIn = true,
payroll = { enabled = true, maxPerPay = 1000000 },
}
Config.Company = {
maxAccounts = 2,
maxMembers = 10,
createCost = 50000,
membersDeposit = true,
ibanPrefix = 'XC',
}
Job-Konten spiegeln die ESX-Society deines Jobs und bekommen eine eigene IBAN, damit man ihnen Geld überweisen kann. Heißt euer Chef-Grade anders als boss, trag ihn in bossGrades ein — sonst kommt niemand ans Geld.
Gemeinschaftskonten gründen Spieler selbst gegen createCost, mit den Rollen Inhaber, Manager und Mitglied.
Justiz und Kontosperre
Config.DOJ = {
enabled = true,
mode = 'group',
ace = 'x-banking.doj',
group = 'admin',
command = 'doj',
seizeTo = 'society_government',
}
mode ist entweder 'group' (prüft die ESX-Gruppe aus group) oder 'ace' (prüft die Berechtigung aus ace). Eine Sperre blockiert jeden Geldabfluss: Auszahlung, Überweisung, Sparen, Kreditrückzahlung, Aktienkauf, Rechnungen, Firmeneinzahlungen. Beschlagnahmtes Geld landet auf dem Konto aus seizeTo.
Schweizer Nummernkonto
Config.Swiss = {
enabled = true,
fee = 10.0,
minDeposit = 1000,
maxBalance = 100000000,
npc = { model = 's_m_m_highsec_01', coords = vec4(...), label = 'Kontakt', blip = false },
}
Ein bewusst verstecktes Konto ohne Blip. Es taucht in der Justiz-Suche nicht auf und lässt sich weder sperren noch beschlagnahmen — dafür kostet jede Einzahlung fee Prozent. Wenn du kein Schlupfloch für Schwarzgeld willst, setz enabled = false.
Kontoauszug, Verlauf und Vermögen
Config.Statement = {
enabled = true,
webhook = '',
last = 15,
cooldownSeconds = 30,
}
Config.History = {
showLast = 25,
}
Config.Networth = {
enabled = true,
snapshotHours = 6,
keep = 30,
}
Config.UI = {
sounds = true,
}
Config.Statement ist der Kontoauszug, den ein Spieler selbst exportiert: last ist die Zahl der Buchungen darauf, cooldownSeconds verhindert Spam, webhook schickt eine Kopie in einen Discord-Kanal. Lässt du webhook leer, bleibt der Auszug im Spiel.
Config.History.showLast bestimmt, wie viele Buchungen die Oberfläche lädt, Config.Requests.showLast dasselbe für Zahlungsanfragen. Beides sind Anzeigegrenzen — in der Datenbank bleibt alles stehen.
Config.Networth zeichnet in Abständen von snapshotHours das Gesamtvermögen auf und hebt keep Messpunkte auf. Daraus entsteht die Kurve auf der Startseite der Bank. Mit enabled = false verschwindet die Kurve, gespart wird dann nichts mehr.
Config.UI.sounds schaltet die Klicks und Bestätigungstöne der Oberfläche ab.
Verwaltung und Protokolle
Config.AdminMode = 'group'
Config.AdminGroup = 'admin'
Config.AdminAce = 'x-banking.admin'
Config.AdminCommand = 'xbank'
Wie beim DOJ entscheidet AdminMode zwischen ESX-Gruppe und ACE-Berechtigung.
Config.Webhooks schickt Überweisungen, Ein- und Auszahlungen, Kredite, Aktiengeschäfte und Admin-Eingriffe an Discord. Trag pro Bereich eine Webhook-URL ein und setz enabled = true. Config.Statement.webhook ist davon getrennt und bekommt die Kontoauszüge, die Spieler selbst exportieren.
Der Geldautomat
Am Automaten öffnet sich standardmäßig kein Bankfenster, sondern ein nachgebautes Terminal mit Gehäuse, Tastatur, Geldschacht und Quittungsdrucker.
Config.ATM.machine = {
enabled = true,
brand = 'FLEECA BANK',
headline = 'Auszahlungen',
provider = 'SIX',
providerSub = 'Payment Services',
notes = { 20, 50, 100, 200, 500, 1000 },
transfer = true,
deposit = true,
history = true,
receiptCount = 6,
}
notes sind die Schnellbeträge auf dem Auszahlungs-Bildschirm, receiptCount die Zeilenzahl auf der Quittung. Mit transfer, deposit und history schaltest du einzelne Menüpunkte ab. Setzt du enabled = false, öffnet am Automaten wieder die normale Bank-Oberfläche.
PIN
Config.ATM.pin = {
enabled = true,
length = 4,
maxFails = 3,
lockSeconds = 300,
}
Beim ersten Automatenbesuch legt der Spieler eine PIN fest. Nach maxFails Fehlversuchen ist der Zugang für lockSeconds gesperrt. Am Bankschalter wird nie nach der PIN gefragt.
ATM-Hacking
Config.ATM.robbery = {
enabled = true,
hackControl = 47,
atmCooldownMinutes = 30,
playerCooldownMinutes = 15,
minReward = 500,
maxReward = 5000,
rounds = 4,
requiredHits = 3,
minCops = 0,
copJobs = { 'police', 'sheriff', 'lspd', 'bcso' },
alertChance = 100,
}
hackControl ist die Taste (Standard 47, also G). Das Minispiel läuft über rounds Runden, von denen requiredHits sitzen müssen. Die Cooldowns gelten getrennt pro Automat und pro Spieler. Mit minCops verlangst du eine Mindestzahl an Polizisten im Dienst, alertChance ist die Wahrscheinlichkeit in Prozent, dass ein Blip bei den Jobs aus copJobs gesetzt wird.
Handy-App
Die App ist eine eigene Resource: x-banking-phone. Sie unterstützt lb-phone und qs-smartphone und registriert sich bei dem Telefon, das auf deinem Server läuft.
ensure x-banking
ensure lb-phone
ensure x-banking-phone
Die App muss nach x-banking und nach dem Telefon geladen werden. In shared/config.lua der App schaltest du einzelne Telefone ab:
Config.Phones = {
['lb-phone'] = true,
['qs-smartphone'] = true,
}
Im Handy gibt es Kontostand, Überweisen, offene Rechnungen und Zahlungsanfragen sowie den Verlauf. Alles andere bleibt bewusst der Bank und dem Automaten vorbehalten.
Bei qs-smartphone unterscheiden sich die Export-Namen je nach Version. Die App probiert der Reihe nach die Namen aus Config.QsExports durch und schreibt beim Start in die Serverkonsole, welcher funktioniert hat. Steht dort, dass keiner gepasst hat, trag den Namen deiner Version vorne in die Liste ein.
Häufige Fragen
Beim Start kommen SQL-Fehler über fehlende Tabellen
sql/install.sql wurde nicht oder nur teilweise importiert. Führ die Datei komplett aus; sie ist so gebaut, dass ein erneuter Durchlauf nichts kaputt macht.
Der Kontostand weicht von einem anderen Script ab
Prüf, ob das andere Script ebenfalls auf bank arbeitet. X-Banking nutzt ausschließlich das ESX-Konto aus Config.BankAccount und führt keinen eigenen Kontostand.
Am NPC oder Automaten passiert nichts
Steht Config.TargetSystem auf 'ox_target' oder 'qtarget', obwohl die Resource nicht läuft, gibt es weder Ziel noch Tastenhinweis. Setz den Wert auf 'none' zurück.
Das Job-Konto ist leer oder niemand kommt ans Geld
Zwei Ursachen: Entweder heißt der Chef-Grade anders als in Config.Society.bossGrades, oder es existiert kein addon_account für den Job. X-Banking liest die ESX-Society und fällt auf addon_account_data zurück; gibt es beides nicht, bleibt das Konto leer.
Rechnungen kommen beim Empfänger nicht an
Im okokBilling-Modus muss der Empfänger online sein. Für Rechnungen an Offline-Spieler setz Config.Invoices.okokBilling = false, dann übernimmt das eingebaute System.
Spieler verdienen mit Sparzinsen mehr als ein Kredit kostet
Senk Config.Savings.maxInterestBalance oder interestRate. Die verzinste Obergrenze sollte deutlich unter dem größten Kreditbetrag liegen, sonst ist die Kombination aus Kredit und Sparkonto ein Selbstläufer.
Ein Kredit wurde nicht zurückgezahlt und der Spieler behält das Geld
Das darf nicht passieren, solange blockOnDefault = true gesetzt ist und seizeOrder gefüllt bleibt. Geplatzte Kredite werden weiter eingezogen und blockieren neue Aufnahmen.
Der Aktienkurs läuft davon
maxPriceFactor begrenzt den Abstand zum Startwert. Für ruhigere Kurse senkst du zusätzlich volatility am jeweiligen Symbol oder erhöhst tickSeconds.
ATM-Hacking startet nicht
Prüf Config.ATM.robbery.minCops. Steht dort ein Wert über null und sind nicht genug Spieler aus copJobs im Dienst, bricht der Versuch ab. Danach greifen die beiden Cooldowns pro Automat und pro Spieler.
Die Bank-App reagiert nicht mehr
Drück Escape. Die Oberfläche schließt sich damit immer, auch aus Untermenüs und offenen Dialogen heraus.
Ich hätte die Texte gern auf Englisch
Setz Config.Locale = 'en'. Die englischen Texte liegen fertig in shared/locales.lua. Einzelne Sätze änderst du direkt in der Datei, Platzhalter wie %s müssen dabei stehen bleiben.
Nach einem Update sind meine Einstellungen weg
shared/config.lua und shared/locales.lua liegen im Resource-Ordner. Wird der Ordner beim Update komplett ersetzt, sind auch deine Anpassungen weg. Sicher beide Dateien vorher und spiel sie danach zurück — verschlüsselt sind sie nicht, du kannst sie also einfach kopieren.
Festgeld läuft nie ab
Config.FixedDeposit.dayHours rechnet die Laufzeit in Echtzeitstunden. Bei dayHours = 24 dauert ein 30-Tage-Festgeld tatsächlich 30 reale Tage. Für schnellere Server setz den Wert herunter, zum Beispiel auf 4.
Support
Kommst du nicht weiter, melde dich auf Discord. Halte bitte die Serverkonsole vom Start, deine Resource-Version und den betroffenen Abschnitt aus der config.lua bereit.
Etwas unklar geblieben?
Schreib uns auf Discord, wir ergänzen die Anleitung.