AxiomaFiscal
Módulo embeddable de configuração fiscal para produtos
O AxiomaFiscal é um componente JavaScript auto-contido (IIFE) que renderiza um formulário completo de configuração fiscal. Qualquer produto do ecossistema Axioma pode importá-lo para adicionar dados fiscais ao cadastro de produtos.
Zero dependências. O módulo inclui todas as tabelas fiscais (NCM, CFOP, CST, CSOSN, PIS, COFINS), validação, autocomplete de NCM e suporte a dark/light theme. Basta incluir o script.
Instalação
Adicione o script no HTML do seu produto. Nenhuma dependência extra é necessária.
<!-- No HTML do seu produto --> <div id="fiscal-config"></div> <script src="https://axiom-nfe.web.app/modules/fiscal.js"></script>
O script expõe o objeto global window.AxiomaFiscal com todos os métodos.
Uso básico
Exemplo mínimo: renderizar o form, validar e obter os dados.
<div id="fiscal-config"></div>
<script src="https://axiom-nfe.web.app/modules/fiscal.js"></script>
<script>
// 1. Renderizar o formulário
AxiomaFiscal.render('fiscal-config', {
regime: 'simples_nacional'
});
// 2. No submit do form de produto:
function salvarProduto() {
const { valid, errors } = AxiomaFiscal.validate();
if (!valid) {
alert('Corrija os campos fiscais: ' + errors.join(', '));
return;
}
const fiscal = AxiomaFiscal.getData();
// fiscal = { NCM, CFOP, origem, uCom, CSOSN, pisCST, cofinsCST, ... }
// Salvar junto com o produto no Firestore
await db.collection('shops/xxx/products').doc(productId).update({
fiscal: fiscal
});
}
// 3. Modo edição (produto existente):
AxiomaFiscal.setData(produtoExistente.fiscal);
</script>
API Completa
AxiomaFiscal.render(containerId, options)
Renderiza o formulário fiscal dentro de um elemento DOM.
| Parâmetro | Tipo | Descrição |
|---|---|---|
| containerId | string | ID do elemento DOM onde renderizar |
| options.regime | string | 'simples_nacional' | 'lucro_presumido' | 'lucro_real' |
| options.dark | boolean | Usar tema escuro (default: false) |
| options.defaults | object | Valores iniciais para pré-popular os campos |
| options.onChange | function | Callback chamado quando qualquer campo muda. Recebe getData() como argumento |
AxiomaFiscal.render('fiscal-config', {
regime: 'lucro_presumido',
dark: true,
defaults: { NCM: '61091000', CFOP: '5102' },
onChange: (data) => console.log('Fiscal changed:', data)
});
AxiomaFiscal.getData()
Retorna um objeto com todos os dados fiscais preenchidos. Pronto para salvar no banco.
Retorno — Simples Nacional:
{
"NCM": "61091000",
"CFOP": "5102",
"origem": "0",
"uCom": "UN",
"cest": null,
"ean": null,
"regime": "simples_nacional",
"CSOSN": "102",
"pisCST": "49",
"cofinsCST": "49"
}
Retorno — Lucro Presumido / Real:
{
"NCM": "61091000",
"CFOP": "5102",
"origem": "0",
"uCom": "UN",
"cest": null,
"ean": null,
"regime": "lucro_presumido",
"CST": "00",
"pICMS": 18,
"modBC": "3",
"pisCST": "01",
"pisAliq": 0.65,
"cofinsCST": "01",
"cofinsAliq": 3
}
AxiomaFiscal.setData(data)
Popula o formulário com dados existentes (modo edição). Aceita o mesmo formato retornado por getData().
// Carregar dados fiscais do produto existente
const produto = await db.collection('shops/xxx/products').doc(id).get();
AxiomaFiscal.setData(produto.data().fiscal);
AxiomaFiscal.validate()
Valida os campos obrigatórios. Retorna objeto com valid (boolean) e errors (array de strings). Marca campos com erro visualmente (borda vermelha + mensagem).
const result = AxiomaFiscal.validate();
// { valid: false, errors: ['NCM deve ter 8 dígitos numéricos', 'CFOP é obrigatório'] }
if (result.valid) {
const fiscal = AxiomaFiscal.getData();
// salvar...
}
Campos obrigatórios:
NCM— 8 dígitos numéricosCFOP— código fiscal da operaçãoCSOSN(Simples Nacional) ouCST ICMS(Lucro Presumido/Real)CST PISCST COFINS
AxiomaFiscal.setRegime(regime)
Troca o regime tributário e re-renderiza o formulário com os defaults apropriados. Preserva NCM, CFOP, unidade e EAN já preenchidos.
// Quando o lojista muda o regime tributário da empresa:
regimeSelect.addEventListener('change', (e) => {
AxiomaFiscal.setRegime(e.target.value);
});
AxiomaFiscal.tables
Acesso direto às tabelas fiscais embutidas. Útil para construir UIs customizadas.
| Propriedade | Conteúdo |
|---|---|
| CST_ICMS | 11 códigos (00, 10, 20, 30, 40, 41, 50, 51, 60, 70, 90) |
| CSOSN | 10 códigos Simples Nacional (101–900) |
| CST_PIS_COFINS | 16 códigos PIS/COFINS (01–99) |
| CFOP_COMMON | 9 CFOPs mais usados (venda interna, interestadual, exportação) |
| ORIGEM | 9 origens de mercadoria (0–8) |
| UNIDADES | 20 unidades comerciais (UN, KG, L, CX, etc.) |
| NCM_DB | 38 NCMs comuns com descrição |
| REGIME_DEFAULTS | Defaults por regime (simples, LP, LR) |
// Exemplo: popular um select customizado com CFOPs
const cfops = AxiomaFiscal.tables.CFOP_COMMON;
Object.entries(cfops).forEach(([code, desc]) => {
select.innerHTML += `<option value="${code}">${code} — ${desc}</option>`;
});
Regimes Tributários
O módulo adapta automaticamente os campos exibidos e os defaults conforme o regime:
| Regime | ICMS | PIS/COFINS | Alíquotas |
|---|---|---|---|
| simples_nacional | CSOSN (102 — sem crédito) | CST 49 (outras saídas) | Não exibe (isento) |
| lucro_presumido | CST (00 — tributada) | CST 01 (tributável) | PIS 0,65% / COFINS 3,00% |
| lucro_real | CST (00 — tributada) | CST 01 (tributável) | PIS 1,65% / COFINS 7,60% |
Defaults Automáticos
Ao renderizar sem options.defaults, o módulo aplica defaults inteligentes baseados no regime. O usuário pode alterar qualquer campo.
Atenção: Os defaults são sugestões genéricas. Cada empresa deve consultar seu contador para confirmar as configurações fiscais corretas para seus produtos.
Dark Theme
Passe dark: true nas opções para usar o tema escuro. Ideal para produtos com interface dark (como o próprio NFe dashboard).
AxiomaFiscal.render('fiscal-config', {
regime: 'simples_nacional',
dark: true
});
onChange Callback
Receba notificações em tempo real quando o usuário altera qualquer campo fiscal.
AxiomaFiscal.render('fiscal-config', {
regime: 'simples_nacional',
onChange: (data) => {
// data = resultado de getData()
console.log('NCM changed to:', data.NCM);
// Pode salvar automaticamente, mostrar preview, etc.
}
});
Integração com o Shop
Exemplo completo de como usar no cadastro de produto do Axioma Shop.
<!-- No form de produto (produtos.html) -->
<!-- Seção fiscal dentro do form -->
<div class="section-title">Configuração Fiscal</div>
<div id="fiscal-config"></div>
<script src="https://axiom-nfe.web.app/modules/fiscal.js"></script>
<script>
// Detectar regime da empresa (salvo na loja)
const regime = shop.taxRegime || 'simples_nacional';
// Renderizar form fiscal
AxiomaFiscal.render('fiscal-config', { regime });
// Se editando produto existente, popular com dados salvos
if (produto.fiscal) {
AxiomaFiscal.setData(produto.fiscal);
}
// No save do produto:
async function salvarProduto() {
const { valid, errors } = AxiomaFiscal.validate();
if (!valid) {
showError('Corrija os dados fiscais: ' + errors.join(', '));
return;
}
const fiscal = AxiomaFiscal.getData();
await db.collection(`shops/${shopId}/products`).doc(productId).update({
...outrosCampos,
fiscal: fiscal,
updatedAt: new Date()
});
}
</script>
UI Customizada
Se preferir construir seu próprio formulário, use AxiomaFiscal.tables para acessar as tabelas e REGIME_DEFAULTS para os valores padrão.
// Pegar tabelas sem renderizar o form
const { CSOSN, CST_ICMS, CFOP_COMMON, NCM_DB } = AxiomaFiscal.tables;
// Popular seus próprios selects
const csosn = CSOSN; // { '101': 'Tributada com crédito', '102': 'Sem crédito', ... }
// Buscar NCM
const results = NCM_DB.filter(n =>
n.code.includes('6109') || n.desc.toLowerCase().includes('camiseta')
);
// [{ code: '61091000', desc: 'Camisetas de malha, de algodão' }]
Montando o Payload NFe
Os dados retornados por getData() mapeiam diretamente para os campos do payload de emissão da API NFe.
const fiscal = AxiomaFiscal.getData();
// Montar produto para a API NFe
const produtoNFe = {
cProd: produto.id,
xProd: produto.name,
NCM: fiscal.NCM,
CFOP: fiscal.CFOP,
uCom: fiscal.uCom,
qCom: quantidade,
vUnCom: produto.price,
vProd: quantidade * produto.price,
cEAN: fiscal.ean || 'SEM GTIN',
cEANTrib: fiscal.ean || 'SEM GTIN',
CEST: fiscal.cest,
// ICMS
icms: fiscal.regime === 'simples_nacional'
? { orig: fiscal.origem, CSOSN: fiscal.CSOSN }
: {
orig: fiscal.origem,
CST: fiscal.CST,
modBC: parseInt(fiscal.modBC),
vBC: quantidade * produto.price,
pICMS: fiscal.pICMS,
vICMS: (quantidade * produto.price * fiscal.pICMS / 100)
},
// PIS
pis: { CST: fiscal.pisCST, vBC: quantidade * produto.price,
pPIS: fiscal.pisAliq || 0, vPIS: (quantidade * produto.price * (fiscal.pisAliq || 0) / 100) },
// COFINS
cofins: { CST: fiscal.cofinsCST, vBC: quantidade * produto.price,
pCOFINS: fiscal.cofinsAliq || 0, vCOFINS: (quantidade * produto.price * (fiscal.cofinsAliq || 0) / 100) }
};
NCMs Embutidos
O módulo inclui 38 NCMs comuns para autocomplete. A lista cobre as categorias mais vendidas no varejo brasileiro.
| NCM | Descrição |
|---|
CFOPs Disponíveis
| CFOP | Descrição |
|---|
CSTs ICMS / CSOSN
CST ICMS (Lucro Presumido / Real)
| CST | Descrição |
|---|
CSOSN (Simples Nacional)
| CSOSN | Descrição |
|---|
Demo ao Vivo
Teste o módulo diretamente nesta página.