A autenticação é o primeiro passo para utilizar a API da Nuvende. Este processo garante que apenas aplicações autorizadas possam acessar os recursos protegidos da API.
POST /api/v2/auth/login com scopes necessários (referência)POST /api/v2/auth/refresh antes do token expirar (referência)POST /api/v2/auth/logout para invalidar o token (referência)A API da Nuvende utiliza um sistema de autenticação em duas etapas:
O Basic Auth é um método simples e seguro para enviar credenciais. Ele funciona codificando suas credenciais em Base64 e enviando-as no cabeçalho Authorization da requisição. Isso garante que suas credenciais sejam transmitidas de forma segura.
O token de acesso é uma string única que representa sua autorização para usar a API. Ele tem as seguintes características:
Antes de fazer a requisição, você precisa:
A requisição é enviada para o endpoint /api/v2/auth/login com:
A API da Nuvende:
A API retorna:
Este token deve ser incluído em todas as requisições subsequentes no cabeçalho Authorization: Bearer {token}.
Antes de fazer a requisição, você precisa preparar suas credenciais. Vamos ver como fazer isso:
Primeiro, você precisa ter suas credenciais fornecidas pela Nuvende:
As credenciais devem ser codificadas em Base64 no formato client_id:client_secret:
# Exemplo de como gerar o Base64
echo -n "seu_client_id:seu_client_secret" | base64
# Resultado: c2V1X2NsaWVudF9pZDpzZXVfY2xpZW50X3NlY3JldA==
https://api-h.nuvende.com.br/api/v2/auth/loginPOSTapplication/x-www-form-urlencodedBasic {suas_credenciais_base64}client_credentialscurl -X POST https://api-h.nuvende.com.br/api/v2/auth/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic YjhhMDc1MTgtZDBjZS00ODk3LThlOGUtM2VjOWM1NmMyNjMyOnlvdXItc2VjcmV0LWhlcmU=" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "scope=cob.read cob.write webhooks.read webhooks.write pix.read pix.write contas.read contas.saldo.read contas.extrato.read contas.chaves.read kyc.background-check.natural-person kyc.background-check.legal-person"
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"expires_in": 3600
}
Explicação dos Campos:
{
"error": "invalid_client",
"error_description": "Client authentication failed"
}
Após obter o token, você deve incluí-lo em todas as requisições subsequentes:
curl -X GET https://api-h.nuvende.com.br/api/v2/protected-resource \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
-H "Content-Type: application/json"
Importante: O token deve ser precedido pela palavra "Bearer" e um espaço.
Agora vamos ver como implementar a autenticação em código. Vamos criar uma classe que gerencia todo o processo de autenticação de forma automática.
Vamos criar uma classe NuvendeAuth que:
const axios = require('axios');
class NuvendeAuth {
constructor(clientId, clientSecret, baseUrl) {
// Armazenar credenciais fornecidas
this.clientId = clientId;
this.clientSecret = clientSecret;
this.baseUrl = baseUrl;
// Variáveis para gerenciar o token
this.accessToken = null; // Token atual
this.tokenExpiry = null; // Timestamp de expiração
}
/**
* Gera o header Basic Auth necessário para autenticação
* Converte client_id:client_secret para Base64
*/
getBasicAuthHeader() {
const credentials = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString('base64');
return `Basic ${credentials}`;
}
/**
* Obtém um token de acesso válido
* Se já existe um token válido, retorna ele
* Se não existe ou expirou, faz uma nova requisição
*/
async getAccessToken() {
// Verificar se o token ainda é válido (com margem de 5 minutos)
const now = Date.now();
const margin = 5 * 60 * 1000; // 5 minutos em millisegundos
if (this.accessToken && this.tokenExpiry && (now + margin) < this.tokenExpiry) {
console.log('Usando token existente');
return this.accessToken;
}
console.log('Obtendo novo token de acesso...');
try {
// Fazer requisição de autenticação
const response = await axios.post(`${this.baseUrl}/api/v2/auth/login`,
new URLSearchParams({
grant_type: 'client_credentials',
scope: 'cob.read cob.write webhooks.read webhooks.write pix.read pix.write contas.read contas.saldo.read contas.extrato.read contas.chaves.read kyc.background-check.natural-person kyc.background-check.legal-person'
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': this.getBasicAuthHeader()
}
}
);
// Armazenar o token e calcular expiração
this.accessToken = response.data.access_token;
this.tokenExpiry = now + (response.data.expires_in * 1000);
console.log(`Token obtido com sucesso. Expira em ${response.data.expires_in} segundos`);
return this.accessToken;
} catch (error) {
console.error('Erro na autenticação:', error.response?.data || error.message);
throw error;
}
}
/**
* Faz uma requisição autenticada para qualquer endpoint
* Automaticamente obtém o token se necessário
*/
async makeAuthenticatedRequest(method, endpoint, data = null) {
// Garantir que temos um token válido
const token = await this.getAccessToken();
const config = {
method,
url: `${this.baseUrl}${endpoint}`,
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
};
// Adicionar dados se fornecidos
if (data) {
config.data = data;
}
try {
const response = await axios(config);
return response;
} catch (error) {
// Se o token expirou, tentar obter um novo e refazer a requisição
if (error.response?.status === 401) {
console.log('Token expirado, obtendo novo token...');
this.accessToken = null; // Forçar renovação
const newToken = await this.getAccessToken();
// Refazer a requisição com o novo token
config.headers.Authorization = `Bearer ${newToken}`;
return axios(config);
}
throw error;
}
}
}
// Exemplo de uso prático
async function exemploCompleto() {
// Inicializar o cliente de autenticação
const nuvende = new NuvendeAuth(
process.env.NUVENDE_CLIENT_ID, // Suas credenciais
process.env.NUVENDE_CLIENT_SECRET, // do arquivo .env
'https://api-h.nuvende.com.br' // Ambiente de homologação
);
try {
// Fazer uma requisição autenticada
console.log('Fazendo requisição autenticada...');
const response = await nuvende.makeAuthenticatedRequest('GET', '/api/v2/protected-resource');
console.log('Resposta recebida:', response.data);
} catch (error) {
console.error('Erro na requisição:', error.response?.data || error.message);
}
}
// Executar exemplo
exemploCompleto();
npm install axios
.env):NUVENDE_CLIENT_ID=seu_client_id_aqui
NUVENDE_CLIENT_SECRET=seu_client_secret_aqui
NUVENDE_BASE_URL=https://api-h.nuvende.com.br
const nuvende = new NuvendeAuth(
process.env.NUVENDE_CLIENT_ID,
process.env.NUVENDE_CLIENT_SECRET,
process.env.NUVENDE_BASE_URL
);
// Fazer requisições autenticadas
const response = await nuvende.makeAuthenticatedRequest('GET', '/api/v2/some-endpoint');
Para manter suas credenciais seguras, sempre use variáveis de ambiente:
# .env
NUVENDE_CLIENT_ID=seu_client_id_aqui
NUVENDE_CLIENT_SECRET=seu_client_secret_aqui
NUVENDE_BASE_URL=https://api-h.nuvende.com.br
Por que usar variáveis de ambiente?
Os escopos definem quais operações sua aplicação pode realizar. É importante solicitar apenas os escopos necessários:
kyc.background-check.natural-person - Verificar antecedentes de pessoas físicaskyc.background-check.legal-person - Verificar antecedentes de pessoas jurídicascob.write - Criar e atualizar cobranças Pixcob.read - Consultar cobranças Pix existentespix.write - Iniciar e confirmar pagamentos Pixpix.read - Listar pagamentos Pixwebhooks.read - Consultar webhooks configuradoswebhooks.write - Criar e atualizar webhooksmerchants.read - Consultar dados de estabelecimentosmerchants.write - Gerenciar estabelecimentosterminals.read - Consultar terminais POSterminals.write - Gerenciar terminais POStransactions.read - Consultar transaçõestransactions.write - Processar transaçõesDica: Solicite apenas os escopos que realmente precisa. Isso segue o princípio de "menor privilégio" e aumenta a segurança.
| Código | Significado | Quando Ocorre | Como Resolver |
|---|---|---|---|
200 | OK | Requisição bem-sucedida | - |
400 | Bad Request | Parâmetros inválidos ou ausentes | Verificar parâmetros enviados |
401 | Unauthorized | Credenciais inválidas ou token expirado | Verificar credenciais ou renovar token |
403 | Forbidden | Sem permissão para o recurso | Verificar escopos solicitados |
500 | Internal Server Error | Erro interno do servidor | Tentar novamente mais tarde |
class NuvendeErrorHandler {
static handleAuthError(error) {
const status = error.response?.status;
const data = error.response?.data;
switch (status) {
case 400:
console.error('❌ Parâmetros inválidos:', data);
throw new Error(`Parâmetros inválidos: ${data?.error_description || 'Verifique os dados enviados'}`);
case 401:
console.error('❌ Credenciais inválidas:', data);
throw new Error('Credenciais inválidas. Verifique client_id e client_secret.');
case 403:
console.error('❌ Acesso negado:', data);
throw new Error('Acesso negado. Verifique se você tem permissão para este recurso.');
case 500:
console.error('❌ Erro interno do servidor:', data);
throw new Error('Erro interno do servidor. Tente novamente em alguns minutos.');
default:
console.error('❌ Erro inesperado:', error.message);
throw new Error(`Erro inesperado: ${error.message}`);
}
}
static async retryRequest(requestFn, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await requestFn();
} catch (error) {
console.log(`Tentativa ${attempt}/${maxRetries} falhou:`, error.message);
if (attempt === maxRetries) {
throw error;
}
// Aguardar antes da próxima tentativa (backoff exponencial)
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
}
// Exemplo de uso com tratamento de erros
async function exemploComTratamentoDeErros() {
const nuvende = new NuvendeAuth(
process.env.NUVENDE_CLIENT_ID,
process.env.NUVENDE_CLIENT_SECRET,
'https://api-h.nuvende.com.br'
);
try {
// Usar retry automático para requisições
const response = await NuvendeErrorHandler.retryRequest(async () => {
return await nuvende.makeAuthenticatedRequest('GET', '/api/v2/protected-resource');
});
console.log('✅ Requisição bem-sucedida:', response.data);
} catch (error) {
NuvendeErrorHandler.handleAuthError(error);
}
}
Para facilitar o debugging, adicione logs informativos:
// Configurar logs detalhados
const debug = process.env.NODE_ENV === 'development';
function logRequest(method, url, headers) {
if (debug) {
console.log(`🔄 ${method} ${url}`);
console.log('📋 Headers:', headers);
}
}
function logResponse(response) {
if (debug) {
console.log(`✅ ${response.status} ${response.statusText}`);
console.log('📄 Response:', response.data);
}
}