🪝 Hooks
Overview
Hooks let you run custom validation logic before or after banking actions. Use them to enforce custom policies (e.g. max balance per character), blacklist checks, or external integration across deposits, withdrawals, transfers, society money, loans, cards, and ATM flows.
RegisterHook
If you are writing code inside tgg-banking (for example in server/custom/*.lua), use the built-in function:
luaRegisterHook(eventName, callback)
If you are writing code from an external resource, use export:
lua---@param eventName string ---@param callback fun(source: number, payload: table, result?: table): (boolean|table|nil) ---@return number | nil exports['tgg-banking']:RegisterHook(eventName, callback)
registerHook (lowercase) is also available as an alias.
Both registration methods are supported. Use the variant that matches where your script lives.
Supported events
Money actions (deposit, withdraw, transfer)
beforeDepositafterDepositbeforeWithdrawafterWithdrawbeforeTransferafterTransfer
Society money exports
beforeAddSocietyMoneyafterAddSocietyMoneybeforeRemoveSocietyMoneyafterRemoveSocietyMoney
Loan lifecycle
beforeLoanApplyafterLoanApplybeforeLoanPaymentafterLoanPaymentbeforeLoanPayoffafterLoanPayoffbeforeLoanApplyPaymentafterLoanApplyPayment
Card lifecycle
beforeCardCreateafterCardCreatebeforeCardFreezeafterCardFreezebeforeCardUnfreezeafterCardUnfreezebeforeCardTerminateafterCardTerminatebeforeCardUpdateLimitsafterCardUpdateLimits
ATM
beforeAtmAuthorizeafterAtmAuthorizebeforeAtmPinChangeafterAtmPinChange
Blocking behavior (before* hooks only)
return false-> blocks action with default message.return { success = false, message = 'Your custom message' }-> blocks action with custom message.- any other return value -> allows action.
Where to use this code
Hook code runs on the server only. Add it in one of these ways:
Register hooks once when the server or resource starts (top level of your server script, not inside an event handler).
Examples
Generic outline
The examples below use the external resource form. Replace with RegisterHook when using server/custom/*.lua.
beforeDeposit
Payload: amount, reason, iban, cardNumber, accountType, accountOwnerId, playerIdentifier, newAccountBalance
Block deposits that would exceed a character's max bank balance:
luaexports['tgg-banking']:RegisterHook('beforeDeposit', function(source, payload) if payload.accountOwnerId == payload.playerIdentifier and payload.newAccountBalance > 150000 then return { success = false, message = 'You cannot have more than $150,000 in your bank account.' } end end)
afterDeposit
Same payload as beforeDeposit plus result.
Log successful deposits:
luaexports['tgg-banking']:RegisterHook('afterDeposit', function(source, payload, result) if result and result.success then print(('[BANKING] %s deposited %s to IBAN %s'):format(payload.playerIdentifier, payload.amount, payload.iban)) end end)
beforeWithdraw
Payload: amount, reason, iban, cardNumber, accountType, accountOwnerId, playerIdentifier
Block withdrawals above a limit or from blacklisted accounts:
luaexports['tgg-banking']:RegisterHook('beforeWithdraw', function(source, payload) if payload.amount > 50000 then return { success = false, message = 'Maximum single withdrawal is $50,000.' } end end)
afterWithdraw
Same payload as beforeWithdraw plus result.
Log successful withdrawals:
luaexports['tgg-banking']:RegisterHook('afterWithdraw', function(source, payload, result) if result and result.success then print(('[BANKING] %s withdrew %s from IBAN %s'):format(payload.playerIdentifier, payload.amount, payload.iban)) end end)
beforeTransfer
Payload: amount, reason, senderIban, targetIban, senderOwnerId, targetOwnerId, senderAccountType, targetAccountType, playerIdentifier, newTargetBalance
Block transfers that would exceed limits or to/from restricted accounts:
luaexports['tgg-banking']:RegisterHook('beforeTransfer', function(source, payload) if payload.amount > 100000 then return { success = false, message = 'Maximum single transfer is $100,000.' } end end)
afterTransfer
Same payload as beforeTransfer plus result.
Log successful transfers:
luaexports['tgg-banking']:RegisterHook('afterTransfer', function(source, payload, result) if result and result.success then print(('[BANKING] %s transferred %s from %s to %s'):format( payload.playerIdentifier, payload.amount, payload.senderIban, payload.targetIban )) end end)
beforeAddSocietyMoney / beforeRemoveSocietyMoney
Payload: society, iban, amount, currentBalance, newBalance, source, initiator (export calls use source = 0)
Block society deposits above a threshold:
luaexports['tgg-banking']:RegisterHook('beforeAddSocietyMoney', function(source, payload) if payload.amount > 100000 then return { success = false, message = 'Maximum single deposit is $100,000.' } end end)
beforeLoanApply / afterLoanApply
Payload: playerIdentifier, amount, duration, interestRate, paymentAmount, totalAmount, paymentFrequency, source. After hook adds loanId, loanStatus; result: { success, loanId, amount, paymentAmount, nextPaymentDate }
Log new loans:
luaexports['tgg-banking']:RegisterHook('afterLoanApply', function(source, payload, result) if result and result.success then print(('[LOANS] %s received loan %s for $%s'):format( payload.playerIdentifier, result.loanId, payload.amount )) end end)
beforeCardCreate / afterCardCreate
Payload: accountIban, playerIdentifier, displayName, color, source. After adds cardId, cardNumber. PIN and CVV never in payloads.
Block card creation for certain account types or players:
luaexports['tgg-banking']:RegisterHook('beforeCardCreate', function(source, payload) -- Example: only allow one card per account via external tracking return -- allow by default end)
beforeAtmAuthorize / beforeAtmPinChange
Payload: cardNumber, accountIban, playerIdentifier, source. Raw PIN and new PIN never in payloads.
Block ATM access for specific cards (e.g. flagged accounts):
luaexports['tgg-banking']:RegisterHook('beforeAtmAuthorize', function(source, payload) -- PIN is never in payload; use cardNumber/accountIban for lookup if payload.cardNumber == 123456789 then return { success = false, message = 'This card has been restricted.' } end end)