Pular para o conteúdo

Exemplos em Java

Setup

Requer Java 11+ (HttpClient nativo) e uma lib JSON (usando Jackson aqui).

pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.0</version>
</dependency>
Terminal window
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/CNPJ
JsonNode cliente = MyseApi.call("GET", "/clientes/12345678000199", null);
// Buscar por nome
JsonNode encontrados = MyseApi.call("GET", "/clientes/busca/exemplo", null);
JsonNode top = MyseApi.call("GET", "/clientes/busca/top_clientes", null);
// Atualizar
MyseApi.call("PUT", "/clientes/12345678000199", Map.of(
"tipo", "J",
"razao-social", "Empresa Exemplo (Novo Nome) Ltda"
));
// Excluir
MyseApi.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()
));
}
// Consultar
JsonNode 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);
// Atualizar
MyseApi.call("PUT", "/produtos/SKU-001", Map.of(
"referencia", "SKU-001",
"nome", "Camiseta Polo M (Novo)",
"valor", "99.90"
));
// Excluir
MyseApi.call("DELETE", "/produtos/SKU-001", null);