O Fiscal.io Monitor permite criar e instalar extensões (plugins) em .NET para acrescentar botões, canais de envio e tarefas periódicas — sem alterar o núcleo do produto.
Este manual explica como criar uma extensão, com exemplo de código. Para só instalar um ZIP pronto, veja: Instalando uma extensão de integração no Fiscal.io Monitor.
Recurso de plano: MON-FUNC-630 (Extensões). Permissão típica de instalação: PLUGIN-MANAGER.
clsMainClass e implementar IPlugin.Plugins\{banco}_{guid}_{versao}, carrega MainFile.dll e instancia clsMainClass.plugin.fiscal.io.dll (pasta de instalação / build do Monitor).System, System.Drawing.Os atributos do assembly precisam bater exatamente com as propriedades Guid e Name da classe:
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Minha Extensão Demo")]
[assembly: AssemblyDescription("Exemplo de extensão para o Fiscal.io Monitor")]
[assembly: AssemblyCompany("Minha Empresa")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: Guid("11111111-2222-3333-4444-555555555555")]
Guid (assembly) = IPlugin.GuidAssemblyTitle = IPlugin.NameAssemblyFileVersion → versão exibida no MonitorAssemblyDescription / AssemblyCompany → descrição e autorNome da classe: clsMainClass (sem exceção). Exemplo mínimo com botão + canal de envio:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using plugin.fiscal.io;
namespace MinhaEmpresa.FiscalIo.PluginDemo
{
/// <summary>
/// Nome OBRIGATÓRIO da classe principal: clsMainClass
/// </summary>
public class clsMainClass : IPlugin
{
public string Guid => "11111111-2222-3333-4444-555555555555";
public string Name => "Minha Extensão Demo";
public Bitmap Icon => new Bitmap(16, 16);
public List<IButton> ButtonList { get; } = new List<IButton>
{
new clsBotaoDemo()
};
public event EventOnFiscalChangedHandler EventOnFiscalChanged;
public event EventOnTagChangedHandler EventOnTagChanged;
public event EventGetParameterHandler EventGetParameter;
public event EventSetParameterHandler EventSetParameter;
public event EventSetChannelInHandler EventSetChannelIn;
// Canal de ENVIO (Integrar → Extensão → Enviar arquivos XML)
public bool IsChannelSender => true;
public bool IsChannelReceiver => false;
public clsRetFunc funcExecuteChannelSender(clsDocScope pclsScope, string pFilePath, string pFileType)
{
try
{
if (string.IsNullOrWhiteSpace(pFilePath) || !File.Exists(pFilePath))
{
return new clsRetFunc { Type = "E", Number = "1", Message = "Arquivo não encontrado." };
}
// Exemplo: ler o XML e enviar para o seu ERP/API
var xml = File.ReadAllText(pFilePath);
// SeuCodigo.Enviar(xml, pFileType, pclsScope);
return new clsRetFunc { Type = "S", Number = "0", Message = "XML enviado com sucesso." };
}
catch (Exception ex)
{
return new clsRetFunc { Type = "E", Number = "999", Message = ex.Message };
}
}
public clsRetFunc funcExecuteChannelReceiver(string pChannel)
{
return new clsRetFunc { Type = "S", Number = "0", Message = "Receiver não utilizado neste exemplo." };
}
// Tarefa periódica (opcional)
public bool IsTaskEnabled => false;
public int TaskFrequency => 60; // minutos
public clsRetFunc funcExecuteTask()
{
return new clsRetFunc { Type = "S", Number = "0", Message = "OK" };
}
}
public class clsBotaoDemo : IButton
{
public string ibGuid => "btn-demo-001";
public string ibName => "Demo: marcar documentos";
public Bitmap ibIcon => new Bitmap(16, 16);
public List<string> ibTabList => new List<string>();
public bool funcExecute(object pDocList)
{
// pDocList: lista de documentos selecionados na tela
return true;
}
public bool funcExecute(object pDocList, object pRefList)
{
return funcExecute(pDocList);
}
}
}
AssemblyName do projeto como MainFile).MainFile.dll e, se necessário, DLLs dependentes na raiz do ZIP (sem pastas aninhadas).Os trechos abaixo são independentes. Copie só o que for usar na sua clsMainClass. Não precisa ligar tudo de uma vez.
Use quando o seu sistema gera o XML e o Monitor deve importar. Em Integrar, configure Meio = Extensão e Objetivo = Receber.
public bool IsChannelReceiver => true;
public clsRetFunc funcExecuteChannelReceiver(string pChannel)
{
try
{
// 1) Busque o XML no seu ERP/API/pasta
string xml = SeuCodigo.BuscarProximoXml();
if (string.IsNullOrWhiteSpace(xml))
return new clsRetFunc { Type = "S", Number = "0", Message = "Nada novo." };
// 2) Empurre o XML para o Monitor processar na entrada
var handler = EventSetChannelIn;
if (handler != null)
{
handler(this, new EventSetChannelInEventArgs
{
Channel = pChannel,
XmlContent = xml
});
}
return new clsRetFunc { Type = "S", Number = "0", Message = "XML recebido no Monitor." };
}
catch (Exception ex)
{
return new clsRetFunc { Type = "E", Number = "999", Message = ex.Message };
}
}
Roda sozinha no Gerenciador de tarefas. Ideal para sync periódico.
public bool IsTaskEnabled => true;
public int TaskFrequency => 30; // a cada 30 minutos
public clsRetFunc funcExecuteTask()
{
try
{
// SeuCodigo.Sincronizar();
return new clsRetFunc { Type = "S", Number = "0", Message = "Tarefa concluída." };
}
catch (Exception ex)
{
return new clsRetFunc { Type = "E", Number = "999", Message = ex.Message };
}
}
Útil para triagem automática depois de um sync ou botão.
void AplicarEtiqueta(string chave, string etiqueta, string nota)
{
var handler = EventOnTagChanged;
if (handler == null) return;
handler(this, new EventOnTagChangedEventArgs
{
Filial = "",
Chave = chave, // chave do DFe
Tag = etiqueta, // nome da etiqueta
SetTag = true,
DocNote = nota, // observação
SetDocNote = true
});
}
// Exemplo:
// AplicarEtiqueta("3524...chave...", "Recebido no ERP", "Sync automático");
Depois que o ERP lançou a nota, registre no Monitor. Se quiser, agenda a Confirmação da Operação.
void RegistrarEscrituracao(
string filial, string chave,
string dtReg, string usuario, string dtEnt, string numErp,
bool confirmarOperacao, int atrasoHoras)
{
var handler = EventOnFiscalChanged;
if (handler == null) return;
handler(this, new EventOnFiscalChangedEventArgs
{
Filial = filial,
Chave = chave,
DtRegFisc = dtReg, // data do registro
UsRegFisc = usuario, // usuário
DtEntFisc = dtEnt, // data de lançamento
DcNumFisc = numErp, // número no ERP
DoManifest = confirmarOperacao, // true = agenda manifestação
ManifestDelay = atrasoHoras // horas após a leitura
});
}
string Ler(string nome)
{
var h = EventGetParameter;
if (h == null) return "";
return h(this, new EventGetParameterEventArgs { Param = nome, Global = true }) ?? "";
}
void Salvar(string nome, string valor)
{
var h = EventSetParameter;
if (h == null) return;
h(this, new EventSetParameterEventArgs { Param = nome, Value = valor, Global = true });
}
// Salvar("api_url", "https://meu-erp/api");
// var url = Ler("api_url");
Visão comercial e catálogo: Criar extensão · Hub de Integrações.
Guid, Name, Icon, ButtonListEventOnFiscalChanged, EventOnTagChanged, EventGetParameter, EventSetParameter, EventSetChannelInIsChannelSender / IsChannelReceiver + funcExecuteChannelSender / funcExecuteChannelReceiverIsTaskEnabled, TaskFrequency (minutos), funcExecuteTaskclsRetFunc — use Type = "E" para erro e "S" (ou outro não-erro) para sucesso; Message aparece no rastreio.Tipos úteis no envio: clsDocScope (documento, itens, eventos, vínculos) e pFileType (ex.: XML, PDF, NOTFIS, CONEMB).
clsMainClass) → não carrega.Guid/Name do assembly diferentes da classe → rejeitado na importação.Dúvidas de homologação ou parcerias: suporte@fiscal.io.