Agency Docs
QBESXStandalone

Agency-Phone 自定义应用

现已搭载 AgencyOS27:已拥有手机的用户可免费更新。一款适用于 FiveM 的现代手机,支持 QBCore、ESX 或独立运行,并能自动识别框架。应用涵盖基于 pma-voice 通话的电话、Buzz 消息、FaceZoom.

v27.1.2付费8 页面

🧩 为 Agency-Phone 开发自定义应用

把应用放到手机上有两种方式,选择适合你的一种:

方式适用于需要改动的内容
A. SDK(外部资源)添加带自有图标应用的开发者和脚本只改你自己的资源,无需修改 agency-phone。
B. Drop-in(在 agency-phone 内部)想在手机界面中加入原生界面的服主config.lua + apps/(界面还需 html/js)

如果你要把应用发布给其他服务器,请使用方式 A。它不需要我们的源代码,更新后也能继续使用。

A SDK:从你自己的资源注册应用

agency-phone 提供导出函数,任何资源都能在运行时把带自有图标的应用放到手机主屏幕上。应用界面留在你自己的资源中;手机负责显示图标,玩家点按时把控制权交给你。无需修改 agency-phone,也不需要解锁版本。

最小示例

-- client side of YOUR resource
CreateThread(function()
    Wait(1500) -- let agency-phone boot
    exports['agency-phone']:RegisterApp({
        id        = 'myshop',
        label     = 'My Shop',
        icon      = 'fa-solid fa-cart-shopping', -- FontAwesome 6 class
        -- image  = 'https://cfx-nui-myresource/icon.png', -- or your own image instead
        color     = '#ff9500',
        colorDark = '#e08600',
    })
end)

-- fired when the player taps your icon on the phone
AddEventHandler('agency-phone:client:openApp', function(appId)
    if appId ~= 'myshop' then return end
    exports['agency-phone']:ClosePhone()
    -- open your own NUI here
end)

RegisterApp 配置

字段类型必填说明
idstring是唯一 id,小写,不含空格。
labelstring是图标下方显示的名称。
iconstring否FontAwesome 6 类名。设置了 image 时忽略。
imagestring否自定义图标图片,例如 https://cfx-nui-<resource>/icon.png。
color / colorDarkstring否图标背后的渐变色(十六进制)。
slotnumber否在主屏幕上的位置。不填则自动放置。
storeDescstring否应用在 Store 页面上的简短说明。不填则使用 label。

SDK 导出(客户端)

导出说明
RegisterApp(config)添加或更新你的应用。返回 true,或 false, err。
UnregisterApp(id)移除你的应用。你的资源停止时也会自动移除。
GetRegisteredApps()所有已注册外部应用的表。
ClosePhone()关闭手机,例如在打开你自己的 NUI 之前。

点按事件

玩家点按你的图标时,agency-phone 会在客户端同时触发以下两个事件,任选其一即可:

事件参数
agency-phone:client:openAppappId(按你的 id 过滤)
agency-phone:client:openApp:<yourId>无(已限定为你的应用)

在你的 fxmanifest.lua 中添加 dependency 'agency-phone',以确保启动顺序正确。

B Drop-in:手机内的原生界面

适用于由手机自身绘制的界面(而不是你的资源)。这需要修改 agency-phone 自己的文件。

步骤文件escrow 版本中可编辑?
1. 在 AgencyConfig.Apps 中添加应用条目config.lua✓ 是
2. RegisterNUICallback 逻辑apps/<id>_client.lua(+ _server.lua)✓ 是
3. 界面 <div id="app-<id>">html/index.html✗ 已加密
4. openApp() 中的 case '<id>': + 加载器html/js/phone.js✗ 已加密

第 3 步和第 4 步位于 escrow 加密的文件中,因此原生界面需要源码版或解锁版。如果你只有 escrow 版本,请改用方式 A(界面放在你自己的资源中)。资源内的参考文件:apps/testapp_client.lua 和 apps/dispatch_client.lua。

📋 手机的其他导出

客户端

导出返回说明
IsPhoneOpen()boolean手机当前是否打开。
IsPhonePoweredOn()boolean设备是否开机。
HasPhone()boolean玩家是否拥有手机物品。
HasCarrierContract()boolean是否有有效的 eSIM 或合约。
GetPhoneData()table手机状态快照。
PhoneNotification(title, text, icon, color, timeout, acceptIcon, denyIcon)void手机内通知。
StartCall(contact)void拨打 { name, number }。
StartAgencyPayCheckout(opts)voidAgencyPay 结账(见下文)。

服务端

导出说明
SendMail(identifier, mailData)向玩家投递邮件(在线或离线)。
AddChirp(data)在 Pulse 社交动态中发布消息。
VerifyAgencyPayCharge(source, requestId, minAmount)在发放商品前于服务端确认 AgencyPay 结账已付款(见下文)。

⇄ NUI ↔ Lua 桥接(方式 B)

方向JS 端Lua 端
JS → LuafetchNUI('callbackName', data)RegisterNUICallback('callbackName', fn)
Lua → JS在 window.onmessage 中监听 actionSendNUIMessage({ action = '...' })

💳 AgencyPay 结账

可从任意资源向玩家的钱包收款。

exports['agency-phone']:StartAgencyPayCheckout({
    merchant = 'My Shop', title = 'Agency Pay', subtitle = 'Checkout',
    label = 'Premium Coffee', amount = 24.50,
    icon = 'fa-solid fa-mug-hot', accent = '#ff9f0a',
    clientEvent = 'myshop:client:agencyPayResult',
    serverEvent = 'myshop:server:agencyPayResult',
    metadata = { orderId = 'order_2048' },
})

RegisterNetEvent('myshop:client:agencyPayResult', function(result)
    if result.status == 'paid' then
        -- deliver the goods
    end
end)

结果中包含 status(paid / cancelled / failed)、amount、cardId、balance 以及你的 metadata。

从客户端传到你资源里的 paid 结果本身并不能证明什么。请给 StartAgencyPayCheckout 传入你自己的 id,并在发放任何东西之前于服务端调用 exports['agency-phone']:VerifyAgencyPayCharge(source, id, amount)。只有当该玩家在过去 60 秒内支付了这笔结账时,它才返回 true 和金额,并会把这笔付款标记为已使用,防止同一笔付款被领取两次。

🐛 故障排查

现象解决方法
图标不显示(SDK)把 agency-phone 更新到最新的 Keymaster 版本,在 RegisterApp 前加 Wait(1500),并在清单中添加 dependency 'agency-phone'。
点按没有反应(SDK)你的 agency-phone:client:openApp 处理函数必须与你的 id 完全一致(区分大小写)。
自定义图片不显示使用完整的 NUI 地址 https://cfx-nui-<your-resource>/path/icon.png,并在清单的 files { } 中列出该文件。
图标不显示(drop-in)在配置条目中设置 enabled = true 和 installed = true。

有疑问或需要帮助?欢迎加入 Agency Scripts 的 Discord。

看完本页仍未解决?接下来由我们的支持团队接手。