Agency Docs
QBESXStandalone

Agency-Phone Apps Personnalisées

Désormais avec AgencyOS27 : une mise à jour gratuite pour tous ceux qui ont déjà le téléphone.

v27.1.2Payant8 Pages

🧩 Créer une app personnalisée pour Agency-Phone

Il existe deux façons d'ajouter une app au téléphone. Choisissez celle qui vous convient :

MéthodeIdéale pourCe que vous modifiez
A. SDK (resource externe)Éditeurs et scripts qui ajoutent une app avec leur propre icôneUniquement votre propre resource. Aucune modification d'agency-phone.
B. Drop-in (dans agency-phone)Propriétaires de serveur qui ajoutent un écran natif dans l'interface du téléphoneconfig.lua + apps/ (+ html/js pour un écran)

Si vous distribuez une app à d'autres serveurs, utilisez la méthode A. Elle ne demande aucun code source de notre part et continue de fonctionner après les mises à jour.

A SDK : enregistrer une app depuis votre propre resource

agency-phone fournit des exports qui permettent à n'importe quelle resource d'ajouter à la volée une app avec sa propre icône sur l'écran d'accueil du téléphone. L'interface de votre app reste dans votre resource ; le téléphone affiche l'icône et vous passe la main quand le joueur la touche. Aucune modification d'agency-phone, aucun build déverrouillé.

Exemple minimal

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

Configuration de RegisterApp

ChampTypeRequisDescription
idstringouiId unique, en minuscules, sans espaces.
labelstringouiNom affiché sous l'icône.
iconstringnonClasse FontAwesome 6. Ignorée si image est défini.
imagestringnonImage d'icône personnalisée, par ex. https://cfx-nui-<resource>/icon.png.
color / colorDarkstringnonDégradé derrière l'icône (hex).
slotnumbernonPosition sur l'écran d'accueil. Placée automatiquement si absente.
storeDescstringnonCourte description sur la page Store de votre app. Reprend le label si absente.

Exports du SDK (client)

ExportDescription
RegisterApp(config)Ajoute ou met à jour votre app. Renvoie true, ou false, err.
UnregisterApp(id)Retire votre app. Se fait aussi automatiquement quand votre resource s'arrête.
GetRegisteredApps()Table de toutes les apps externes enregistrées.
ClosePhone()Ferme le téléphone, par ex. avant d'ouvrir votre propre NUI.

L'événement au toucher

Quand le joueur touche votre icône, agency-phone déclenche ces deux événements côté client. Utilisez celui que vous préférez :

ÉvénementArguments
agency-phone:client:openAppappId (filtrez sur votre id)
agency-phone:client:openApp:<yourId>aucun (déjà limité à votre app)

Ajoutez dependency 'agency-phone' à votre fxmanifest.lua pour que l'ordre de démarrage soit correct.

B Drop-in, un écran natif dans le téléphone

Pour un écran dessiné par le téléphone lui-même (et non par votre resource). Cela modifie les fichiers d'agency-phone.

ÉtapeFichierModifiable dans le build escrow ?
1. Entrée d'app dans AgencyConfig.Appsconfig.lua✓ oui
2. Logique RegisterNUICallbackapps/<id>_client.lua (+ _server.lua)✓ oui
3. Écran <div id="app-<id>">html/index.html✗ chiffré
4. case '<id>': dans openApp() + chargeurhtml/js/phone.js✗ chiffré

Les étapes 3 et 4 se trouvent dans des fichiers chiffrés par l'escrow ; un écran natif nécessite donc un build avec sources ou déverrouillé. Si vous n'avez que la version escrow, utilisez plutôt la méthode A (votre écran vit dans votre propre resource). Fichiers de référence dans la resource : apps/testapp_client.lua et apps/dispatch_client.lua.

📋 Autres exports du téléphone

Client

ExportRenvoieDescription
IsPhoneOpen()booleanTéléphone actuellement ouvert.
IsPhonePoweredOn()booleanAppareil allumé.
HasPhone()booleanLe joueur possède un objet téléphone.
HasCarrierContract()booleaneSIM ou contrat actif.
GetPhoneData()tableInstantané de l'état du téléphone.
PhoneNotification(title, text, icon, color, timeout, acceptIcon, denyIcon)voidNotification sur le téléphone.
StartCall(contact)voidAppelle { name, number }.
StartAgencyPayCheckout(opts)voidPaiement AgencyPay (voir plus bas).

Serveur

ExportDescription
SendMail(identifier, mailData)Envoie un mail à un joueur (en ligne ou hors ligne).
AddChirp(data)Publie un message dans le fil social Pulse.
VerifyAgencyPayCharge(source, requestId, minAmount)Confirme côté serveur un paiement AgencyPay réglé avant de remettre la marchandise (voir plus bas).

⇄ Pont NUI ↔ Lua (méthode B)

SensCôté JSCôté Lua
JS → LuafetchNUI('callbackName', data)RegisterNUICallback('callbackName', fn)
Lua → JSécoutez action dans window.onmessageSendNUIMessage({ action = '...' })

💳 Paiement AgencyPay

Débitez le wallet du joueur depuis n'importe quelle 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)

Le résultat contient status (paid / cancelled / failed), amount, cardId, balance et vos metadata.

Un résultat paid qui arrive du client jusqu'à votre resource ne prouve rien à lui seul. Passez votre propre id à StartAgencyPayCheckout et appelez exports['agency-phone']:VerifyAgencyPayCharge(source, id, amount) côté serveur avant de remettre quoi que ce soit. La fonction ne renvoie true et le montant que si ce joueur a réglé ce paiement dans les 60 dernières secondes, puis elle consomme le paiement pour qu'il ne puisse pas être réclamé deux fois.

🐛 Dépannage

SymptômeSolution
L'icône n'apparaît pas (SDK)Mettez agency-phone à jour vers le dernier build Keymaster, faites Wait(1500) avant RegisterApp et ajoutez dependency 'agency-phone' à votre manifest.
Toucher l'icône ne fait rien (SDK)Votre handler agency-phone:client:openApp doit correspondre exactement à votre id (sensible à la casse).
L'image personnalisée ne s'affiche pasUtilisez une URL NUI complète https://cfx-nui-<your-resource>/path/icon.png et listez le fichier dans files { } de votre manifest.
L'icône n'apparaît pas (drop-in)enabled = true et installed = true dans l'entrée de config.

Des questions ou besoin d'un coup de main ? Rejoignez le Discord d'Agency Scripts.

Toujours bloqué après cette page ? Notre support prend le relais.