Exemplos em Java
Setup
Requer Java 11+ (HttpClient nativo) e uma lib JSON (usando Jackson aqui).
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.16.0</version></dependency>export MYSE_API_BASE="https://api.mysebr.com.br/nfemyse-v3/rest"export MYSE_API_TOKEN="seu_token_aqui"Cliente HTTP centralizado
package com.example.myse;
import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.time.Duration;import java.util.Map;
public class MyseApi {
public static class ApiError extends RuntimeException { public final int httpStatus; public final JsonNode payload; public final String requestId; public ApiError(int s, String m, JsonNode p, String r) { super(m); this.httpStatus = s; this.payload = p; this.requestId = r; } }
private static final String BASE = System.getenv("MYSE_API_BASE"); private static final String TOKEN = System.getenv("MYSE_API_TOKEN"); private static final ObjectMapper MAPPER = new ObjectMapper(); private static final HttpClient CLIENT = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build();
public static JsonNode call(String method, String path, Map<String, ?> body) throws Exception { HttpRequest.BodyPublisher publisher = (body == null) ? HttpRequest.BodyPublishers.noBody() : HttpRequest.BodyPublishers.ofString(MAPPER.writeValueAsString(body));
HttpRequest req = HttpRequest.newBuilder() .uri(URI.create(BASE + path)) .timeout(Duration.ofSeconds(30)) .header("Authorization", "Token " + TOKEN) .header("Content-Type", "application/json") .method(method, publisher) .build();
HttpResponse<String> res = CLIENT.send(req, HttpResponse.BodyHandlers.ofString()); String requestId = res.headers().firstValue("X-Request-Id").orElse(null); JsonNode json = MAPPER.readTree(res.body());
if (res.statusCode() >= 400) { String msg = json.path("error").path("message").asText("HTTP " + res.statusCode()); throw new ApiError(res.statusCode(), msg, json, requestId); }
if ("999".equals(json.path("status").asText())) { String msg = json.path("data").path("erro").asText( json.path("descricao").asText("erro") ); String rid = json.path("meta").path("request_id").asText(requestId); throw new ApiError(200, msg, json, rid); }
return json; }}Cenário: emitir NFCe com polling
public class EmissorNFCe {
private static final Set<String> TERMINAIS = Set.of("004", "010", "900", "999");
public static JsonNode emitir(Pedido p) throws Exception { Map<String, Object> body = Map.of( "serie", "65", "cfop", "5102", "numero-origem", "PED-" + p.getId(), "tp_pagamento", p.getFormaPagamento(), "cliente", p.getCpfCnpjCliente(), "itens", p.getItens().stream().map(i -> Map.of( "produto", i.getSku(), "quantidade", String.valueOf(i.getQtd()), "valor-unitario", String.valueOf(i.getPreco()) )).toList() );
JsonNode emissao = MyseApi.call("POST", "/nfce/emissao", body); String status = emissao.path("status").asText(); if (!"001".equals(status) && !"050".equals(status)) { throw new RuntimeException("Emissão falhou: " + emissao.path("descricao").asText()); }
String recibo = emissao.path("data").path("recibo").asText(); System.out.printf("[emissao] recibo=%s request_id=%s%n", recibo, emissao.path("meta").path("request_id").asText());
// Polling long inicio = System.currentTimeMillis(); long wait = 2000; while (System.currentTimeMillis() - inicio < 5 * 60_000L) { Thread.sleep(wait); JsonNode consulta = MyseApi.call("GET", "/nfce/cupom/" + recibo, null); String st = consulta.path("status").asText(); System.out.println("[polling] status=" + st);
if (TERMINAIS.contains(st)) { if ("004".equals(st)) return consulta.path("data"); throw new RuntimeException("Status terminal não-sucesso: " + st); } wait = Math.min((long)(wait * 1.5), 30_000L); }
throw new RuntimeException("Timeout aguardando recibo " + recibo); }}Retry com backoff
public static <T> T comRetry(Callable<T> fn, int maxTentativas) throws Exception { Exception last = null; for (int i = 1; i <= maxTentativas; i++) { try { return fn.call(); } catch (MyseApi.ApiError e) { if (e.payload != null && "999".equals(e.payload.path("status").asText())) { throw e; // validação: não retentar } last = e; } catch (Exception e) { last = e; } if (i < maxTentativas) { Thread.sleep(1000L * (long) Math.pow(2, i - 1)); } } throw last;}Helper de polling reutilizável
public class FiscalHelpers { static final Set<String> TERMINAIS = Set.of("004", "010", "900", "999");
/** Polling com backoff exponencial até status terminal. */ public static JsonNode aguardarRecibo(String pathBase, String recibo) throws Exception { return aguardarRecibo(pathBase, recibo, 5 * 60_000L); }
public static JsonNode aguardarRecibo(String pathBase, String recibo, long timeoutMs) throws Exception { long inicio = System.currentTimeMillis(); long wait = 2000; while (System.currentTimeMillis() - inicio < timeoutMs) { Thread.sleep(wait); JsonNode resp = MyseApi.call("GET", pathBase + "/" + recibo, null); if (TERMINAIS.contains(resp.path("status").asText())) return resp; wait = Math.min((long)(wait * 1.5), 30_000L); } throw new RuntimeException("Timeout aguardando recibo " + recibo); }
private static void validarMotivo(String motivo) { if (motivo.length() < 15 || motivo.length() > 255) { throw new IllegalArgumentException("motivo deve ter entre 15 e 255 caracteres"); } }}Emitir NF-e (com transporte completo)
public static JsonNode emitirNFe(Pedido p) throws Exception { Map<String, Object> body = new HashMap<>(); body.put("serie", "1"); body.put("cfop", "5102"); body.put("numero-origem", "PED-" + p.getId()); body.put("tipo", "S"); body.put("finalidade", "N"); body.put("valor-despesas", "0.00"); body.put("cliente", p.getCpfCnpjCliente());
Map<String, Object> transporte = new HashMap<>(); transporte.put("modalidade", "0"); transporte.put("transportadora", p.getTransportadora()); transporte.put("placa-veiculo", p.getPlaca()); transporte.put("valor-frete", p.getFrete()); transporte.put("valor-seguro", "0.00"); transporte.put("peso-bruto", p.getPesoBruto()); transporte.put("peso-liquido", p.getPesoLiquido()); transporte.put("quantidade-volume", "1"); transporte.put("especie-volume", "Caixa"); transporte.put("marca-volume", "Embalagem"); body.put("transporte", transporte);
body.put("itens", p.getItens().stream().map(i -> Map.of( "produto", i.getSku(), "quantidade", String.valueOf(i.getQtd()), "valor-unitario", String.valueOf(i.getPreco()) )).toList());
if (p.getFaturas() != null) { body.put("faturas", p.getFaturas().stream().map(f -> Map.of( "valor", String.valueOf(f.getValor()), "data", f.getData() )).toList()); }
JsonNode emissao = MyseApi.call("POST", "/nfe/emissao", body); String status = emissao.path("status").asText(); if (!"001".equals(status) && !"050".equals(status)) { throw new RuntimeException("Emissão falhou: " + emissao.path("descricao").asText()); }
String recibo = emissao.path("data").path("recibo").asText(); JsonNode resultado = FiscalHelpers.aguardarRecibo("/nfe/nota", recibo); if (!"004".equals(resultado.path("status").asText())) { throw new RuntimeException("Status terminal não-sucesso: " + resultado.path("status")); } return resultado.path("data"); // inclui sefaz.chave, url-danfe, url-xml}Cancelar NF-e
public static JsonNode cancelarNFe(String chave, String motivo) throws Exception { FiscalHelpers.validarMotivo(motivo); JsonNode cancel = MyseApi.call("POST", "/nfe/cancelamento", Map.of("chave", chave, "motivo", motivo)); if (!"001".equals(cancel.path("status").asText())) { throw new RuntimeException(cancel.path("descricao").asText()); } return FiscalHelpers.aguardarRecibo("/nfe/cancelamento", cancel.path("data").path("recibo").asText());}Lançar carta de correção (CC-e)
/** * O campo "motivo" na CC-e é o TEXTO da correção (xCorrecao). */public static JsonNode cartaCorrecaoNFe(String chave, String textoCorrecao) throws Exception { FiscalHelpers.validarMotivo(textoCorrecao); JsonNode cce = MyseApi.call("POST", "/nfe/correcao", Map.of("chave", chave, "motivo", textoCorrecao)); if (!"001".equals(cce.path("status").asText())) { throw new RuntimeException(cce.path("descricao").asText()); } return FiscalHelpers.aguardarRecibo("/nfe/correcao", cce.path("data").path("recibo").asText());}Cancelar NFC-e
public static JsonNode cancelarNFCe(String chave, String motivo) throws Exception { FiscalHelpers.validarMotivo(motivo); JsonNode cancel = MyseApi.call("POST", "/nfce/cancelamento", Map.of("chave", chave, "motivo", motivo)); if (!"001".equals(cancel.path("status").asText())) { throw new RuntimeException(cancel.path("descricao").asText()); } return FiscalHelpers.aguardarRecibo("/nfce/cancelamento", cancel.path("data").path("recibo").asText());}Emitir NFS-e (Nota Fiscal de Serviço)
public static JsonNode emitirNFSe(Servico s) throws Exception { Map<String, Object> body = new HashMap<>(); body.put("numero-origem", "OS-" + s.getId()); body.put("observacao", s.getObservacao()); body.put("nome-contato", s.getNomeContato()); body.put("telefone-contato", s.getTelefoneContato()); body.put("data-fim", s.getDataFim()); body.put("cliente", s.getCpfCnpjCliente()); body.put("itens", s.getItens().stream().map(i -> Map.of( "produto", i.getCodigoServico(), "quantidade", String.valueOf(i.getQtd()), "valor-unitario", String.valueOf(i.getPreco()) )).toList());
JsonNode emissao = MyseApi.call("POST", "/nfse/emissao", body); String status = emissao.path("status").asText(); if (!"001".equals(status) && !"050".equals(status)) { throw new RuntimeException("Emissão NFSe falhou: " + emissao.path("descricao")); }
String recibo = emissao.path("data").path("recibo").asText(); JsonNode resultado = FiscalHelpers.aguardarRecibo("/nfse/nota", recibo); if (!"004".equals(resultado.path("status").asText())) { throw new RuntimeException("Status terminal não-sucesso: " + resultado.path("status")); } return resultado.path("data");}Cancelar NFS-e
public static JsonNode cancelarNFSe(String chave, String motivo) throws Exception { FiscalHelpers.validarMotivo(motivo); return MyseApi.call("POST", "/nfse/cancelamento", Map.of("chave", chave, "motivo", motivo));}Reconhecer nota de fornecedor (MD-e)
/** * Códigos de reconhecimento: * "210200" — Confirmação da operação (terminal, irreversível) * "210210" — Ciência da operação (provisório, 15 dias) * "210220" — Desconhecimento da operação * "210240" — Operação não realizada */public static JsonNode reconhecerNotaFornecedor(String chave, String codigo) throws Exception { Set<String> validos = Set.of("210200", "210210", "210220", "210240"); if (!validos.contains(codigo)) { throw new IllegalArgumentException("Código inválido: " + codigo); } JsonNode resp = MyseApi.call("POST", "/nffornecedor/reconhecimento", Map.of("chave", chave, "codigo-reconhecimento", codigo)); if (!"001".equals(resp.path("status").asText())) { throw new RuntimeException(resp.path("descricao").asText()); } return FiscalHelpers.aguardarRecibo("/nffornecedor", resp.path("data").path("recibo").asText());}Listar com paginação
public static List<JsonNode> listarTodosClientes() throws Exception { List<JsonNode> todos = new ArrayList<>(); int page = 1; int pageSize = 100;
while (true) { JsonNode resp = MyseApi.call("GET", "/clientes?page=" + page + "&page_size=" + pageSize, null); if (!"005".equals(resp.path("status").asText())) break; JsonNode data = resp.path("data"); if (!data.isArray() || data.size() == 0) break; data.forEach(todos::add); if (data.size() < pageSize) break; page++; Thread.sleep(200); }
return todos;}Tratamento de erros
try { JsonNode nfce = EmissorNFCe.emitir(pedido); System.out.println("NFCe emitida: " + nfce.path("sefaz").path("chave").asText());} catch (MyseApi.ApiError e) { logger.error("API error: status={} requestId={} msg={}", e.httpStatus, e.requestId, e.getMessage()); throw e;}Health check (sem autenticação)
HttpRequest req = HttpRequest.newBuilder() .uri(URI.create(BASE + "/health")) .timeout(Duration.ofSeconds(5)) .build();HttpResponse<String> res = CLIENT.send(req, HttpResponse.BodyHandlers.ofString());JsonNode health = new ObjectMapper().readTree(res.body());// { "status": "ok", "database": "ok", "timestamp": "..." }Alterar nota antes da emissão (PUT)
Disponível em NF-e (/nfe/{id}), NFC-e (/nfce/{id}) e NFS-e (/nfse/{id}).
Só funciona enquanto a nota ainda não foi submetida para emissão.
public static JsonNode alterarNota(String tipo, String id, Map<String, ?> dados) throws Exception { // tipo: "nfe" | "nfce" | "nfse" return MyseApi.call("PUT", "/" + tipo + "/" + id, dados);}
// Uso:alterarNota("nfe", "12345", Map.of( "serie", "1", "cfop", "5102", "cliente", "12345678000199", "itens", List.of(Map.of( "produto", "SKU-001", "quantidade", "3", "valor-unitario", "89.90" ))));Consulta detalhada por recibo
JsonNode nfeCompleta = MyseApi.call("GET", "/nfe/nota/" + recibo + "/completa", null);JsonNode nfceCompleta = MyseApi.call("GET", "/nfce/cupom/" + recibo + "/completa", null);Listagens
JsonNode nfes = MyseApi.call("GET", "/nfe?page=1&page_size=20", null);JsonNode nfces = MyseApi.call("GET", "/nfce?page=1&page_size=50", null);JsonNode nfses = MyseApi.call("GET", "/nfse?dataInicial=2026-05-01&page=1&page_size=20", null);JsonNode fornecedor = MyseApi.call("GET", "/nffornecedor?page=1&page_size=20", null);
// Forma legada (path-based)JsonNode nfesLegado = MyseApi.call("GET", "/nfe/paginacao/1/20", null);Clientes (CRUD completo)
public static JsonNode cadastrarPF(PessoaFisica pf) throws Exception { Map<String, Object> body = new HashMap<>(); body.put("tipo", "F"); body.put("nome", pf.getNome()); body.put("cpf", pf.getCpf()); body.put("rg", pf.getRg()); body.put("consumidor-final", "1"); body.put("contato", Map.of( "email", pf.getEmail(), "telefone", pf.getTelefone() )); body.put("endereco", pf.getEndereco()); return MyseApi.call("POST", "/clientes", body);}
public static JsonNode cadastrarPJ(PessoaJuridica pj) throws Exception { Map<String, Object> body = new HashMap<>(); body.put("tipo", "J"); body.put("razao-social", pj.getRazaoSocial()); body.put("nome-fantasia", pj.getNomeFantasia()); body.put("cnpj", pj.getCnpj()); body.put("inscricao-municipal", pj.getInscricaoMunicipal()); body.put("tipo-inscricao-estadual", pj.getContribuinte() != null ? pj.getContribuinte() : "9"); body.put("inscricao-estadual", pj.getInscricaoEstadual() != null ? pj.getInscricaoEstadual() : "ISENTO"); body.put("consumidor-final", "0"); body.put("contato", Map.of( "email", pj.getEmail(), "telefone", pj.getTelefone() )); body.put("endereco", pj.getEndereco()); return MyseApi.call("POST", "/clientes", body);}
// Consultar por CPF/CNPJJsonNode cliente = MyseApi.call("GET", "/clientes/12345678000199", null);
// Buscar por nomeJsonNode encontrados = MyseApi.call("GET", "/clientes/busca/exemplo", null);JsonNode top = MyseApi.call("GET", "/clientes/busca/top_clientes", null);
// AtualizarMyseApi.call("PUT", "/clientes/12345678000199", Map.of( "tipo", "J", "razao-social", "Empresa Exemplo (Novo Nome) Ltda"));
// ExcluirMyseApi.call("DELETE", "/clientes/12345678000199", null);Produtos (CRUD completo)
public static JsonNode cadastrarProduto(Produto p) throws Exception { Map<String, Object> body = new HashMap<>(); body.put("referencia", p.getSku()); body.put("nome", p.getNome()); body.put("valor", String.valueOf(p.getValor())); body.put("medida", p.getMedida() != null ? p.getMedida() : "UN"); body.put("categoria", p.getCategoria()); body.put("ncm", p.getNcm()); body.put("origem", p.getOrigem() != null ? p.getOrigem() : "0"); body.put("cfop-preferencial", p.getCfop() != null ? p.getCfop() : "5102"); body.put("tipo-produto", "P"); if (p.getConfiguracoesFiscais() != null) { body.put("configuracoes-fiscais", p.getConfiguracoesFiscais()); } return MyseApi.call("POST", "/produtos", body);}
public static JsonNode cadastrarServico(Servico s) throws Exception { return MyseApi.call("POST", "/produtos", Map.of( "referencia", s.getSku(), "nome", s.getNome(), "valor", String.valueOf(s.getValor()), "medida", "H", "tipo-produto", "S", "codigo-servico", s.getCodigoServico() ));}
// ConsultarJsonNode produto = MyseApi.call("GET", "/produtos/SKU-001", null);JsonNode porNome = MyseApi.call("GET", "/produtos/nome/Camiseta", null);
// Listar paginado com busca (use _todos para não filtrar)JsonNode todos = MyseApi.call("GET", "/produtos/paginacao/1/20/_todos", null);JsonNode filtrados = MyseApi.call("GET", "/produtos/paginacao/1/20/Camiseta", null);
// AtualizarMyseApi.call("PUT", "/produtos/SKU-001", Map.of( "referencia", "SKU-001", "nome", "Camiseta Polo M (Novo)", "valor", "99.90"));
// ExcluirMyseApi.call("DELETE", "/produtos/SKU-001", null);