Pagamentos via Terminais

Estabelecimentos

Como gerenciar estabelecimentos comerciais via API

A API da Nuvende permite o gerenciamento completo de estabelecimentos comerciais, incluindo cadastro, atualização e listagem. Os estabelecimentos são entidades fundamentais para organizar e gerenciar operações de pagamento.

Conceitos Fundamentais

O que são Estabelecimentos Comerciais?

Estabelecimentos comerciais são entidades que representam comerciantes no sistema Nuvende. Cada estabelecimento possui identificação única (UUID) e está associado a uma conta específica, podendo ter múltiplos terminais associados para processamento de pagamentos.

Funcionalidades Disponíveis

  • Listar Estabelecimentos: Consultar todos os estabelecimentos cadastrados com paginação
  • Cadastrar Estabelecimento: Criar novo estabelecimento comercial
  • Atualizar Estabelecimento: Modificar dados de estabelecimento existente

Implementação Técnica

Endpoints Disponíveis

  • GET /api/v1/pagamentos/merchants - Listar estabelecimentos
  • POST /api/v1/pagamentos/merchants - Cadastrar estabelecimento
  • PUT /api/v1/pagamentos/merchants/{id} - Atualizar estabelecimento

Estrutura de Dados

Headers Obrigatórios

Authorization: Bearer {access_token}
Content-Type: application/json
Accept: application/json

Estrutura de Estabelecimento

{
  "id": "string (UUID)",
  "pix_integration": "string",
  "code": "string",
  "name": "string",
  "document": "string",
  "pix_key": "string (UUID)",
  "account_token": "string|null",
  "external_id": "string",
  "channel_id": "string (UUID)",
  "created_at": "datetime",
  "updated_at": "datetime"
}

Campos Obrigatórios para Criação

  • pix_integration: Tipo de integração Pix
  • code: Código único do comerciante
  • name: Nome do comerciante
  • document: Documento do comerciante (CNPJ/CPF)
  • external_id: ID externo do estabelecimento
  • pix_key: Chave Pix (UUID)
  • channel_id: ID do canal (UUID)

Implementação em Código

Classe de Gerenciamento de Estabelecimentos

const axios = require('axios');

class EstabelecimentoService {
  constructor(baseUrl, accessToken) {
    this.baseUrl = baseUrl;
    this.accessToken = accessToken;
  }

  /**
   * Lista todos os estabelecimentos com paginação
   * @param {Object} filtros - Filtros de busca (opcional)
   * @returns {Promise<Object>} Lista paginada de estabelecimentos
   */
  async listarEstabelecimentos(filtros = {}) {
    try {
      console.log('Listando estabelecimentos...');
      
      const response = await axios.get(`${this.baseUrl}/api/v1/pagamentos/merchants`, {
        headers: {
          'Authorization': `Bearer ${this.accessToken}`,
          'Accept': 'application/json'
        },
        params: filtros
      });

      console.log(`${response.data.data.length} estabelecimentos encontrados`);
      return response.data;
      
    } catch (error) {
      console.error('Erro ao listar estabelecimentos:', error.response?.data || error.message);
      throw this.tratarErro(error);
    }
  }

  /**
   * Cadastra um novo estabelecimento
   * @param {Object} dadosEstabelecimento - Dados do estabelecimento
   * @returns {Promise<Object>} Estabelecimento criado
   */
  async cadastrarEstabelecimento(dadosEstabelecimento) {
    try {
      console.log('Cadastrando estabelecimento...');
      
      const response = await axios.post(`${this.baseUrl}/api/v1/pagamentos/merchants`, dadosEstabelecimento, {
        headers: {
          'Authorization': `Bearer ${this.accessToken}`,
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      });

      console.log('Estabelecimento cadastrado com sucesso');
      return response.data;
      
    } catch (error) {
      console.error('Erro ao cadastrar estabelecimento:', error.response?.data || error.message);
      throw this.tratarErro(error);
    }
  }

  /**
   * Atualiza um estabelecimento existente
   * @param {string} id - ID do estabelecimento (UUID)
   * @param {Object} dadosAtualizacao - Dados para atualização
   * @returns {Promise<Object>} Estabelecimento atualizado
   */
  async atualizarEstabelecimento(id, dadosAtualizacao) {
    try {
      console.log(`Atualizando estabelecimento: ${id}`);
      
      const response = await axios.put(`${this.baseUrl}/api/v1/pagamentos/merchants/${id}`, dadosAtualizacao, {
        headers: {
          'Authorization': `Bearer ${this.accessToken}`,
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      });

      console.log('Estabelecimento atualizado com sucesso');
      return response.data;
      
    } catch (error) {
      console.error('Erro ao atualizar estabelecimento:', error.response?.data || error.message);
      throw this.tratarErro(error);
    }
  }

  /**
   * Valida dados de estabelecimento
   * @param {Object} dados - Dados a serem validados
   * @returns {Object} Resultado da validação
   */
  validarDadosEstabelecimento(dados) {
    const erros = [];

    if (!dados.name || dados.name.trim().length === 0) {
      erros.push('Nome é obrigatório');
    }

    if (!dados.document || dados.document.trim().length === 0) {
      erros.push('Documento é obrigatório');
    }

    if (!dados.code || dados.code.trim().length === 0) {
      erros.push('Código é obrigatório');
    }

    if (!dados.pix_integration || dados.pix_integration.trim().length === 0) {
      erros.push('Tipo de integração Pix é obrigatório');
    }

    if (!dados.external_id || dados.external_id.trim().length === 0) {
      erros.push('ID externo é obrigatório');
    }

    if (!dados.pix_key || dados.pix_key.trim().length === 0) {
      erros.push('Chave Pix é obrigatória');
    }

    if (!dados.channel_id || dados.channel_id.trim().length === 0) {
      erros.push('ID do canal é obrigatório');
    }

    return {
      valido: erros.length === 0,
      erros: erros
    };
  }

  /**
   * Trata erros da API
   * @param {Error} error - Erro capturado
   * @returns {Error} Erro tratado
   */
  tratarErro(error) {
    const status = error.response?.status;
    const data = error.response?.data;

    switch (status) {
      case 400:
        return new Error(`Dados inválidos: ${data?.message || 'Verifique os parâmetros enviados'}`);
      case 401:
        return new Error('Token de acesso inválido ou expirado');
      case 403:
        return new Error('Permissões insuficientes para gerenciar estabelecimentos');
      case 404:
        return new Error('Estabelecimento não encontrado');
      case 422:
        return new Error(`Dados não processáveis: ${data?.message || 'Verifique o formato dos dados'}`);
      case 500:
        return new Error('Erro interno do servidor. Tente novamente mais tarde');
      default:
        return new Error(`Erro inesperado: ${error.message}`);
    }
  }
}

// Exemplo de uso prático
async function exemploGerenciamentoEstabelecimentos() {
  const estabelecimentoService = new EstabelecimentoService(
    'https://api-h.nuvende.com.br',
    'seu_access_token'
  );

  try {
    // Listar estabelecimentos
    const estabelecimentos = await estabelecimentoService.listarEstabelecimentos();
    console.log('Estabelecimentos:', estabelecimentos);

    // Cadastrar novo estabelecimento
    const novoEstabelecimento = {
      pix_integration: 'external',
      code: 'EST-001',
      name: 'Loja Central',
      document: '12345678000195',
      external_id: 'ext-loja-001',
      pix_key: '20125aa5-aabf-4fa0-b5bc-d81d519c5da7',
      channel_id: '0591d83c-03a3-4fc6-8812-9baabb170843'
    };

    const validacao = estabelecimentoService.validarDadosEstabelecimento(novoEstabelecimento);
    if (!validacao.valido) {
      console.error('Dados inválidos:', validacao.erros);
      return;
    }

    const estabelecimentoCriado = await estabelecimentoService.cadastrarEstabelecimento(novoEstabelecimento);
    console.log('Estabelecimento criado:', estabelecimentoCriado);

  } catch (error) {
    console.error('Erro no exemplo:', error.message);
  }
}

Casos de Uso Práticos

Sistema de Franquias

// Gerenciamento de múltiplas lojas
class SistemaFranquias {
  constructor(estabelecimentoService) {
    this.estabelecimentoService = estabelecimentoService;
  }

  async cadastrarNovaLoja(dadosLoja) {
    try {
      // Validar dados da loja
      const validacao = this.estabelecimentoService.validarDadosEstabelecimento(dadosLoja);
      if (!validacao.valido) {
        throw new Error(`Dados inválidos: ${validacao.erros.join(', ')}`);
      }

      // Cadastrar estabelecimento
      const estabelecimento = await this.estabelecimentoService.cadastrarEstabelecimento(dadosLoja);
      
      // Configurar terminais para a nova loja
      await this.configurarTerminais(estabelecimento.id);
      
      return estabelecimento;
      
    } catch (error) {
      console.error('Erro ao cadastrar nova loja:', error.message);
      throw error;
    }
  }

  async configurarTerminais(estabelecimentoId) {
    // Implementar configuração de terminais
    console.log(`Configurando terminais para estabelecimento ${estabelecimentoId}`);
  }
}

2025 © Nuvende - CNPJ 38.297.374/0001-93