Autenticação

Login

Como realizar autenticação na API

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.

Ordem das chamadas

  1. POST /api/v2/auth/login com scopes necessários (referência)
  2. Usar o Bearer nas demais requisições
  3. POST /api/v2/auth/refresh antes do token expirar (referência)
  4. POST /api/v2/auth/logout para invalidar o token (referência)

Como Funciona a Autenticação

A API da Nuvende utiliza um sistema de autenticação em duas etapas:

  1. Envio das Credenciais: Suas credenciais (Client ID e Client Secret) são enviadas usando Basic Auth
  2. Obtenção do Token: A API retorna um token de acesso que deve ser usado em todas as requisições subsequentes

Por que Basic Auth?

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 que é um Token de Acesso?

O token de acesso é uma string única que representa sua autorização para usar a API. Ele tem as seguintes características:

  • Temporário: Expira após um período determinado (geralmente 1 hora)
  • Específico: Contém apenas as permissões (escopos) que você solicitou
  • Seguro: Deve ser mantido em segurança e não compartilhado

Fluxo de Autenticação Detalhado

1. Preparação das Credenciais

Antes de fazer a requisição, você precisa:

  • Ter suas credenciais (Client ID e Client Secret) fornecidas pela Nuvende
  • Codificar essas credenciais em Base64
  • Preparar a lista de escopos (permissões) que sua aplicação precisa

2. Envio da Requisição

A requisição é enviada para o endpoint /api/v2/auth/login com:

  • Headers apropriados (Content-Type e Authorization)
  • Parâmetros no corpo da requisição (grant_type e scope)

3. Processamento pela API

A API da Nuvende:

  • Valida suas credenciais
  • Verifica se você tem permissão para os escopos solicitados
  • Gera um token de acesso único

4. Resposta e Uso

A API retorna:

  • O token de acesso
  • O tipo do token (sempre "bearer")
  • O tempo de expiração em segundos

Este token deve ser incluído em todas as requisições subsequentes no cabeçalho Authorization: Bearer {token}.

Implementação Passo a Passo

Passo 1: Preparar as Credenciais

Antes de fazer a requisição, você precisa preparar suas credenciais. Vamos ver como fazer isso:

1.1. Obter suas Credenciais

Primeiro, você precisa ter suas credenciais fornecidas pela Nuvende:

  • Client ID: Identificador único da sua aplicação
  • Client Secret: Chave secreta para autenticação

1.2. Codificar em Base64

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==

Passo 2: Fazer a Requisição de Autenticação

2.1. Endpoint e Headers

  • URL: https://api-h.nuvende.com.br/api/v2/auth/login
  • Método: POST
  • Content-Type: application/x-www-form-urlencoded
  • Authorization: Basic {suas_credenciais_base64}

2.2. Parâmetros do Corpo da Requisição

  • grant_type: Sempre deve ser client_credentials
  • scope: Lista de permissões separadas por espaço

2.3. Exemplo Completo com cURL

curl -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"

Passo 3: Processar a Resposta

3.1. Resposta de Sucesso (HTTP 200)

{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "token_type": "bearer",
  "expires_in": 3600
}

Explicação dos Campos:

  • access_token: O token que você usará para autenticar requisições
  • token_type: Sempre será "bearer" (tipo de autenticação)
  • expires_in: Tempo de expiração em segundos (3600 = 1 hora)

3.2. Resposta de Erro (HTTP 401)

{
  "error": "invalid_client",
  "error_description": "Client authentication failed"
}

Passo 4: Usar o Token em Requisições

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.

Implementação em Código

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.

JavaScript/Node.js - Implementação Completa

Explicação da Estrutura

Vamos criar uma classe NuvendeAuth que:

  1. Armazena as credenciais de forma segura
  2. Gerencia o token automaticamente (obtém e renova quando necessário)
  3. Facilita requisições autenticadas
  4. Trata erros de forma consistente
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();

Como Usar em Seu Projeto

  1. Instalar dependências:
npm install axios
  1. Configurar variáveis de ambiente (arquivo .env):
NUVENDE_CLIENT_ID=seu_client_id_aqui
NUVENDE_CLIENT_SECRET=seu_client_secret_aqui
NUVENDE_BASE_URL=https://api-h.nuvende.com.br
  1. Usar em seu código:
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');

Configuração de Ambiente

Variáveis de Ambiente

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?

  • Segurança: Evita expor credenciais no código
  • Flexibilidade: Permite trocar credenciais sem alterar código
  • Ambientes: Diferentes credenciais para desenvolvimento e produção

Escopos Disponíveis - Entendendo as Permissões

Os escopos definem quais operações sua aplicação pode realizar. É importante solicitar apenas os escopos necessários:

KYC (Know Your Customer)

  • kyc.background-check.natural-person - Verificar antecedentes de pessoas físicas
  • kyc.background-check.legal-person - Verificar antecedentes de pessoas jurídicas

Cobranças Pix (recebimento)

  • cob.write - Criar e atualizar cobranças Pix
  • cob.read - Consultar cobranças Pix existentes

Pagamentos Pix (envio)

  • pix.write - Iniciar e confirmar pagamentos Pix
  • pix.read - Listar pagamentos Pix

Webhooks

  • webhooks.read - Consultar webhooks configurados
  • webhooks.write - Criar e atualizar webhooks

Estabelecimentos

  • merchants.read - Consultar dados de estabelecimentos
  • merchants.write - Gerenciar estabelecimentos

Terminais

  • terminals.read - Consultar terminais POS
  • terminals.write - Gerenciar terminais POS

Transações

  • transactions.read - Consultar transações
  • transactions.write - Processar transações

Dica: Solicite apenas os escopos que realmente precisa. Isso segue o princípio de "menor privilégio" e aumenta a segurança.

Tratamento de Erros - Guia Completo

Códigos de Resposta HTTP

CódigoSignificadoQuando OcorreComo Resolver
200OKRequisição bem-sucedida-
400Bad RequestParâmetros inválidos ou ausentesVerificar parâmetros enviados
401UnauthorizedCredenciais inválidas ou token expiradoVerificar credenciais ou renovar token
403ForbiddenSem permissão para o recursoVerificar escopos solicitados
500Internal Server ErrorErro interno do servidorTentar novamente mais tarde

Implementação Robusta de Tratamento de Erros

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);
  }
}

Logs e Debugging

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);
  }
}

Dicas Importantes para você, desenvolvedor

Segurança

  • Nunca commite credenciais no código
  • Sempre use variáveis de ambiente
  • Rotacione credenciais periodicamente
  • Monitore logs de autenticação

Performance

  • Cache o token de acesso
  • Implemente retry com backoff exponencial
  • Monitore tempo de resposta das requisições
  • Use connection pooling quando possível

Debugging

  • Ative logs detalhados em desenvolvimento
  • Monitore códigos de erro HTTP
  • Teste cenários de falha
  • Documente problemas encontrados

Manutenção

  • Monitore expiração de tokens
  • Atualize dependências regularmente
  • Teste após mudanças na API
  • Mantenha documentação atualizada

2025 © Nuvende - CNPJ 38.297.374/0001-93