---
agentTools:
  projectIndex: https://docs.ninepay.com.br/llms.txt
  projectSearch: https://docs.ninepay.com.br/agentSearch?query=term1%20term2
---

# Introdução à API

Ambientes, autenticação, formato das respostas e dos erros, paginação e hash de cartões

Bem-vindo à referência da **API NinePay**. É através desta API que você integra o seu sistema ao nosso.

Nossa API é [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) e todas as suas respostas são em [JSON](https://www.json.org/), no endpoint base:

```text Produção
https://payments.cefis.com.br/api/v1/
```

A lista completa de endpoints, com parâmetros, respostas e exemplos em várias linguagens, está na [Referência da API](/reference/criar-novo-pagamento).

## Ambientes

Além do ambiente de **produção** temos disponível o ambiente **sandbox** para a realização de testes de integração. Toda a comunicação com o ambiente sandbox deve ser feita através da URL:

```text Sandbox
https://api.sandbox.cefispay.com.br/api/v1/
```

Veja como pedir acesso em [Ambiente de Testes](/docs/sandbox).

## Autenticação

Todas as requisições que requerem autenticação devem informar no header `Authorization` o token de API enviado pela nossa equipe, observando sempre o ambiente desejado, no seguinte formato:

```http
Authorization: Bearer <token>
```

> ❗️ O token é segredo
>
> Use o token só no seu back-end. Nunca o coloque em código que roda no navegador ou no app do cliente.

Prefixos das chaves (`sk_prod_` e `sk_hmlg_`), criação, rotação e expiração estão em [Autenticação](/docs/autenticacao).

## Headers

Recomendamos que os cabeçalhos das requisições sejam corretamente adicionados para trabalhar com os tipos de dados enviados e recebidos da API:

- Todas as requisições devem conter o header `Content-Type: application/json`, a menos que o endpoint específico defina diferente.
- Todas as requisições devem conter o header `Accept: application/json`, a menos que o endpoint específico defina diferente.

## Respostas

- Os recursos vêm dentro de `data`: `GET /customers/{id}` responde `{ "data": { ... } }`.
- As criações respondem **201**. `POST /payments` responde `{ "customer", "payment", "invoice_url" }` (o `invoice_url` só no boleto) e `POST /subscriptions` responde `{ "customer", "subscription" }`.
- Valores sempre em centavos (inteiro): R$ 50,00 é `5000`.

## Erros

Todo erro tem o mesmo formato:

```json
{
  "code": "VALIDATION_ERROR",
  "message": "Os dados informados são inválidos.",
  "errors": { "email": ["O campo email é obrigatório."] },
  "timestamp": "2026-10-22T12:03:54+00:00",
  "request_id": "64d62d36-e797-45ed-a9d5-c203bde81032",
  "documentation_url": "https://docs.ninepay.com.br",
  "suggestion": "Corrija os campos e tente novamente."
}
```

`errors` só vem na validação, com uma **lista** de mensagens por campo. `suggestion` vem quando há uma. Guarde o `request_id` para falar com o suporte.

| `code` | HTTP | Quando |
| --- | --- | --- |
| `AUTHENTICATION_ERROR` | 401 | Token ausente ou inválido |
| `FORBIDDEN_ERROR` | 403 | O recurso não é da sua empresa. Em várias rotas, um id que não existe também responde 403, para não revelar quais ids existem |
| `COMPANYBLOCKED_ERROR` | 403 | A conta está suspensa |
| `RESOURCE_NOT_FOUND_ERROR` | 404 | O recurso não existe |
| `ROUTE_NOT_FOUND_ERROR` | 404 | A rota não existe |
| `METHOD_NOT_ALLOWED_ERROR` | 405 | O método não vale para a rota (ex.: `PUT /customers` sem o id) |
| `INVALID_STATE_ERROR` | 400 | O recurso não está num estado que permita a ação (ex.: cancelar um pagamento já pago) |
| `VALIDATION_ERROR` | 422 | Dados inválidos; veja `errors` |
| `REFUND_NOT_ALLOWED` | 422 | O pagamento não pode ser reembolsado |
| `TOO_MANY_ATTEMPTS` | 429 | Muitas requisições; respeite o cabeçalho `Retry-After` |
| `UNEXPECTED_ERROR` | 500 | Erro nosso; se repetir, fale com o suporte com o `request_id` |

## Paginação

As listagens recebem `page` (a partir de 1) e `limit` (itens por página: **10** por padrão, de 1 a **100**). A resposta traz `data` (os itens), `links` e `meta` (`current_page`, `last_page`, `per_page`, `total`). Para percorrer tudo, avance `page` até `meta.last_page`.

## Datas

- Datas de calendário (`due_date`, `next_payment`) vão como `AAAA-MM-DD` na requisição.
- Nas respostas, os campos de data e hora aparecem em dois formatos: ISO 8601 em UTC (`2026-10-27T03:00:00.000000Z`, em `due_date` e `ref_date` do pagamento) e `AAAA-MM-DD HH:MM:SS` no horário de Brasília (`created_at` e `updated_at`). Leia o campo pelo formato dele.

## Identificadores

Cada recurso tem um `id` numérico e um `uuid`. Use o `id` nas rotas autenticadas e o **`uuid`** em tudo que é público (o link de pagamento, o checkout e o PDF do boleto).

## Hash de cartões

O hash de um cartão é uma versão criptografada de todos os dados do cartão do cliente. Essa é a maneira mais segura de enviar os dados do cartão do seu cliente diretamente para a gente. Abaixo detalhamos como ele funciona e como obter um hash a partir dos dados inseridos pelo cliente.

> 🚧 Só no front-end
>
> Esse fluxo deve ser executado no front-end, seja ele web ou mobile. Os dados do cartão do cliente nunca devem ser enviados para o seu back-end; já o hash do cartão pode ser enviado para o back-end sem problemas.

### Gerando uma encryption key

A encryption key é uma chave pública RSA usada para encriptar os dados do cartão. Essa chave só pode ser usada uma vez: sempre que precisar encriptar um novo cartão, gere uma nova encryption key.

Para gerar uma encryption key, faça uma requisição `POST` para a rota `/encryption_keys` da API enviando como parâmetro o seu `merchant_id`. Ela não usa o token da API (nunca o coloque no front-end): o `merchant_id` identifica a sua conta, e um `merchant_id` que não existe responde 401.

A requisição deverá ter esse formato:

```bash cURL
curl -X POST https://payments.cefis.com.br/api/v1/encryption_keys \
  -H 'Content-Type: application/json' \
  -d '{"merchant_id":"SEU_MERCHANT_ID"}'
```

Como resposta você receberá um objeto JSON no seguinte formato:

```json
{
  "id": 1111,
  "public_key": "-----BEGIN PUBLIC KEY-----\n ... \n-----END PUBLIC KEY-----\n",
  "ip_address": "000.000.000.000",
  "created_at": "2017-07-03"
}
```

<a id="encriptando-os-dados-do-cartão"></a>

### Encriptando os dados do cartão

Para encriptar os dados do cartão, primeiro formate-os corretamente: crie uma string JSON contendo todos os dados do cartão no seguinte formato:

```json
{"card_number":"1111111111111111","card_holder_name":"Jose Silva","card_expiration_date":"11/2021","card_cvv":"111"}
```

Em seguida faça a criptografia RSA dessa string utilizando a chave pública (`public_key`) gerada no passo anterior, com padding do tipo **PKCS1**.

Após criptografar os dados, converta o resultado para base64. Você terá algo parecido com isto:

```text
GprWNDlg+MKGgtr6y9wJgz7oOUxGuhhdX3EwydmoOvb+yNDWrjDKktDtWicReOrvSo0u5rsNvCqBFjyoMfaRXn4Qq3KdV8vuuFXubb4FT3OcSSVpu6ddaOjm2tf82+GKjdCy54Lgw4T0m9mWdLPveh/zkYP0+4lhHCFhBKX5EqBdR4918wP5oUV1KpzV4V94ldSA+Cy2n1NUxyUiSnv87H2m+HkdqKDIcX9X8KEtUmorC/EjTPzoeEdpRdj8t3ThcL73mirJvDcYthSdT/ADyaFQ2hMRMkKEVOQjUYMn76vzWyQkqsZ+HVQlxQMOBVHPh5yfrmi1HAVd1jLQuOK8wQ==
```

O último passo é concatenar o `id` da sua encryption key (recebido na resposta da requisição anterior) com a string em base64 que representa os dados do cartão, da seguinte forma:

```text
encryption_key_id + "_" + base64_encrypted_card
```

O resultado será o seu card hash:

```text
1111_GprWNDlg+MKGgtr6y9wJgz7oOUxGuhhdX3EwydmoOvb+yNDWrjDKktDtWicReOrvSo0u5rsNvCqBFjyoMfaRXn4Qq3KdV8vuuFXubb4FT3OcSSVpu6ddaOjm2tf82+GKjdCy54Lgw4T0m9mWdLPveh/zkYP0+4lhHCFhBKX5EqBdR4918wP5oUV1KpzV4V94ldSA+Cy2n1NUxyUiSnv87H2m+HkdqKDIcX9X8KEtUmorC/EjTPzoeEdpRdj8t3ThcL73mirJvDcYthSdT/ADyaFQ2hMRMkKEVOQjUYMn76vzWyQkqsZ+HVQlxQMOBVHPh5yfrmi1HAVd1jLQuOK8wQ==
```

Pronto: os dados do cartão do cliente já estão em um formato seguro para serem transportados pela rede e podem ser enviados para o seu back-end dar sequência ao fluxo (no campo `card_hash` do [`POST /payments`](/reference/criar-novo-pagamento)).

> 📘 Validade do card hash
>
> Cada card hash pode ser usado apenas uma vez e vale por no máximo 30 minutos após a geração da encryption key. Caso precise usar o cartão mais de uma vez, faça uma requisição para a rota de cartões e salve esse cartão vinculado ao usuário que o detém: você receberá um ID único que poderá ser usado em novas transações com o mesmo cartão.

## Suporte

Dúvidas sobre a integração: [ti@ninepay.com.br](mailto:ti@ninepay.com.br). Termos de uso: [bit.ly/cefispay-contrato](https://bit.ly/cefispay-contrato).
