> For the complete documentation index, see [llms.txt](https://docs.rainmad.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rainmad.com/resources/id-card/integrations.md).

# Integrations

### QBCore

#### qb-multicharacter

* Open [qb-multicharacter/server/main.lua](https://github.com/qbcore-framework/qb-multicharacter/blob/main/server/main.lua).
* Find the [GiveStarterItems](https://github.com/qbcore-framework/qb-multicharacter/blob/76c09e4b4a2faa683a3a8661bbe5b02b5198c29a/server/main.lua#L7C1-L27C4) function.
* Update the code for `id_card` and `driver_license` to utilize the `createCard` export.

```lua
local function GiveStarterItems(source)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    for _, v in pairs(QBCore.Shared.StarterItems) do
        local info = {}
        -- if v.item == 'id_card' then
        --     info.citizenid = Player.PlayerData.citizenid
        --     info.firstname = Player.PlayerData.charinfo.firstname
        --     info.lastname = Player.PlayerData.charinfo.lastname
        --     info.birthdate = Player.PlayerData.charinfo.birthdate
        --     info.gender = Player.PlayerData.charinfo.gender
        --     info.nationality = Player.PlayerData.charinfo.nationality
        -- elseif v.item == 'driver_license' then
        --     info.firstname = Player.PlayerData.charinfo.firstname
        --     info.lastname = Player.PlayerData.charinfo.lastname
        --     info.birthdate = Player.PlayerData.charinfo.birthdate
        --     info.type = 'Class C Driver License'
        -- end
        if v.item == 'id_card' or v.item == 'driver_license' then
            exports.rm_idcard:createCard(src, v.item)
        else
            exports['qb-inventory']:AddItem(src, v.item, v.amount, false, info, 'qb-multicharacter:GiveStarterItems')
        end
    end
end
```

#### qb-cityhall

* Open [qb-cityhall/server/main.lua](https://github.com/qbcore-framework/qb-cityhall/blob/main/server/main.lua).
* Find the [giveStarterItems](https://github.com/qbcore-framework/qb-cityhall/blob/4eefa1801321b0815d651996d82ec424d617c872/server/main.lua#L19C1-L39C4) function.
* Update the `id_card` and `driver_license` items to invoke the `createCard` export.

```lua
local function giveStarterItems()
    local Player = QBCore.Functions.GetPlayer(source)
    if not Player then return end
    for _, v in pairs(QBCore.Shared.StarterItems) do
        local info = {}
        -- if v.item == 'id_card' then
        --     info.citizenid = Player.PlayerData.citizenid
        --     info.firstname = Player.PlayerData.charinfo.firstname
        --     info.lastname = Player.PlayerData.charinfo.lastname
        --     info.birthdate = Player.PlayerData.charinfo.birthdate
        --     info.gender = Player.PlayerData.charinfo.gender
        --     info.nationality = Player.PlayerData.charinfo.nationality
        -- elseif v.item == 'driver_license' then
        --     info.firstname = Player.PlayerData.charinfo.firstname
        --     info.lastname = Player.PlayerData.charinfo.lastname
        --     info.birthdate = Player.PlayerData.charinfo.birthdate
        --     info.type = 'Class C Driver License'
        -- end
        if v.item == 'id_card' or v.item == 'driver_license' then
            exports.rm_idcard:createCard(source, v.item)
        else
            exports['qb-inventory']:AddItem(source, v.item, 1, false, info, 'qb-cityhall:giveStarterItems')
        end
    end
end
```

* Find the [qb-cityhall:server:requestId](https://github.com/qbcore-framework/qb-cityhall/blob/4eefa1801321b0815d651996d82ec424d617c872/server/main.lua#L65C1-L93C5) event.
* Initialize `id_card`, `driver_license`, and `weaponlicense` using the `createCard` export.

```lua
RegisterNetEvent('qb-cityhall:server:requestId', function(item, hall)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end
    local itemInfo = Config.Cityhalls[hall].licenses[item]
    if not Player.Functions.RemoveMoney('cash', itemInfo.cost, 'cityhall id') then return TriggerClientEvent('QBCore:Notify', src, ('You don\'t have enough money on you, you need %s cash'):format(itemInfo.cost), 'error') end
    local info = {}
    -- if item == 'id_card' then
    --     info.citizenid = Player.PlayerData.citizenid
    --     info.firstname = Player.PlayerData.charinfo.firstname
    --     info.lastname = Player.PlayerData.charinfo.lastname
    --     info.birthdate = Player.PlayerData.charinfo.birthdate
    --     info.gender = Player.PlayerData.charinfo.gender
    --     info.nationality = Player.PlayerData.charinfo.nationality
    -- elseif item == 'driver_license' then
    --     info.firstname = Player.PlayerData.charinfo.firstname
    --     info.lastname = Player.PlayerData.charinfo.lastname
    --     info.birthdate = Player.PlayerData.charinfo.birthdate
    --     info.type = 'Class C Driver License'
    -- elseif item == 'weaponlicense' then
    --     info.firstname = Player.PlayerData.charinfo.firstname
    --     info.lastname = Player.PlayerData.charinfo.lastname
    --     info.birthdate = Player.PlayerData.charinfo.birthdate
    if item == 'id_card' or item == 'driver_license' or item == 'weaponlicense' then
        exports.rm_idcard:createCard(src, item)
        return
    else
        return false
    end
    if not exports['qb-inventory']:AddItem(src, item, 1, false, info, 'qb-cityhall:server:requestId') then return end
    TriggerClientEvent('qb-inventory:client:ItemBox', src, QBCore.Shared.Items[item], 'add')
end)
```

<details>

<summary><strong>Optional:</strong> <code>rm_idcard</code> relies on its own NPC system for purchasing licenses. To avoid player confusion, you should disable the native options in the Cityhall script.</summary>

* Open [qb-cityhall/client/main.lua](https://github.com/qbcore-framework/qb-cityhall/blob/main/client/main.lua).
* Find the [openCityhallMenu](https://github.com/qbcore-framework/qb-cityhall/blob/4eefa1801321b0815d651996d82ec424d617c872/client/main.lua#L99C1-L129C4) function.
* Comment out the `ID Card` option.

```lua
local function openCityhallMenu()
    local mainMenu = {
        {
            header = 'City Hall',
            isMenuHeader = true
        },
        -- {
        --     header = 'ID Card',
        --     txt = 'Get your ID Card',
        --     params = {
        --         event = 'qb-cityhall:client:openIdentityMenu'
        --     }
        -- },
        {
            header = 'Job Center',
            txt = 'Available Jobs',
            params = {
                event = 'qb-cityhall:client:openJobMenu'
            }
        },
        {
            header = 'Close Menu',
            txt = '',
            params = {
                event = 'qb-menu:client:closeMenu'
            }
        }
    }

    exports['qb-menu']:openMenu(mainMenu)
end
```

</details>

#### qb-inventory

* Open [qb-inventory/server/main.lua](https://github.com/qbcore-framework/qb-inventory/blob/main/server/main.lua).
* Find the [qb-inventory:server:useItem](https://github.com/qbcore-framework/qb-inventory/blob/2bdea9b53237396178dcd8af776a55c1e857e864/server/main.lua#L180C1-L240C5) event.
* Comment out the logic for `id_card` and `driver_license` to prevent conflicts.

```lua
RegisterNetEvent('qb-inventory:server:useItem', function(item)
    local src = source
    local itemData = GetItemBySlot(src, item.slot)
    if not itemData then return end
    local itemInfo = QBCore.Shared.Items[itemData.name]
    if itemData.type == 'weapon' then
        TriggerClientEvent('qb-weapons:client:UseWeapon', src, itemData, itemData.info.quality and itemData.info.quality > 0)
        TriggerClientEvent('qb-inventory:client:ItemBox', src, itemInfo, 'use')
    -- elseif itemData.name == 'id_card' then
    --     UseItem(itemData.name, src, itemData)
    --     TriggerClientEvent('qb-inventory:client:ItemBox', source, itemInfo, 'use')
    --     local playerPed = GetPlayerPed(src)
    --     local playerCoords = GetEntityCoords(playerPed)
    --     local players = QBCore.Functions.GetPlayers()
    --     local gender = item.info.gender == 0 and 'Male' or 'Female'
    --     for _, v in pairs(players) do
    --         local targetPed = GetPlayerPed(v)
    --         local dist = #(playerCoords - GetEntityCoords(targetPed))
    --         if dist < 3.0 then
    --             TriggerClientEvent('chat:addMessage', v, {
    --                 template = '<div class="chat-message advert" style="background: linear-gradient(to right, rgba(5, 5, 5, 0.6), #74807c); display: flex;"><div style="margin-right: 10px;"><i class="far fa-id-card" style="height: 100%;"></i><strong> {0}</strong><br> <strong>Civ ID:</strong> {1} <br><strong>First Name:</strong> {2} <br><strong>Last Name:</strong> {3} <br><strong>Birthdate:</strong> {4} <br><strong>Gender:</strong> {5} <br><strong>Nationality:</strong> {6}</div></div>',
    --                 args = {
    --                     'ID Card',
    --                     item.info.citizenid,
    --                     item.info.firstname,
    --                     item.info.lastname,
    --                     item.info.birthdate,
    --                     gender,
    --                     item.info.nationality
    --                 }
    --             })
    --         end
    --     end
    -- elseif itemData.name == 'driver_license' then
    --     UseItem(itemData.name, src, itemData)
    --     TriggerClientEvent('qb-inventory:client:ItemBox', src, itemInfo, 'use')
    --     local playerPed = GetPlayerPed(src)
    --     local playerCoords = GetEntityCoords(playerPed)
    --     local players = QBCore.Functions.GetPlayers()
    --     for _, v in pairs(players) do
    --         local targetPed = GetPlayerPed(v)
    --         local dist = #(playerCoords - GetEntityCoords(targetPed))
    --         if dist < 3.0 then
    --             TriggerClientEvent('chat:addMessage', v, {
    --                 template = '<div class="chat-message advert" style="background: linear-gradient(to right, rgba(5, 5, 5, 0.6), #657175); display: flex;"><div style="margin-right: 10px;"><i class="far fa-id-card" style="height: 100%;"></i><strong> {0}</strong><br> <strong>First Name:</strong> {1} <br><strong>Last Name:</strong> {2} <br><strong>Birth Date:</strong> {3} <br><strong>Licenses:</strong> {4}</div></div>',
    --                 args = {
    --                     'Drivers License',
    --                     item.info.firstname,
    --                     item.info.lastname,
    --                     item.info.birthdate,
    --                     item.info.type
    --                 }
    --             }
    --             )
    --         end
    --     end
    else
        UseItem(itemData.name, src, itemData)
        TriggerClientEvent('qb-inventory:client:ItemBox', src, itemInfo, 'use')
    end
end)
```

* Open [qb-inventory/server/commands.lua](https://github.com/qbcore-framework/qb-inventory/blob/main/server/commands.lua)
* Find the [giveitem](https://github.com/qbcore-framework/qb-inventory/blob/2bdea9b53237396178dcd8af776a55c1e857e864/server/commands.lua#L3C1-L49C14) command.
* Modify the logic for `id_card` and `driver_license` to use the `createCard` export upon generation.

```lua
QBCore.Commands.Add('giveitem', 'Give An Item (Admin Only)', { { name = 'id', help = 'Player ID' }, { name = 'item', help = 'Name of the item (not a label)' }, { name = 'amount', help = 'Amount of items' } }, false, function(source, args)
    local id = tonumber(args[1])
    local player = QBCore.Functions.GetPlayer(id)
    local amount = tonumber(args[3]) or 1
    local itemData = QBCore.Shared.Items[tostring(args[2]):lower()]
    if player then
        if itemData then
            -- check iteminfo
            local info = {}
            -- if itemData['name'] == 'id_card' then
            --     info.citizenid = player.PlayerData.citizenid
            --     info.firstname = player.PlayerData.charinfo.firstname
            --     info.lastname = player.PlayerData.charinfo.lastname
            --     info.birthdate = player.PlayerData.charinfo.birthdate
            --     info.gender = player.PlayerData.charinfo.gender
            --     info.nationality = player.PlayerData.charinfo.nationality
            -- elseif itemData['name'] == 'driver_license' then
            --     info.firstname = player.PlayerData.charinfo.firstname
            --     info.lastname = player.PlayerData.charinfo.lastname
            --     info.birthdate = player.PlayerData.charinfo.birthdate
            --     info.type = 'Class C Driver License'
            if itemData['name'] == 'id_card' or itemData['name'] == 'driver_license' then
                exports.rm_idcard:createCard(source, itemData['name'])
                return
            elseif itemData['type'] == 'weapon' then
                amount = 1
                info.serie = tostring(QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(1) .. QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(4))
                info.quality = 100
            elseif itemData['name'] == 'harness' then
                info.uses = 20
            elseif itemData['name'] == 'markedbills' then
                info.worth = math.random(5000, 10000)
            elseif itemData['name'] == 'printerdocument' then
                info.url = 'https://cdn.discordapp.com/attachments/870094209783308299/870104331142189126/Logo_-_Display_Picture_-_Stylized_-_Red.png'
            end

            if AddItem(id, itemData['name'], amount, false, info, 'give item command') then
                QBCore.Functions.Notify(source, Lang:t('notify.yhg') .. GetPlayerName(id) .. ' ' .. amount .. ' ' .. itemData['name'] .. '', 'success')
                TriggerClientEvent('qb-inventory:client:ItemBox', id, itemData, 'add', amount)
                if Player(id).state.inv_busy then TriggerClientEvent('qb-inventory:client:updateInventory', id) end
            else
                QBCore.Functions.Notify(source, Lang:t('notify.cgitem'), 'error')
            end
        else
            QBCore.Functions.Notify(source, Lang:t('notify.idne'), 'error')
        end
    else
        QBCore.Functions.Notify(source, Lang:t('notify.pdne'), 'error')
    end
end, 'admin')
```

***

### QBox

#### qbx\_idcard

Ensure that the `qbx_idcard` script is not running. If there is a `qbx_idcard` folder under the \[qbx] folder, back it up and delete it. `rm_idcard` will provide the `GetMetaLicense` export.

#### qbx\_cityhall

<details>

<summary><strong>Optional:</strong> <code>rm_idcard</code> relies on its own NPC system for purchasing licenses. To avoid player confusion, you should disable the native options in the Cityhall script.</summary>

* Open [qbx\_cityhall/client/main.lua](https://github.com/qbcore-framework/qb-cityhall/blob/main/client/main.lua).
* Find the [openCityhallMenu](https://github.com/Qbox-project/qbx_cityhall/blob/d99876f00f9f63cc5c33b517f3f6eeb68e8d270d/client/main.lua#L103C1-L136C4) function.
* Comment out the `Identity` option.

```lua
local function openCityhallMenu()
    local closestCityhall = getClosestHall()
    local options = {}

    -- options[#options + 1] = {
    --     title = locale('info.identity'),
    --     description = locale('info.obtain_license_identity'),
    --     onSelect = function()
    --         openIdentificationMenu(closestCityhall)
    --     end
    -- }

    if sharedConfig.employment.enabled then
        options[#options + 1] = {
            title = locale('info.employment'),
            description = locale('info.select_job'),
            onSelect = openEmploymentMenu
        }
    end

    lib.registerContext({
        id = 'cityhall_menu',
        title = locale('info.cityhall'),
        onExit = function()
            if not config.useTarget and inRangeCityhall then
                lib.showTextUI(locale('info.open_cityhall'))
            end
        end,
        options = options
    })
    lib.showContext('cityhall_menu')
    if not config.useTarget then return end
    inRangeCityhall = false
end
```

</details>
