# Integrazioni

cxg-tattoos può collegarsi a diversi framework per addebitare gli acquisti e verificare i permessi amministrativi. L'integrazione di aspetto riapplica i tatuaggi salvati quando il personaggio viene caricato o cambia skin. Ogni parte si configura separatamente.

Consulta anche [Introduzione](https://docs.cxgstudios.com/docs/it/01-cxg-tattoos/01-introduccion.md), [Installazione](https://docs.cxgstudios.com/docs/it/01-cxg-tattoos/02-instalacion.md), [Configurazione](https://docs.cxgstudios.com/docs/it/01-cxg-tattoos/03-configuracion.md), [Catalogo](https://docs.cxgstudios.com/docs/it/01-cxg-tattoos/04-catalogo.md) e [Interfaccia](https://docs.cxgstudios.com/docs/it/01-cxg-tattoos/06-interfaz.md).

## Framework disponibili

| Sistema | Identificatore di configurazione | Risorsa predefinita | Pagamenti | Permessi |
| --- | --- | --- | --- | --- |
| Qbox | `qbx` | `qbx_core` | Sì | Sì |
| QBCore | `qbcore` | `qb-core` | Sì | Sì |
| ESX | `esx` | `es_extended` | Sì | Sì |
| Senza framework | `standalone` | Non applicabile | Callback personalizzato o acquisti gratuiti | ACE o verifica personalizzata |

Con `auto`, la risorsa rileva Qbox, QBCore o ESX se avviati; se non ne trova nessuno, usa `standalone`. Puoi impostare il framework manualmente quando il server ha più framework attivi o usa un nome di risorsa diverso:

```lua
Config.Purchases.framework = 'qbx' -- auto | qbx | qbcore | esx | standalone
Config.Purchases.resources.qbx = 'qbx_core'
Config.Purchases.accounts = { 'cash', 'bank' }
Config.Purchases.esxAccountMap.cash = 'money'
Config.Purchases.esxAccountMap.bank = 'bank'
Config.Purchases.allowFreePurchases = false
```

I conti vengono provati nell'ordine indicato. L'addebito viene effettuato da un solo conto; se il saldo non è sufficiente, si prova il successivo. In ESX, `esxAccountMap` traduce `cash` nel nome del conto `money`.

`Config.Purchases.reason` e `refundReason` identificano il motivo delle transazioni per i provider che lo supportano. I valori iniziali sono `tattoo-purchase` e `tattoo-purchase-refund`. L'opzione `allowFreePurchases` permette di saltare l'addebito nell'adattatore standalone; non rende gratuiti gli acquisti sugli altri framework.

## Pagamenti senza framework

In modalità `standalone`, collega `tryCharge` e `refund` alla risorsa economica del server. Entrambi i callback sono necessari per accettare acquisti: il rimborso permette di restituire l'addebito se il salvataggio del tatuaggio non riesce.

```lua
Config.Purchases.framework = 'standalone'
Config.Purchases.standalone.tryCharge = function(source, totalAmount, context)
    -- Sustituye esta llamada por la API de economía de tu servidor.
    local charged, receipt = MyEconomy.charge(source, totalAmount, context)
    if charged then
        return true, receipt
    end
    return false, 'No tienes saldo suficiente.'
end

Config.Purchases.standalone.refund = function(source, totalAmount, context, receiptData)
    -- Usa receiptData para devolver el mismo cobro aprobado.
    return MyEconomy.refund(source, totalAmount, receiptData) == true
end
```

`MyEconomy` rappresenta l'API del server; sostituiscila con il nome e le chiamate effettive. Per consentire intenzionalmente gli acquisti gratuiti, imposta `allowFreePurchases = true`.

Gli adattatori di pagamento espongono `isAvailable(settings)`, `charge(source, amount, context, settings)` e `refund(source, amount, context, settings)`. Un pagamento approvato deve conservare la ricevuta in `context.paymentReceipt`; cxg-tattoos la usa per inviare l'eventuale rimborso allo stesso sistema di pagamento. Per un'economia personalizzata, i callback standalone `tryCharge` e `refund` sono la modalità di configurazione diretta.

## Permessi amministrativi

I permessi vengono verificati sul server per aprire e usare il pannello amministrativo. Nascondere o modificare l'interfaccia client non concede l'accesso.

La configurazione iniziale usa il framework rilevato e ACE come fallback:

```lua
Config.Permissions = {
    framework = 'auto', -- auto | qbx | qbcore | esx | standalone
    mode = 'hybrid',    -- framework | ace | hybrid | custom
    acePrefix = 'cxg-tattoos.',
    resources = {
        qbx = 'qbx_core',
        qbcore = 'qb-core',
        esx = 'es_extended',
    },
    bindings = {
        admin = {
            ace = { 'cxg-tattoos.admin', 'group.admin', 'admin' },
            qbx = { 'god', 'admin', 'group.admin' },
            qbcore = { 'god', 'admin', 'group.admin' },
            esx = { 'superadmin', 'admin' },
        },
    },
}
```

La modalità `framework` consulta i ruoli del framework. `ace` usa le voci ACE del binding. `hybrid` consente l’accesso tramite uno qualsiasi dei due metodi. In modalità `standalone`, l'autorizzazione tramite framework non è disponibile; configura ACE o un controllo personalizzato.

Per esempio, per consentire l'accesso ai membri del principal ACE `group.admin`:

```cfg
add_ace group.admin cxg-tattoos.admin allow
```

Per delegare la decisione al tuo sistema, usa `mode = 'custom'`. Il callback riceve l'id del giocatore, il permesso, il contesto dell'operazione e il binding configurato; solo il valore booleano `true` autorizza:

```lua
Config.Permissions.mode = 'custom'
Config.Permissions.custom = {
    hasPermission = function(source, permission, context, binding)
        return exports.my_permissions:hasPermission(source, permission) == true
    end,
}
```

Adatta `my_permissions` all'API installata sul server. Se il callback manca, fallisce o restituisce un altro valore, l'accesso viene negato.

Si configura anche il comando che apre il pannello. `permission` deve corrispondere a una chiave di `Config.Permissions.bindings`:

```lua
Config.AdminCommand.enabled = true
Config.AdminCommand.name = 'tattooadmin'
Config.AdminCommand.permission = 'admin'
```

Con questi valori, il permesso `admin` protegge il comando `/tattooadmin` e le azioni amministrative. Imposta `enabled = false` per disattivare il comando; il permesso viene comunque verificato negli altri percorsi di amministrazione.

### File di integrazione modificabili

I bridge modificabili raggruppano i collegamenti ai sistemi esterni. Per un permesso o un pagamento personalizzato, è preferibile configurare i callback descritti sopra. Se adatti un bridge esistente, mantienine il contratto:

| File o gruppo | Uso | Contratto dell'adattatore |
| --- | --- | --- |
| `bridge/permissions/server.lua` | Selezione del framework e applicazione della modalità `framework`, `ace`, `hybrid` o `custom` | `TattooPermissions.Has(source, permission, context)` restituisce `true` solo in caso di autorizzazione |
| `bridge/permissions/registry.lua` | Registrazione e utilità comuni dei permessi | `TattooPermissionBridge.register(name, adapter)` |
| `bridge/permissions/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | Verifiche per ogni framework o modalità senza framework | `isAvailable(settings)` e `hasPermission(source, binding, settings, permission)`; accetta `context` aggiuntivo se adattato |
| `bridge/payments/server.lua` | Selezione del provider, addebito e rimborso | `Config.TryChargePlayer(source, totalAmount, context)` e `Config.RefundPlayer(source, totalAmount, context)` |
| `bridge/payments/registry.lua` | Registrazione e utilità comuni dei pagamenti | `TattooPaymentBridge.register(name, adapter)` e utilità per le ricevute |
| `bridge/payments/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | Operazioni di pagamento per framework o tramite callback personalizzati | `isAvailable(settings)`, `charge(...)` e `refund(...)` |
| `bridge/appearance.lua` | Eventi di caricamento della skin e richiesta dei tatuaggi salvati | Richiede l'elenco del personaggio e lo applica al termine del caricamento dell'aspetto |

Il callback dei permessi riceve anche `context` come quinto argomento quando viene invocato dal bridge. Il registro contiene i provider inclusi (`qbx`, `qbcore`, `esx`, `standalone`); le opzioni personalizzate non richiedono l'aggiunta di un altro provider.

In un adattatore di pagamento, mantieni la registrazione della ricevuta con `TattooPaymentBridge.setReceipt(context, provider, account, amount, identifier, data)`. Il rimborso deve verificare lo stesso provider e importo con `getReceipt(context, provider, amount)` e contrassegnare la ricevuta come rimborsata dopo aver confermato il rimborso. Adatta il file del provider già in uso; per un'integrazione personalizzata senza modificare gli adattatori, usa i callback standalone.

## Aspetto e caricamento del personaggio

La risorsa ascolta gli eventi comuni di `illenium-appearance`, `fivem-appearance`, QBCore, ESX e `spawnmanager`; quindi recupera e riapplica i tatuaggi salvati. In Qbox, la configurazione dell'anteprima multicharacter usa `playerskins.skin` per mostrare i tatuaggi salvati nella schermata di selezione del personaggio.

Se il sistema di aspetto usa un evento diverso, richiedi l'applicazione dopo il caricamento della skin:

```lua
TriggerServerEvent('cxg-tattoos:fetchMyTattoos')
```

L'evento restituisce al client i tatuaggi del personaggio attuale. Non inviare l'elenco da una fonte scelta dal giocatore: la proprietà viene determinata e convalidata sul server.

L'anteprima multicharacter di Qbox si configura con questi campi:

```lua
Config.QbxMulticharacterPreview.enabled = true
Config.QbxMulticharacterPreview.resource = 'qbx_core'
Config.QbxMulticharacterPreview.playerskinsTable = 'playerskins'
Config.QbxMulticharacterPreview.playersTable = 'players'
Config.QbxMulticharacterPreview.syncExistingOnStart = true
```

`enabled` attiva l'integrazione; `resource` indica il nome installato di Qbox. `playerskinsTable` e `playersTable` identificano le tabelle di aspetto e personaggi usate dall'installazione. `syncExistingOnStart` permette di sincronizzare all'avvio di cxg-tattoos i tatuaggi già salvati, così che compaiano anche nella selezione multicharacter. Se il server ha rinominato le tabelle, aggiorna questi due campi. Non è necessario modificare `qbx_core`.
