> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pluggoucash.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Regras de contrato

> Entenda as regras de negócio, validações e fluxo para solicitar transferências

## Visão geral

Antes de realizar chamadas ao endpoint de solicitação de transferência, é importante compreender os campos aceitos, os tipos de chave PIX e as regras de negócio aplicadas. Toda requisição passa por uma série de validações em cadeia — se qualquer etapa falhar, a transferência não será processada e você receberá uma resposta de erro correspondente.

***

## Campos do payload

| Campo          | Tipo    | Obrigatório | Descrição                                                            |
| -------------- | ------- | ----------- | -------------------------------------------------------------------- |
| `amount`       | integer | Sim         | Valor do saque em centavos. Mínimo: 1000 (R\$ 10,00).                |
| `key_type`     | string  | Não\*       | Tipo da chave PIX. Se omitido, assume `cpf` como padrão.             |
| `key_value`    | string  | Sim         | Valor da chave PIX de destino.                                       |
| `discount_fee` | boolean | Não         | Define como a taxa de saque é aplicada. Padrão: `true`. Veja abaixo. |

<Info>
  Se `key_type` não for informado, o sistema assume `cpf` como padrão e valida o `key_value` como CPF.
</Info>

***

## Taxa de saque (`discount_fee`)

O campo `discount_fee` controla se a taxa de saque é **descontada** do valor transferido ou **acrescida** ao valor total debitado da conta.

| Valor           | Comportamento                                                                                                                                                                                                                   |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `true` (padrão) | A taxa é descontada do valor solicitado. O valor que cai na conta destino (`liquid_amount`) é o `amount` menos as taxas.                                                                                                        |
| `false`         | A taxa é acrescentada ao valor total do saque. O valor que cai na conta destino (`liquid_amount`) é exatamente o `amount` solicitado, sem desconto de taxas. O débito na sua conta inclui o valor solicitado **mais** as taxas. |

**Exemplo com `discount_fee: true` (padrão):**

Você solicita R$ 500,00 (`amount: 50000`) e a taxa é R$ 2,00 (`200` centavos):

* Valor debitado da conta: R\$ 500,00
* Valor transferido (`liquid_amount`): R\$ 498,00

**Exemplo com `discount_fee: false`:**

Você solicita R$ 500,00 (`amount: 50000`) e a taxa é R$ 2,00 (`200` centavos):

* Valor debitado da conta: R\$ 502,00
* Valor transferido (`liquid_amount`): R\$ 500,00

<Tip>
  Use `discount_fee: false` quando precisar que o destinatário receba o valor exato informado em `amount`. Use o padrão (`true`) quando preferir que a taxa seja deduzida do valor transferido.
</Tip>

***

## Tipos de chave PIX aceitos

| Tipo     | Formato esperado no `key_value`          | Validação                                          |
| -------- | ---------------------------------------- | -------------------------------------------------- |
| `cpf`    | `12345678909` ou `123.456.789-09`        | Validado algoritmicamente (dígitos verificadores). |
| `cnpj`   | `12345678000190` ou `12.345.678/0001-90` | Validado algoritmicamente (dígitos verificadores). |
| `email`  | `usuario@email.com`                      | Validado como e-mail válido.                       |
| `phone`  | `11999999999` ou `+5511999999999`        | Deve ter entre 10 e 11 dígitos (sem o +55).        |
| `random` | `a1b2c3d4-e5f6-7890-abcd-ef1234567890`   | Deve ter no mínimo 32 caracteres alfanuméricos.    |

<Tip>
  CPF e CNPJ podem ser enviados com ou sem formatação (pontos, traços, barras). A API aceita ambos os formatos e realiza a validação algorítmica automaticamente.
</Tip>

***

## Fluxo de validação

As verificações abaixo são aplicadas **na ordem listada**. A primeira falha interrompe o processamento e retorna o erro correspondente.

<Steps>
  <Step title="Autenticação das credenciais">
    As credenciais `X-Public-Key` e `X-Secret-Key` devem estar presentes nos headers da requisição, além de serem **válidas e ativas**.

    Se as credenciais estiverem ausentes, inválidas ou inativas, a API retorna `401 Unauthorized`.

    ```json theme={null}
    {
        "error": "Credenciais inválidas",
        "message": "Chave não encontrada ou inativa"
    }
    ```
  </Step>

  <Step title="Permissão da credencial">
    A credencial utilizada deve possuir permissão do tipo **cashout** (apenas saídas) ou **all** (ambas). Credenciais do tipo apenas entrada não podem solicitar transferências.

    Se a credencial não tiver permissão, a API retorna `403 Forbidden`.

    ```json theme={null}
    {
        "success": false,
        "message": "Esta credencial não tem permissão para realizar esta operação.",
        "data": null
    }
    ```
  </Step>

  <Step title="Status da conta">
    A conta do usuário deve estar com o status **approved** (aprovada). Contas pendentes, em análise ou rejeitadas não podem solicitar saques.

    Se a conta não estiver aprovada, a API retorna `403 Forbidden`.

    ```json theme={null}
    {
        "success": false,
        "message": "Sua conta precisa estar aprovada para solicitar saques.",
        "data": null
    }
    ```
  </Step>

  <Step title="Conta não bloqueada">
    A conta do usuário não pode estar bloqueada. Contas bloqueadas perdem temporariamente o acesso a todas as funcionalidades da API.

    Se a conta estiver bloqueada, a API retorna `403 Forbidden`.

    ```json theme={null}
    {
        "success": false,
        "message": "Sua conta está bloqueada. Entre em contato com o suporte.",
        "data": null
    }
    ```
  </Step>

  <Step title="Validação dos campos">
    Os campos obrigatórios devem ser preenchidos com valores válidos. O tipo de chave PIX deve ser um dos aceitos (`cpf`, `cnpj`, `email`, `phone`, `random`) e o `key_value` deve seguir o formato correspondente. CPF e CNPJ são validados algoritmicamente.

    Se houver erros de validação, a API retorna `422 Unprocessable Entity` com os erros detalhados por campo.

    ```json theme={null}
    {
        "success": false,
        "message": "Erro de validação nos dados fornecidos",
        "data": {
            "errors": {
                "amount": ["O valor mínimo para saque é R$ 10,00."],
                "key_value": ["CPF inválido."],
                "key_type": ["O tipo de chave deve ser: cpf, cnpj, email, phone ou random."]
            }
        }
    }
    ```
  </Step>

  <Step title="Valor mínimo">
    O valor do saque (`amount`) deve ser de no mínimo **1.000 centavos** (R\$ 10,00).

    Se o valor for inferior ao mínimo, a API retorna `400 Bad Request`.

    ```json theme={null}
    {
        "success": false,
        "message": "O valor mínimo para saque é R$ 10,00.",
        "data": null
    }
    ```
  </Step>

  <Step title="Saldo disponível">
    O usuário deve ter saldo disponível suficiente para cobrir o saque. O saldo é verificado em tempo real no momento da requisição.

    * Com `discount_fee: true` (padrão), o saldo deve cobrir o valor de `amount`.
    * Com `discount_fee: false`, o saldo deve cobrir o valor de `amount` **mais** as taxas de saque.

    Se o saldo for insuficiente, a API retorna `400 Bad Request` com os detalhes do saldo.

    ```json theme={null}
    {
        "success": false,
        "message": "Saldo insuficiente para saque.",
        "data": {
            "available_balance": 30000,
            "requested_amount": 50000
        }
    }
    ```
  </Step>

  <Step title="Limite por solicitação">
    O valor não pode ultrapassar o limite por solicitação configurado para o usuário (se houver). Esse limite é definido individualmente por conta.

    Se o valor exceder o limite, a API retorna `400 Bad Request`.

    ```json theme={null}
    {
        "success": false,
        "message": "O valor solicitado ultrapassa o limite por solicitação de saque.",
        "data": {
            "valid": false,
            "limit": 500000,
            "requested": 600000
        }
    }
    ```
  </Step>

  <Step title="Limite diário">
    O valor não pode ultrapassar o limite diário de saques restante do usuário. O limite considera a soma de todos os saques com status `paid` e `pending` realizados no dia.

    Se o valor exceder o limite diário restante, a API retorna `400 Bad Request`.

    ```json theme={null}
    {
        "success": false,
        "message": "O valor solicitado ultrapassa o limite diário de saques.",
        "data": {
            "valid": false,
            "daily_limit": 1000000,
            "withdrawn_today": 800000,
            "remaining": 200000,
            "requested": 500000
        }
    }
    ```
  </Step>

  <Step title="Valor líquido após taxas">
    Após o cálculo das taxas de saque, o valor líquido transferido deve ser maior que **R\$ 0,00**.

    * Com `discount_fee: true` (padrão), a taxa é descontada de `amount` — o `liquid_amount` deve ser positivo após o desconto.
    * Com `discount_fee: false`, o `liquid_amount` é igual ao `amount` solicitado; a taxa é acrescentada ao total debitado da conta.

    Se o valor líquido for insuficiente, a API retorna `400 Bad Request`.

    ```json theme={null}
    {
        "success": false,
        "message": "O valor do saque após as taxas deve ser maior que R$ 0,00.",
        "data": null
    }
    ```
  </Step>

  <Step title="Horário de funcionamento">
    Dependendo da adquirente configurada, saques podem estar restritos ao horário comercial, das **09:00 às 22:00** (horário de Brasília).

    Se a solicitação for feita fora do horário permitido, a API retorna `400 Bad Request`.

    ```json theme={null}
    {
        "success": false,
        "message": "Saques estão disponíveis apenas das 09:00 às 22:00. Tente novamente dentro do horário.",
        "data": null
    }
    ```
  </Step>

  <Step title="Processamento na adquirente">
    Se o saque for auto-aprovado, a comunicação com a adquirente de cash-out deve ser bem-sucedida para que a transferência PIX seja realizada.

    Se houver falha na comunicação, a API retorna `500 Internal Server Error`.

    ```json theme={null}
    {
        "success": false,
        "message": "Erro ao processar o saque. Tente novamente mais tarde.",
        "data": null
    }
    ```
  </Step>
</Steps>

***

## Resposta de sucesso

Se todas as validações passarem e o saque for processado com sucesso, a API retorna `201 Created` com os seguintes dados:

| Campo                | Tipo    | Descrição                                                                                                                            |
| -------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `data.id`            | string  | UUID único do saque criado                                                                                                           |
| `data.amount`        | integer | Valor solicitado em centavos                                                                                                         |
| `data.liquid_amount` | integer | Valor líquido transferido em centavos. Com `discount_fee: true`, é `amount` menos taxas; com `false`, é igual ao `amount` solicitado |
| `data.pix_key_type`  | string  | Tipo da chave PIX utilizada                                                                                                          |
| `data.pix_key`       | string  | Valor da chave PIX de destino                                                                                                        |
| `data.status`        | string  | Status inicial do saque                                                                                                              |
| `data.created_at`    | string  | Data/hora de criação no formato `YYYY-MM-DD HH:mm:ss`                                                                                |

```json theme={null}
{
    "success": true,
    "message": "Saque solicitado e processado com sucesso!",
    "data": {
        "id": "e5f6a1b2-c3d4-7890-efgh-4567890abcde",
        "amount": 50000,
        "liquid_amount": 50000,
        "pix_key_type": "cpf",
        "pix_key": "12345678909",
        "status": "pending",
        "created_at": "2026-01-29 14:58:00"
    }
}
```

***

## Resumo dos códigos de resposta

| Código | Situação                                                        |
| ------ | --------------------------------------------------------------- |
| `201`  | Saque solicitado com sucesso                                    |
| `400`  | Regra de negócio violada (saldo, limites, valor, horário)       |
| `401`  | Credenciais ausentes, inválidas ou inativas                     |
| `403`  | Sem permissão (credencial, conta não aprovada, conta bloqueada) |
| `422`  | Erro de validação nos dados enviados                            |
| `500`  | Erro interno ou falha na comunicação com a adquirente           |
