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.
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.
GET /api/v1/pagamentos/merchants - Listar estabelecimentosPOST /api/v1/pagamentos/merchants - Cadastrar estabelecimentoPUT /api/v1/pagamentos/merchants/{id} - Atualizar estabelecimentoAuthorization: Bearer {access_token}
Content-Type: application/json
Accept: application/json
{
"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"
}
pix_integration: Tipo de integração Pixcode: Código único do comerciantename: Nome do comerciantedocument: Documento do comerciante (CNPJ/CPF)external_id: ID externo do estabelecimentopix_key: Chave Pix (UUID)channel_id: ID do canal (UUID)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);
}
}
// 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}`);
}
}