Agency Docs
QBESXStandalone

Agency-Phone Apps Personalizados

Agora com o AgencyOS27: uma atualização grátis para quem já tem o telefone.

v27.1.2Pago8 Páginas

🧩 Criar uma app própria para o Agency-Phone

Há duas maneiras de pôr uma app no telefone. Escolhe a que te serve:

MétodoIdeal paraO que alteras
A. SDK (resource externo)Criadores e scripts que adicionam uma app com o seu próprio íconeSó o teu próprio resource. Nenhuma alteração ao agency-phone.
B. Drop-in (dentro do agency-phone)Donos de servidor que adicionam um ecrã nativo na interface do telefoneconfig.lua + apps/ (+ html/js para um ecrã)

Se distribuis uma app para outros servidores, usa o método A. Não precisa de código-fonte nosso e continua a funcionar depois das atualizações.

A SDK: registar uma app a partir do teu próprio resource

O agency-phone disponibiliza exports com que qualquer resource coloca, em tempo de execução, uma app com o seu próprio ícone no ecrã inicial do telefone. A interface da tua app fica no teu resource; o telefone mostra o ícone e passa-te o controlo quando o jogador lhe toca. Sem alterações ao agency-phone, sem build desbloqueado.

Exemplo mínimo

-- 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)

Configuração do RegisterApp

CampoTipoObrigatórioDescrição
idstringsimId único, em minúsculas, sem espaços.
labelstringsimNome mostrado por baixo do ícone.
iconstringnãoClasse do FontAwesome 6. Ignorada se image estiver definido.
imagestringnãoImagem de ícone própria, por exemplo https://cfx-nui-<resource>/icon.png.
color / colorDarkstringnãoGradiente atrás do ícone (hex).
slotnumbernãoPosição no ecrã inicial. Se faltar, é colocada automaticamente.
storeDescstringnãoDescrição curta na página da Store da tua app. Se faltar, usa o label.

Exports do SDK (cliente)

ExportDescrição
RegisterApp(config)Adiciona ou atualiza a tua app. Devolve true, ou false, err.
UnregisterApp(id)Remove a tua app. Também acontece automaticamente quando o teu resource para.
GetRegisteredApps()Tabela de todas as apps externas registadas.
ClosePhone()Fecha o telefone, por exemplo antes de abrires a tua própria NUI.

O evento ao tocar

Quando o jogador toca no teu ícone, o agency-phone dispara estes dois eventos no cliente. Usa o que preferires:

EventoArgumentos
agency-phone:client:openAppappId (filtra pelo teu id)
agency-phone:client:openApp:<yourId>nenhum (já é só para a tua app)

Adiciona dependency 'agency-phone' ao teu fxmanifest.lua para a ordem de arranque estar certa.

B Drop-in, um ecrã nativo dentro do telefone

Para um ecrã desenhado pelo próprio telefone (não pelo teu resource). Isto altera ficheiros do agency-phone.

PassoFicheiroEditável no build escrow?
1. Entrada da app em AgencyConfig.Appsconfig.lua✓ sim
2. Lógica com RegisterNUICallbackapps/<id>_client.lua (+ _server.lua)✓ sim
3. Ecrã <div id="app-<id>">html/index.html✗ cifrado
4. case '<id>': em openApp() + carregadorhtml/js/phone.js✗ cifrado

Os passos 3 e 4 estão em ficheiros cifrados pelo escrow, por isso um ecrã nativo precisa de um build com código-fonte ou desbloqueado. Se só tens a versão escrow, usa o método A (o teu ecrã fica no teu próprio resource). Ficheiros de referência dentro do resource: apps/testapp_client.lua e apps/dispatch_client.lua.

📋 Outros exports do telefone

Cliente

ExportDevolveDescrição
IsPhoneOpen()booleanTelefone aberto neste momento.
IsPhonePoweredOn()booleanAparelho ligado.
HasPhone()booleanO jogador tem um item de telefone.
HasCarrierContract()booleaneSIM ou contrato ativo.
GetPhoneData()tableInstantâneo do estado do telefone.
PhoneNotification(title, text, icon, color, timeout, acceptIcon, denyIcon)voidNotificação no telefone.
StartCall(contact)voidLiga para { name, number }.
StartAgencyPayCheckout(opts)voidPagamento AgencyPay (ver abaixo).

Servidor

ExportDescrição
SendMail(identifier, mailData)Entrega um mail a um jogador (online ou offline).
AddChirp(data)Publica uma mensagem no feed social Pulse.
VerifyAgencyPayCharge(source, requestId, minAmount)Confirma no servidor um pagamento AgencyPay antes de entregares a mercadoria (ver abaixo).

⇄ Ponte NUI ↔ Lua (método B)

DireçãoLado JSLado Lua
JS → LuafetchNUI('callbackName', data)RegisterNUICallback('callbackName', fn)
Lua → JSescuta action em window.onmessageSendNUIMessage({ action = '...' })

💳 Pagamento AgencyPay

Cobra na wallet do jogador a partir de qualquer resource.

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)

O resultado inclui status (paid / cancelled / failed), amount, cardId, balance e os teus metadata.

Um paid que chega do cliente ao teu resource não prova nada por si só. Passa o teu próprio id a StartAgencyPayCheckout e chama exports['agency-phone']:VerifyAgencyPayCharge(source, id, amount) no servidor antes de entregares seja o que for. Só devolve true e o valor se este jogador pagou esse pagamento nos últimos 60 segundos, e consome o pagamento para que não possa ser reclamado duas vezes.

🐛 Resolução de problemas

SintomaSolução
O ícone não aparece (SDK)Atualiza o agency-phone para o build mais recente do Keymaster, usa Wait(1500) antes de RegisterApp e adiciona dependency 'agency-phone' ao teu manifest.
Tocar não faz nada (SDK)O teu handler de agency-phone:client:openApp tem de corresponder exatamente ao teu id (distingue maiúsculas e minúsculas).
A imagem própria não apareceUsa um URL NUI completo https://cfx-nui-<your-resource>/path/icon.png e lista o ficheiro em files { } no teu manifest.
O ícone não aparece (drop-in)enabled = true e installed = true na entrada da config.

Dúvidas ou precisas de ajuda? Junta-te ao Discord da Agency Scripts.

Continuas sem avançar depois desta página? O nosso suporte assume daqui.