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

# Cofre

> Como guardar cartões de crédito no Cofre via API pública e obter um cardTokenId

O **Cofre** permite enviar os dados sensíveis do cartão uma vez e receber um `cardTokenId` para reutilização segura no seu backend. O endpoint exige o produto `tokenization` habilitado na conta do merchant.

## Pré-requisitos

<Steps>
  <Step title="Produto habilitado">
    O produto **Tokenization** precisa estar habilitado para o seu merchant. A
    ativação é feita pela equipe UvviPay — solicite ao seu contato comercial.
  </Step>

  <Step title="Credenciais de API">
    Use `client-id` e `client-secret` no backend. Nunca exponha o
    `client-secret` no front-end. Veja [Autenticação](/authentication).
  </Step>
</Steps>

## Como funciona

1. Você envia `card` + `customer` para
   [`POST /v1/vault/tokenize`](/api-reference/card-tokenization/tokenize).
2. A UvviPay cria ou reutiliza o customer (`externalCustomerId`) e o cartão.
3. Se já existir um token **ativo** para o mesmo customer e cartão, a API
   devolve o `cardTokenId` existente com **HTTP 201**.
4. Caso contrário, o cartão é guardado no Cofre e a API retorna o novo
   `cardTokenId` com **HTTP 201**.

Guarde o `cardTokenId` no seu sistema. Ele identifica o cartão no Cofre.

<Warning>
  Não envie dados de cartão a partir do browser. Chame o endpoint apenas do
  seu backend e trate o PAN/CVV como dado sensível (PCI).
</Warning>

## Chamadas concorrentes

Para o mesmo customer e cartão:

* Se já houver token **ativo**, a API reutiliza o `cardTokenId` sem criar outro.
* Chamadas concorrentes sem token ativo podem ambas acionar o provedor; a
  persistência é serializada. Ao final, as respostas bem-sucedidas convergem
  para o mesmo `cardTokenId` ativo (**HTTP 201**).

Não há header de idempotência neste endpoint. Reutilize o `cardTokenId`
salvo no seu sistema sempre que possível.

## Exemplo

```bash theme={null}
curl -X POST https://api.uvvipay.com.br/v1/vault/tokenize \
  -H "Content-Type: application/json" \
  -H "client-id: SUA_CLIENT_ID" \
  -H "client-secret: SUA_CLIENT_SECRET" \
  -d '{
    "card": {
      "number": "************1111",
      "holderName": "JOAO DA SILVA",
      "securityCode": "***",
      "expirationMonth": 12,
      "expirationYear": 2029
    },
    "customer": {
      "name": "João da Silva",
      "email": "joao@exemplo.com",
      "phone": "11987654321",
      "documentNumber": "12345678901",
      "documentType": "cpf",
      "externalCustomerId": "customer-ext-00000000001"
    }
  }'
```

### Resposta (201)

```json theme={null}
{
  "cardTokenId": "550e8400-e29b-41d4-a716-446655440000"
}
```

## Campos importantes

| Campo                         | Observação                                                                         |
| ----------------------------- | ---------------------------------------------------------------------------------- |
| `customer.externalCustomerId` | Obrigatório, 20 a 255 caracteres. Identificador estável do customer no seu sistema |
| `customer.documentNumber`     | Apenas dígitos; CPF (11) ou CNPJ (14)                                              |
| `customer.documentType`       | `cpf` ou `cnpj`                                                                    |
| `card.number`                 | 13 a 19 dígitos                                                                    |
| `card.securityCode`           | CVV/CVC, 3 ou 4 dígitos                                                            |
| `card.expirationMonth`        | Inteiro de 1 a 12                                                                  |
| `card.expirationYear`         | Ano com 4 dígitos (ex.: `2029`)                                                    |

## Rate limit

`POST /v1/vault/tokenize` tem limite de **30 requisições por minuto por IP**.
Se exceder, a API responde **HTTP 429 Too Many Requests**.

Não há headers `Retry-After` nem `X-RateLimit-*` neste endpoint.

## Retries

| Situação                   | Recomendação                                                          |
| -------------------------- | --------------------------------------------------------------------- |
| `429`                      | Backoff exponencial com jitter e tente de novo                        |
| `5xx`                      | Retry com backoff exponencial e jitter; limite o número de tentativas |
| `400`, `401`, `403`, `422` | Não repita o mesmo payload sem corrigir a causa                       |

## Dados sensíveis

Nunca registre em logs, métricas ou traces:

* PAN completo (`card.number`)
* CVV/CVC (`card.securityCode`)
* `client-secret`
* network token completo ou criptogramas

## Erros

| Status | Tipo        | Quando acontece                                     |
| ------ | ----------- | --------------------------------------------------- |
| `400`  | Definitivo  | Payload inválido (validação de campos)              |
| `401`  | Definitivo  | `client-id` / `client-secret` ausentes ou inválidos |
| `403`  | Definitivo  | Produto `tokenization` não habilitado               |
| `422`  | Definitivo  | Provedor não provisionou o cartão no Cofre          |
| `429`  | Transitório | Rate limit excedido                                 |
| `5xx`  | Transitório | Falha interna ou indisponibilidade temporária       |

## Próximos passos

<CardGroup cols={2}>
  <Card title="Guardar cartão no Cofre" href="/api-reference/card-tokenization/tokenize">
    Referência completa do endpoint
  </Card>

  <Card title="Autenticação" href="/authentication">
    Headers e boas práticas de credenciais
  </Card>
</CardGroup>
