Skip to main content

Wallet API

Developer reference for the Wallet app. Server exports let another resource read a player’s cards, show one to a nearby player, issue and revoke membership cards and set the ID photo. Below the exports: the callbacks the phone itself uses, the two client events, the card schema and the Events app callbacks.
Three ways to get a card into a player’s wallet from your own resource:
  1. A condition card in Config.Wallet.Cards — give an item, a license or a job grade and the card appears on the next open. No code.
  2. issueWalletCard — a membership card with label, business, colour and expiry, for online and offline players.
  3. Code inside the roadphone resource (server/serverAPI/*.lua, addons) may call the global functions directly.
Call the exports from a thread — a command handler, an event handler or CreateThread. Building cards runs synchronous queries.

Return shape

Write exports return a table:

Reading

getWalletCards

Every card of an online player, built live from the framework and the wallet tables.
number
required
The player’s server ID.
table
Array of card objects. Empty when the player is offline or has no identifier.

getWalletCard

One card by id.
number
required
The player’s server ID.
string
required
'id', 'license:<id>', 'job', 'gang', 'custom:<id>', 'member:<row id>' or 'ticket:<row id>'.
table | nil
The card object, or nil when the player does not hold it.

hasWalletCard

Does the player hold this card right now? The cheapest way to gate something on a license, a pass or a job card.
number
required
The player’s server ID.
string
required
A card id, see getWalletCard.
boolean
true when the card exists for the player at this moment.

getWalletMemberships

Active membership cards (rows of roadshop_wallet_cards that are not revoked), newest first. Expired cards are included with valid = false.
number | string
required
A server ID (online player) or an identifier string (the player may be offline).
string
Only cards issued under this business name. Omit for all.
table

Membership cards

issueWalletCard

Issue a membership card. The holder gets a notification and their wallet refreshes while they are online; an offline player finds the card on the next open.
number | string
required
A server ID (online player) or an identifier string. The identifier must be the one RoadPhone stores for the character: xPlayer.identifier on ESX, citizenid on QBCore / Qbox.
table
required
table
{ ok = true, id = number, expiresAt = number | nil } or { ok = false, error = string }. Keep id — it is what revokeWalletCard needs.

revokeWalletCard

Revoke a membership card. The row stays for the records (revoked = 1); the card leaves the holder’s wallet immediately when they are online.
number
required
The id returned by issueWalletCard or listed by getWalletMemberships.
table
{ ok = true, id = number, identifier = string } or { ok = false, error = 'not_found' } (unknown id or already revoked).

Showing and photos

showWalletCard

Show one of a player’s cards to another player nearby — the same flow as the Show button, without the per-player rate limit. Use it for scripted ID checks.
number
required
Server ID of the card holder.
number
required
Server ID of the receiver. Must be within Config.Wallet.ShowRadius and in the same routing bucket.
string
required
A card id the holder owns right now.
table
table
{ ok = true, showId = number, duration = number } or { ok = false, error = string }.

setWalletPhoto

Set or clear the ID photo of a character — for example from a character creator or a mugshot system.
number | string
required
A server ID or an identifier string.
string | nil
required
An http(s):// URL of at most 255 characters, or nil to remove the photo (the app then offers Take photo again).
table
{ ok = true, photo = string | nil } or { ok = false, error = string }.
The export trusts the URL you pass. Only the in-app capture is restricted to the upload host allow-list, because that URL comes from the client.

refreshWallet

Tell an online player’s phone to reload its cards. Needed only after you changed something the Wallet reads that is not covered by the exports above — for example a Config.Wallet.Cards condition that flipped through your own inventory code.
number
required
The player’s server ID.
boolean
true when the player is online.

Callbacks

Registered in server/wallet.lua. The phone calls them through the NUI proxies listed further down; the server never trusts a player id or identifier from the client — every distance is measured server-side and every identity is re-read from the framework. Every failure answers { ok = false, reason = … }:

Client events

Both are networked client events (RegisterNetEvent). refreshWallet triggers the second one for you; do not trigger roadphone:wallet:incoming yourself — the phone treats its payload as an already-verified card, the checks live in showWalletCard.

NUI callbacks

Registered in client/wallet.lua, for reference when you read the phone UI or write a custom app that reuses the flow.

Card schema

Every card — from the exports, from getCards and in roadphone:wallet:incoming — has this shape:
meta per type: Field kind values: date, datetime (unix seconds), dob (YYYY-MM-DD), sex (m / f), height (centimetres); without kind the value is shown as text.

Global functions (inside the roadphone resource)

Plain globals of server/wallet.lua — the same functions the exports wrap. They are not exports; use them from server/serverAPI/*.lua, addons or other scripts that run inside the resource. They return reason instead of error on failure. The boss actions of the Events app (Business tab) go through WalletIssueCard and WalletRevokeCard as well, so a card issued by a boss and a card issued by your resource behave the same.

Events app callbacks

The Events app supplies the tickets and membership cards the Wallet shows. Registered in server/events.lua; every one answers { ok = false, reason = … } on failure. roadphone:events:changed (Server → Client) tells the phone to reload the Events app.

Rate limits

Only the phone’s own callbacks are rate-limited; the exports are not.

Wallet

Configuration, card types, player flow and troubleshooting

Export Index

Every client and server export of RoadPhone Pro