# Integrações

cxg-tattoos pode se conectar a diferentes frameworks para cobrar compras e verificar permissões administrativas. A integração de aparência reaplica as tatuagens salvas quando o personagem carrega ou troca de skin. Cada parte é configurada separadamente.

Consulte também [Introdução](https://docs.cxgstudios.com/docs/pt-BR/01-cxg-tattoos/01-introduccion.md), [Instalação](https://docs.cxgstudios.com/docs/pt-BR/01-cxg-tattoos/02-instalacion.md), [Configuração](https://docs.cxgstudios.com/docs/pt-BR/01-cxg-tattoos/03-configuracion.md), [Catálogo](https://docs.cxgstudios.com/docs/pt-BR/01-cxg-tattoos/04-catalogo.md) e [Interface](https://docs.cxgstudios.com/docs/pt-BR/01-cxg-tattoos/06-interfaz.md).

## Frameworks disponíveis

| Sistema | Identificador de configuração | Recurso padrão | Pagamentos | Permissões |
| --- | --- | --- | --- | --- |
| Qbox | `qbx` | `qbx_core` | Sim | Sim |
| QBCore | `qbcore` | `qb-core` | Sim | Sim |
| ESX | `esx` | `es_extended` | Sim | Sim |
| Sem framework | `standalone` | Não se aplica | Callback próprio ou compras grátis | ACE ou verificação própria |

Com `auto`, o recurso detecta Qbox, QBCore ou ESX se estiverem iniciados; se nenhum for encontrado, usa `standalone`. Você pode definir o framework quando o servidor tiver vários ativos ou usar um nome de recurso diferente:

```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
```

As contas são verificadas na ordem indicada. A cobrança é feita em uma única conta; se o saldo não for suficiente, a seguinte será tentada. No ESX, `esxAccountMap` traduz `cash` para o nome de conta `money`.

`Config.Purchases.reason` e `refundReason` identificam o motivo das transações nos providers compatíveis. Os valores iniciais são `tattoo-purchase` e `tattoo-purchase-refund`. `allowFreePurchases` permite dispensar a cobrança no adaptador standalone; isso não torna gratuitas as compras em outros frameworks.

## Pagamentos sem framework

No modo `standalone`, conecte `tryCharge` e `refund` ao recurso de economia do servidor. Os dois callbacks são necessários para aceitar compras: o reembolso devolve a cobrança se o salvamento da tatuagem falhar.

```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` representa a API do seu servidor; substitua-a pelo nome e pelas chamadas reais. Para permitir compras sem custo intencionalmente, defina `allowFreePurchases = true`.

Os adaptadores de pagamento expõem `isAvailable(settings)`, `charge(source, amount, context, settings)` e `refund(source, amount, context, settings)`. Um pagamento aprovado deve manter o recibo em `context.paymentReceipt`; cxg-tattoos o usa para enviar qualquer reembolso ao mesmo sistema. Para uma economia própria, os callbacks standalone `tryCharge` e `refund` são a forma direta de configuração.

## Permissões administrativas

As permissões são verificadas no servidor para abrir e operar o painel administrativo. Ocultar ou alterar a interface do cliente não concede acesso.

A configuração inicial usa o framework detectado e ACE como 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' },
        },
    },
}
```

O modo `framework` consulta os cargos do framework. `ace` usa as entradas ACE do binding. `hybrid` aceita qualquer um dos dois caminhos. Em `standalone`, a autorização do framework não está disponível; configure ACE ou uma verificação própria.

Por exemplo, para permitir membros do principal ACE `group.admin`:

```cfg
add_ace group.admin cxg-tattoos.admin allow
```

Para delegar uma decisão ao seu próprio sistema, use `mode = 'custom'`. O callback recebe o ID do jogador, a permissão, o contexto da operação e o binding configurado; somente o booleano `true` autoriza:

```lua
Config.Permissions.mode = 'custom'
Config.Permissions.custom = {
    hasPermission = function(source, permission, context, binding)
        return exports.my_permissions:hasPermission(source, permission) == true
    end,
}
```

Adapte `my_permissions` à API instalada no servidor. Se o callback não existir, falhar ou retornar outro valor, o acesso será negado.

O comando que abre o painel também é configurável. `permission` deve corresponder a uma chave de `Config.Permissions.bindings`:

```lua
Config.AdminCommand.enabled = true
Config.AdminCommand.name = 'tattooadmin'
Config.AdminCommand.permission = 'admin'
```

Com esses valores, a permissão `admin` protege o comando `/tattooadmin` e as ações administrativas. Defina `enabled = false` para desativar o comando; a permissão continua sendo verificada nos outros caminhos administrativos.

### Arquivos de integração editáveis

Os bridges editáveis agrupam conexões com sistemas externos. Para uma permissão ou pagamento personalizado, prefira configurar os callbacks explicados acima. Ao adaptar um bridge existente, preserve seu contrato:

| Arquivo ou grupo | Uso | Contrato do adaptador |
| --- | --- | --- |
| `bridge/permissions/server.lua` | Seleção do framework e aplicação do modo `framework`, `ace`, `hybrid` ou `custom` | `TattooPermissions.Has(source, permission, context)` retorna `true` somente quando autoriza |
| `bridge/permissions/registry.lua` | Registro e utilitários comuns de permissões | `TattooPermissionBridge.register(name, adapter)` |
| `bridge/permissions/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | Verificações por framework ou modo sem framework | `isAvailable(settings)` e `hasPermission(source, binding, settings, permission)`; aceita `context` adicional se adaptado |
| `bridge/payments/server.lua` | Seleção do provider, cobrança e reembolso | `Config.TryChargePlayer(source, totalAmount, context)` e `Config.RefundPlayer(source, totalAmount, context)` |
| `bridge/payments/registry.lua` | Registro e utilitários comuns de pagamentos | `TattooPaymentBridge.register(name, adapter)` e utilitários de recibos |
| `bridge/payments/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | Operações de pagamento por framework ou callbacks próprios | `isAvailable(settings)`, `charge(...)` e `refund(...)` |
| `bridge/appearance.lua` | Eventos de carregamento de skin e solicitação de tatuagens salvas | Solicita a lista do personagem e a aplica ao terminar o carregamento da aparência |

O callback de permissão também recebe `context` como quinto argumento quando chamado pelo bridge. O registro contém os providers incluídos (`qbx`, `qbcore`, `esx`, `standalone`); opções personalizadas não exigem adicionar outro provider.

Em um adaptador de pagamentos, preserve o registro do recibo com `TattooPaymentBridge.setReceipt(context, provider, account, amount, identifier, data)`. O reembolso deve verificar o mesmo provider e valor com `getReceipt(context, provider, amount)` e marcar o recibo como reembolsado após a confirmação. Adapte o arquivo do provider que você já usa; para uma integração própria sem alterar adaptadores, use os callbacks standalone.

## Aparência e carregamento do personagem

O recurso escuta eventos comuns de `illenium-appearance`, `fivem-appearance`, QBCore, ESX e `spawnmanager`; em seguida, recupera e reaplica as tatuagens salvas. No Qbox, a configuração de prévia multicharacter usa `playerskins.skin` para exibir as tatuagens salvas na seleção de personagem.

Se o sistema de aparência usar outro evento, solicite a aplicação depois que o carregamento da skin terminar:

```lua
TriggerServerEvent('cxg-tattoos:fetchMyTattoos')
```

O evento retorna ao cliente as tatuagens do personagem atual. Não envie a lista a partir de uma fonte escolhida pelo jogador: a propriedade é resolvida e validada no servidor.

A prévia multicharacter do Qbox é ajustada com estes campos:

```lua
Config.QbxMulticharacterPreview.enabled = true
Config.QbxMulticharacterPreview.resource = 'qbx_core'
Config.QbxMulticharacterPreview.playerskinsTable = 'playerskins'
Config.QbxMulticharacterPreview.playersTable = 'players'
Config.QbxMulticharacterPreview.syncExistingOnStart = true
```

`enabled` ativa a integração; `resource` indica o nome instalado do Qbox. `playerskinsTable` e `playersTable` identificam as tabelas de aparência e personagens usadas pela instalação. `syncExistingOnStart` sincroniza tatuagens salvas ao iniciar cxg-tattoos, para que também apareçam na seleção multicharacter. Se o servidor renomeou as tabelas, atualize esses dois campos. Não é necessário modificar `qbx_core`.
