@brasil-fiscal/cte
v0.3.0
Published
Lib open-source para emissao de CTe (Conhecimento de Transporte Eletronico) em TypeScript.
Maintainers
Readme
@brasil-fiscal/cte
Lib open-source em TypeScript para emissao de CT-e (Conhecimento de Transporte Eletronico, modelo 57) no Brasil. Parte do ecossistema @brasil-fiscal.
Status: 0.x. Emissao, consulta, cancelamento, carta de correcao e DACTE do CT-e normal rodoviario, com testes automatizados contra os XSDs oficiais. Vira 1.0 depois da homologacao real na SEFAZ.
O que cobre
- CT-e normal (
tpCTe0), servico normal (tpServ0), modal rodoviario, leiaute 4.00 - Status do servico, emissao (recepcao sincrona), consulta pela chave
- Cancelamento (110111) e carta de correcao (110110), com
procEventoCTemontado - DACTE em PDF, retrato A4, com codigo de barras e QR Code
- Tomador remetente, expedidor, recebedor, destinatario ou terceiro
- ICMS 00, 20, 40/41/51, 60, 90, outra UF e Simples Nacional; partilha com a UF de fim
- IBS/CBS (reforma tributaria) com tributacao integral, opcional
- Documentos transportados: NF-e (chave), NF modelo 01/04 e outros
- Todos os autorizadores: MG, MS, MT, PR, RS, SP, SVRS e SVSP
Ainda nao cobre: CT-e complementar/anulacao/substituicao, subcontratacao e redespacho, outros modais, CT-e OS, contingencia (EPEC/SVC) e outros eventos. Veja o ROADMAP.
Instalacao
npm install @brasil-fiscal/cte
npm install pdfkit qrcode # so para gerar o DACTERequer Node.js 18+ e o xmllint (libxml2) no sistema: todo XML passa pelo XSD oficial antes de ir para a SEFAZ. No macOS ja vem instalado; no Debian/Ubuntu, apt install libxml2-utils.
Uso
import { CTeCore } from '@brasil-fiscal/cte';
import { readFileSync } from 'node:fs';
const cte = CTeCore.create({
pfx: readFileSync('./certificado.pfx'),
senha: 'senha-do-certificado',
ambiente: 'homologacao', // ou 'producao'
uf: 'MT' // UF do emitente
});
await cte.statusServico(); // { online: true, codigoStatus: '107', ... }Emitir
const cidade = { codigo: '5103403', nome: 'CUIABA', uf: 'MT' };
const endereco = {
logradouro: 'RUA DAS FLORES', numero: '100', bairro: 'CENTRO',
codigoMunicipio: '5103403', municipio: 'CUIABA', cep: '78005000', uf: 'MT'
};
const r = await cte.transmitir({
identificacao: {
cfop: '5353',
naturezaOperacao: 'PRESTACAO DE SERVICO DE TRANSPORTE',
serie: 1,
numero: 123,
municipioEnvio: cidade,
municipioInicio: cidade,
municipioFim: cidade
},
emitente: {
cnpj: '11222333000181', inscricaoEstadual: '131234567',
razaoSocial: 'TRANSPORTADORA LTDA', endereco, crt: 3
},
tomador: { tipo: 'remetente', indicadorIE: 1 },
remetente: { cnpj: '44555666000109', inscricaoEstadual: '132000000', nome: 'LOJA LTDA', endereco },
destinatario: { cpf: '12345678909', nome: 'JOAO DA SILVA', endereco },
prestacao: { valorTotal: 1500, valorReceber: 1500, componentes: [{ nome: 'FRETE PESO', valor: 1500 }] },
imposto: { icms: { cst: '00', baseCalculo: 1500, aliquota: 12, valor: 180 } },
carga: {
valor: 25000,
produtoPredominante: 'ELETRONICOS',
quantidades: [{ unidade: '01', tipoMedida: 'PESO BRUTO', quantidade: 1250 }]
},
documentos: { tipo: 'nfe', itens: [{ chave: '5126...' }] },
rodoviario: { rntrc: '12345678' }
});
r.chaveAcesso; // 44 digitos
r.protocolo; // nProt
r.xmlProtocolado; // cteProc: guarde este XMLA chave de acesso, o digito verificador, o QR Code e o autorizador sao calculados pela lib.
Erros
| Erro | Quando | O que fazer |
|---|---|---|
| CTeValidationError | Entrada invalida (antes de montar o XML) | err.campos lista campo e motivo |
| CTeSchemaError | XML nao passou no XSD oficial | err.erros traz o elemento e a regra |
| SefazRejectError | A SEFAZ rejeitou | err.cStat e err.xMotivo |
| CTeTimeoutError | O envio passou do tempo limite | Nao reenvie: consulte err.chaveAcesso primeiro |
| CTeEnvioIncertoError | Conexao caiu ou resposta ilegivel depois do envio (o CTeTimeoutError e um caso dele) | Nao reenvie: consulte err.chaveAcesso primeiro |
try {
await cte.transmitir(dados);
} catch (err) {
if (err instanceof CTeEnvioIncertoError) {
const situacao = await cte.consultarProtocolo(err.chaveAcesso);
// situacao.autorizado === true → ja foi autorizado, nao reenvie
}
}Consultar, cancelar, corrigir e imprimir
await cte.consultarProtocolo(chave); // { autorizado, cancelado, protocolo, ... }
await cte.cancelar({ chaveAcesso: chave, protocolo, justificativa: 'FRETE EMITIDO EM DUPLICIDADE' });
await cte.cartaCorrecao({
chaveAcesso: chave,
sequencia: 1, // 2 na segunda CC-e, e assim por diante
correcoes: [{ grupo: 'compl', campo: 'xObs', valor: 'NOVA OBSERVACAO' }]
});
const pdf = await cte.dacte(r.xmlProtocolado);Homologacao
npm run homologacao roda o roteiro completo (status, emissao, consulta, CC-e, DACTE e cancelamento) com o seu certificado. Veja as variaveis no topo de examples/homologacao.ts.
Desenvolvimento
npm install
npm test
npm run buildEcossistema @brasil-fiscal
| Pacote | Status | Descricao | |--------|--------|-----------| | @brasil-fiscal/core | Estavel | Infraestrutura compartilhada | | @brasil-fiscal/nfe | Estavel | NF-e e NFC-e | | @brasil-fiscal/cte | 0.x | CT-e (este pacote) | | @brasil-fiscal/mdfe | Em desenvolvimento | MDF-e |
