TNK System suporte@tnksystem.com.br
(51) 2700-8001

Especificação de integração

Integração do ecommerce com o ERP TNK

Como o site troca dados com o ERP: o que o ERP publica, o que o site precisa devolver e as regras que, se ignoradas, fazem o pedido entrar errado sem gerar erro. Documento voltado a quem desenvolve a loja.

Formato OfficeWeb 1.4 · acompanha os schemas expOfficeWeb.xsd, impOfficeWeb.xsd, typesOfficeWeb.xsd e a pasta Exemplos.

Esta é a versão sempre atual. Ela vive em docs.tnksystem.com.br/integrador-ftp e é atualizada quando o protocolo muda. O pacote .rar que você recebeu continua valendo para os schemas .xsd e a pasta Exemplos — mas, se o texto divergir, o que vale é esta página.

1Quem faz o quê

O ERP TNK roda na infraestrutura do lojista, atrás do firewall dele. Não há API HTTP nem acesso ao banco: a integração é troca de arquivos XML por FTP, e o ponto de encontro é um servidor FTP acessível pelos dois lados.

Quem faz o quê:

As duas pontas nunca se falam em tempo real. O integrador roda em ciclos (por padrão, exportação a cada 30 minutos e importação a cada 5), então trate a integração como assíncrona: um pedido gravado no FTP entra no ERP na próxima rodada, não no mesmo instante.

Direção dos nomes

Os nomes dos arquivos são do ponto de vista do ERP: Exp* é o que o ERP exporta (você lê), Imp* é o que o ERP importa (você escreve). Não é o ponto de vista do site.

2Transporte: o FTP

FTP simples na porta 21, modo passivo. Duas pastas, cujos nomes são configuráveis por instalação, mas na prática são sempre estes:

PastaQuem escreveQuem lêConteúdo
/exportIntegrador TNKSite ExpProdutos_NN.xml, ExpClientes_NN.xml, ExpIndexadores_NN.xml
/importSiteIntegrador TNK ImpOfficeWeb_NN.xml

Numeração dos arquivos

O NN é um sequencial inteiro por prefixo, sem zeros à esquerda (ExpProdutos_1.xml, ExpProdutos_2.xml, …). Cada prefixo tem a sua contagem própria e o integrador nunca sobrescreve um arquivo existente: ele olha o maior número já presente na pasta e continua dali.

Você é responsável por limpar o /export

O integrador não apaga o que escreveu. Depois de consumir uma remessa, remova o arquivo (ou mova para uma subpasta sua). Se nada for removido, a pasta cresce indefinidamente — e cada ExpProdutos com imagens tem alguns MB.

Processe sempre em ordem crescente de NN: uma remessa mais nova reflete o estado mais recente do ERP.

Na direção contrária, o integrador cuida da limpeza sozinho: o que ele lê de /import é movido para /import/processados. Não conte com o arquivo continuar em /import, e não use essa pasta como seu histórico.

Escreva o arquivo de forma atômica

O integrador pode passar exatamente enquanto você está enviando, e vai ler um XML pela metade. Envie com nome temporário (ex.: ImpOfficeWeb_12.tmp) e só então renomeie para .xml. O rename no FTP é instantâneo; o upload não.

3Regras do arquivo XML

O formato é validado por XSD, e há quatro detalhes que reprovam o arquivo mesmo com o conteúdo correto:

  1. UTF-8 sem BOM. O BOM (EF BB BF) no início quebra a leitura. Vários frameworks o inserem por conta própria — confira o primeiro byte do arquivo gerado.
  2. Sem a declaração <?xml … ?>. O arquivo começa direto na tag raiz. É assim que o integrador oficial do ERP sempre gerou, e é o que está nos exemplos.
  3. A ordem dos elementos é obrigatória. Os schemas usam xs:sequence, não xs:all: trocar dois campos de lugar invalida o arquivo, ainda que os nomes estejam todos certos. Siga a ordem dos Exemplos, não a ordem alfabética nem a da sua struct.
  4. O atributo versao na raiz é obrigatório: <ImpOfficeWeb versao="1.4">.

Ainda sobre tipos, o que mais causa retrabalho:

4ERP → site

ArquivoTraz
ExpProdutos_NN.xml produtos com preço, saldo, grupo/subgrupo/marca, dados de ecommerce, tabelas de preço, grades e imagens
ExpClientes_NN.xml clientes já cadastrados no ERP, com endereço
ExpIndexadores_NN.xml indexadores e seus valores de custo e venda

A lista de campos está no expOfficeWeb.xsd e não vale repetir aqui. O que o schema não conta:

5Imagens do produto

As imagens vão dentro do XML, em base64, nos formatos jpg, bmp ou png (o formato vem no atributo formato). O base64 é quebrado em linhas de 76 colunas.

São dois lugares, com papéis distintos:

ElementoÉQuantidade
<Imagem> a foto de capa do produto no máximo uma (o schema não permite repetir)
<Imagens> as demais fotos, na ordem definida no ERP quantas o produto tiver
A regra, em uma frase

A capa não se repete dentro de <Imagens>. Para montar a galeria completa do produto, use <Imagem> seguida das fotos de <Imagens>. Para a vitrine e a listagem, use só <Imagem>.

Os dois blocos são opcionais: produto sem foto simplesmente não os traz, e produto só com capa não traz o <Imagens>. Trate a ausência como normal.

<Descricao> dentro da imagem é o nome do arquivo como está no ERP. Serve para você reconhecer a mesma imagem entre duas remessas e não reprocessar base64 que já baixou.

6Site → ERP: pedidos

Um único arquivo, ImpOfficeWeb_NN.xml, com dois blocos opcionais na ordem <Clientes> e depois <Pedidos>. Pode levar vários pedidos.

<ImpOfficeWeb versao="1.4">
  <Clientes>
    <Cliente CPFCNPJ="02945423022">
      <Nome>Nome do comprador</Nome>
      <CPF>02945423022</CPF>
      <Fone>51996784439</Fone>
      <Email>comprador@exemplo.com.br</Email>
      <Endereco>
        <CodigoIBGE>4307708</CodigoIBGE>
        <CEP>93265-000</CEP>
        <Bairro>Centro</Bairro>
        <Endereco>Rua Rio Grande</Endereco>
        <Numero>724</Numero>
      </Endereco>
    </Cliente>
  </Clientes>
  <Pedidos>
    <Pedido Id="1042">
      <Data>2026-09-08</Data>
      <Hora>14:30:00</Hora>
      <ClienteDoc>02945423022</ClienteDoc>
      <Vendedor>0</Vendedor>
      <ValorTotal>149.80</ValorTotal>
      <Itens>
        <Item Sequencial="1">
          <Produto>1116</Produto>
          <Quantidade>2.0000</Quantidade>
          <ValorUnitario>74.9000</ValorUnitario>
          <ValorTotal>149.80</ValorTotal>
        </Item>
      </Itens>
      <Observacao>Pedido do site</Observacao>
      <NaoCalcularIPI>false</NaoCalcularIPI>
      <Mobile>false</Mobile>
      <Ecommerce>true</Ecommerce>
      <Bonificacao>false</Bonificacao>
    </Pedido>
  </Pedidos>
</ImpOfficeWeb>

Identificando o comprador

O pedido aponta para o cliente de uma de duas formas — o schema exige exatamente uma (é um xs:choice):

O integrador procura o comprador no cadastro do ERP nesta ordem: CPF/CNPJ, id externo gravado em importação anterior, código do cliente, e-mail. Achou, reaproveita; não achou, cria a partir do bloco <Clientes>.

Cadastro existente nunca é sobrescrito

Se o comprador já está no ERP, o que ele digitou no site é descartado — o dado do ERP é o dado do vendedor, e prevalece. Não use o pedido para tentar corrigir endereço ou telefone de cliente antigo: não vai ter efeito.

<CodigoIBGE> é o que amarra a cidade. O ERP resolve cidade e UF por esse código, não pelo nome nem pelo CEP. Sem ele — ou com um código que não existe na tabela do ERP — o cliente é criado sem cidade e sem UF, e alguém vai ter que completar à mão. Mande sempre os 7 dígitos do IBGE do município.

Campos do pedido que costumam faltar

Estes são obrigatórios pelo schema mesmo quando não fazem sentido para uma loja — mande com valor neutro em vez de omitir: <Observacao> (pode ir vazio), <NaoCalcularIPI>, <Mobile>, <Ecommerce>, <Bonificacao>. Marque <Ecommerce>true</Ecommerce>: é o que identifica o pedido como vindo da loja.

<Itens>: cada <Item> exige o atributo Sequencial (1, 2, 3…), o <Produto> (o Id do ExpProdutos), quantidade, valor unitário e valor total. Item de produto com variação leva <Grades>, com a quantidade de cada <Grade Id="…"> — e a soma das grades tem que fechar com a <Quantidade> do item.

<Status> é opcional e vai pela descrição, não por código (ex.: Cancelado). A lista válida é a tabela de status daquele ERP; descrição que não casa entra como Aberto. Pedido com status de cancelado não baixa estoque.

O que acontece do outro lado

Todo pedido importado entra aguardando o financeiro e baixa o estoque dos itens. Aprovar, faturar e emitir nota são atos manuais dentro do ERP — o site não controla isso, e não há caminho de volta informando que o pedido foi aprovado.

7Códigos que vêm do ERP

Quatro campos do pedido são códigos internos do ERP daquele lojista. Não existe numeração padrão entre instalações, e nada no protocolo os sincroniza: a lista é levantada na base do cliente e passada a você pelo suporte TNK.

CampoCódigo inexistente ou ausente
<FormaPagamento> grava zerado — o financeiro completa à mão
<Vendedor> cai no vendedor padrão configurado no integrador
<Transportador> grava zerado
<TabelaPreco> (no item) grava zerado; o valor do item é o que você mandou
Este é o erro que não parece erro

Nenhum desses casos falha o pedido: ele entra normal, só com o campo errado. Um número chutado é pior que a omissão — ele casa com uma forma de pagamento real do ERP, com prazo e taxa próprios, e o contas a receber nasce errado sem ninguém perceber.

Portanto: na dúvida, omita <FormaPagamento> em vez de enviar um valor provisório. Zerado é visível para o financeiro; errado, não. <Vendedor> é obrigatório pelo schema — se não tiver o código, mande 0 e o integrador usa o padrão da instalação.

8Reenvio e duplicidade

A identidade do pedido é o atributo Id do <Pedido> — o número dele no seu sistema. Use um id estável e nunca o reutilize para outro pedido.

Com base nele, o integrador decide sozinho:

Não use o reenvio para alterar itens

Mudou a composição do pedido depois de importado? A correção é feita dentro do ERP, pelo operador. Reenviar com itens diferentes atualiza o cabeçalho e deixa os itens antigos — o pedido fica inconsistente. Reenvio serve bem para mudança de status.

9Por que um pedido é recusado

Quando algo não fecha, o pedido é recusado inteiro e sem gravar nada — nunca entra pela metade. Os outros pedidos do mesmo arquivo seguem normalmente, e o arquivo só sai de /import quando todos os pedidos dele tiverem sido resolvidos.

Ou seja, um pedido recusado deixa o arquivo parado em /import e a rodada seguinte tenta de novo — os pedidos que já entraram são pulados, sem risco de duplicar. Corrigido o cadastro no ERP (o produto que faltava, por exemplo), o pedido entra sozinho na próxima rodada, sem precisar reenviar o arquivo.

As causas, em ordem de frequência:

Antes de acusar o integrador, peça ao lojista o log: logs\integrador-ftp.jsonl, na pasta do programa. Ele registra arquivo, pedido e motivo de cada recusa.

10Checklist antes do primeiro envio

Valide contra o XSD e confira estes pontos antes de gravar o primeiro ImpOfficeWeb em ambiente de produção: