Pular para conteúdo

Cenário 3 — dados entrando no X-Adm

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-25

Aplica-se a: equipe X-Adm (ERP/ZIM) e quem opera a nuvem.

O que é

Um sistema de fora (um parceiro, como a PIED) gera dados que precisam entrar no ERP — por exemplo, pedidos pagos que viram pedidos no X-Adm. O caminho:

  1. um app do parceiro na nuvem (pied.<cliente>.xadm.biz) recebe do parceiro e traduz para o formato do X-Adm;
  2. ele entrega ao integrador (int.<cliente>), que grava nas mesmas tabelas-espelho do cenário 1, marcadas como pendentes de importação;
  3. o PowerSync leva os pendentes ao integrador-client, um programa Java no servidor do cliente;
  4. o integrador-client chama a rotina pAbast do ZIM, que grava no ERP, e devolve o resultado linha a linha à nuvem.

Clientes neste cenário hoje: Maxsul (pedidos da PIED). O mesmo mecanismo faz a baixa de MDF-e com a Sascar (ver §MDF-e).

sequenceDiagram
    participant PIED as PIED (parceiro)
    participant APP as pied.<cliente>
    participant INT as int.<cliente>
    participant PS as ps.<cliente>
    participant IC as integrador-client (servidor do cliente)
    participant ZIM as ERP X-Adm (pAbast)

    PIED->>APP: webhook do pedido (e consulta periódica)
    APP->>APP: guarda o original, traduz para o formato X-Adm
    APP->>INT: PUT /api/v1/xadm (Origem INT-PIED)
    INT->>INT: grava no espelho com cod_retorno = 000 (pendente)
    INT->>PS: replicação
    PS->>IC: linhas pendentes
    IC->>ZIM: dXpEnvio + zimrtmu.exe pAbast
    ZIM-->>IC: dXpRetorno (código por linha)
    IC->>INT: POST /api/v1/powersync (006 gravado ou 1XX erro)
    INT->>PS: status atualizado
    PS->>APP: (o app consulta o status pelo integrador)

O status de cada linha: cod_retorno

Toda linha que vai para o ERP carrega um código de retorno. É o que se olha para saber onde um pedido está.

cod_retorno Significa Próximo passo
000 pendente — ainda não foi ao ERP o integrador-client pega no próximo ciclo
001 em processamento no integrador-client aguardar
006 gravado no X-Adm fim
1XX erro de dado, definitivo (ex.: 120-Cliente CPF … não cadastrado) corrigir a causa e re-armar (ver §Verificação); não volta sozinho
9XX erro temporário o integrador-client tenta de novo sozinho

O texto do erro vem em msg_retorno, como o ZIM escreveu.

Linhas que dependem umas das outras (cliente → pedido → itens → fórmula do kit) são agrupadas numa remessa: o integrador-client só envia ao ERP a remessa completa, para o ERP nunca receber um item sem o pedido. A remessa fica ABERTA (a caminho), ENTREGUE (tudo 006), TRAVADA (alguma linha 1XX) ou RESOLVIDA_MANUAL (o operador lançou à mão no X-Adm e fechou).

Pré-requisitos

  • Base do cliente na nuvem: banco, integrador e PowerSync (Cliente novo, passos 1 a 6 — inclusive o cadastro na Central).
  • No integrador do cliente, CLIENTE_ID e CENTRAL_API_TOKEN preenchidos (sinal de vida do integrador-client).
  • No servidor do cliente: Windows 64 bits, Java 8 ou mais novo de 64 bits, saída HTTPS para ps.<cliente>.xadm.biz e int.<cliente>.xadm.biz.
  • A rotina pAbast instalada no ZIM do cliente (equipe X-Adm), na versão que conhece o fluxo.

Passos

1. Definir o que entra e em quais tabelas

A equipe X-Adm e a nuvem combinam, por fluxo:

  • quais tabelas do X-Adm recebem o dado (na PIED: propriedades, fones, estoque, contratos, itensped, formulas) e quais campos de cada uma;
  • a chave de cada registro — sempre a do X-Adm; o código do parceiro entra só como campo de rastreio, nunca como chave;
  • o layout de cada tabela no arquivo dXpEnvio e os códigos de retorno do pAbast — é o contrato pAbast, que a equipe X-Adm valida.

Tabela ou coluna nova segue o mesmo caminho do cenário 1 (§Definir o banco-espelho).

2. O app do parceiro — pied.<cliente>.xadm.biz

Cada parceiro tem o seu app, dono das próprias tabelas (pied_*). O da PIED:

  • Recebe o webhook da PIED em POST https://pied.<cliente>.xadm.biz/webhook/pied e, de tempos em tempos, consulta a API da PIED para não perder nada. Guarda o original antes de processar.
  • Só envia pedido pago. O pedido vai para o X-Adm quando o pagamento vira received.
  • Traduz para o formato do X-Adm (natureza de operação por UF, kit × produto simples, telefone) e envia ao integrador com Origem: "INT-PIED", na ordem cliente → contato → produto → pedido → itens → fórmulas.
  • Não reenvia o que não mudou (compara o conteúdo) e, se o integrador estiver fora, guarda numa fila e tenta de novo.
  • Mostra cada pedido, o seu status e o retorno do ERP no painel https://pied.<cliente>.xadm.biz/.

Na Maxsul o fluxo está em produção: o pedido pago segue sozinho, sem liberação manual (PIED_INTEGRACAO_MODO=PRODUCAO). Pendente: as telas do app ainda não pedem login — o gate de login Google (@xadm.com.br) está planejado. Até lá, o endereço do painel não deve circular fora da equipe.

Implantação do app — recurso no Coolify, variáveis e a ordem segura de ligar (primeiro só capturar, depois homologação, depois produção): Implantação do maxsul-pied · Configuração.

A PIED desliga o webhook sozinha

Se uma entrega falhar (app fora do ar, erro), a PIED desativa o webhook e não religa. O app tem um vigia que avisa; o recadastro é manual no painel da PIED: Recadastrar o webhook.

3. O integrador

Nada específico a configurar além do Cliente novo — integrador: o integrador recebe o PUT do app do parceiro exatamente como recebe o do X-Adm, grava as linhas com cod_retorno = 000 e monta as remessas. Duas regras:

  • o INTEGRADOR_API_TOKEN do app do parceiro é o mesmo do integrador;
  • a origem nova do parceiro precisa estar na lista de origens conhecidas do integrador, senão os erros dela não geram alerta (INT-PIED já está).

4. Sincronização: o que o integrador-client enxerga

No powersync.yaml do cliente entram as tabelas do fluxo e as remessas vivas. Na Maxsul:

streams:
  global:
    auto_subscribe: true
    queries:
      - SELECT * FROM contratos    WHERE deleted = false
      - SELECT * FROM propriedades WHERE deleted = false
      - SELECT * FROM fones        WHERE deleted = false
      - SELECT * FROM itensped     WHERE deleted = false
      - SELECT * FROM estoque      WHERE deleted = false
      - SELECT * FROM formulas     WHERE deleted = false
      - SELECT * FROM integracao_remessa WHERE (status = 'ABERTA' OR status = 'TRAVADA')
      - SELECT * FROM integracao_remessa_item WHERE remessa_id IN (SELECT id FROM integracao_remessa WHERE (status = 'ABERTA' OR status = 'TRAVADA'))

E a chave pública do integrador-client do cliente entra em client_auth (passo 6). Toda mudança exige publicar o repo do PowerSync.

5. Importação no ERP: integrador-client e pAbast

A cada ciclo (na hora em que chega dado novo, e de 5 em 5 minutos como segurança), o integrador-client:

  1. junta as linhas com cod_retorno 000 ou 9XX — só remessas completas, até 999 linhas por lote — e marca como 001;
  2. escreve o arquivo dXpEnvio na pasta do X-Adm (largura fixa, windows-1252, uma linha por registro);
  3. executa zimrtmu.exe pAbast nessa pasta;
  4. espera o ZIM escrever Iniciou Zim no dXpRetorno e responde com o literal do fluxo (IMPORTA_PIED na PIED) — a partir daqui o ERP está gravando;
  5. lê o dXpRetorno: um código e uma mensagem por linha enviada, na mesma ordem;
  6. grava o código de cada linha e devolve à nuvem (POST https://int.<cliente>.xadm.biz/api/v1/powersync). Sem internet nessa hora, o resultado fica numa fila local e sobe quando a rede voltar.

O lado da equipe X-Adm é a rotina pAbast: ler o dXpEnvio, gravar, e escrever o retorno de cada linha com o código certo — 006 para gravado, 1XX para erro de dado (com a mensagem), 9XX para erro que vale tentar de novo. O layout de cada tabela, os literais e os casos de erro estão no contrato pAbast.

O pAbast precisa aceitar a mesma linha duas vezes

Se o integrador-client cair depois de o ERP começar a gravar e antes de receber o retorno, ele reenvia a linha no próximo ciclo. Reenviar um pedido já gravado não pode gerar um pedido novo.

6. Instalar o integrador-client

Na nuvem, antes de ir ao cliente:

  1. Gerar o par de chaves da instalação — a chave privada é a credencial do cliente:

    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out <cliente>-private.pem
    openssl rsa -in <cliente>-private.pem -pubout -out <cliente>-public.pem
    
  2. Colocar a pública no powersync.yaml do cliente (client_auth, kid <cliente>-ps-v1, audience <cliente>) e publicar o repo do PowerSync.

  3. Montar o pacote: o .jar, o integrador-client.properties preenchido e o <cliente>-private.pem.

No servidor do cliente, numa pasta só (ex.: C:\integrador-client\):

Arquivo O que é
integrador-client.jar o programa
integrador-client.properties a configuração (abaixo)
<cliente>-private.pem a credencial — nunca copie, mande por e-mail ou suba em repositório
rodar.bat inicia o programa; cadastrado no Agendador de Tarefas para subir com o Windows

Configuração mínima:

cliente=<cliente>
powersync.url=https://ps.<cliente>.xadm.biz

jwt.chavePrivada=<cliente>-private.pem
jwt.kid=<cliente>-ps-v1
jwt.issuer=<cliente>-ps
jwt.audience=<cliente>
jwt.subject=<cliente>-ps-java

powersync.upload.url=https://int.<cliente>.xadm.biz/api/v1/powersync
powersync.upload.token=<INTEGRADOR_API_TOKEN do cliente>

zim.executavel=C:/Zim/zimrtmu.exe
zim.diretorio=C:/X-Adm
zim.fluxos=pied

zim.fluxos é obrigatório; valores válidos: pied, abastecimento, encerra-mdfe (vários, separados por vírgula). Valor inválido faz o programa sair na largada.

Homologar com a equipe X-Adm antes de ligar: rodar java -jar integrador-client.jar --debug, listar os pendentes e processar um lote acompanhado — processar grava no ERP e devolve o status à nuvem. Runbook completo, com códigos de saída e problemas comuns: Instalação do integrador-client.

MDF-e com a Sascar

Mesmo mecanismo, outro gatilho. O X-Adm envia o MDF-e aberto ao integrador (cenário 1, origem PMDFE). O integrador pede ao app compartilhado sascar.xadm.biz que vigie o caminhão; quando a Sascar indica que ele chegou, o app avisa o integrador, que marca o MDF-e para baixa com cod_retorno = 000. O integrador-client (fluxo encerra-mdfe) chama o pAbast, que encerra o MDF-e no ERP. Clientes: Vantroba e Pontual. Contrato de encerramento de MDF-e.

Verificação

Conferir Como Esperado
Pedido chegou do parceiro painel https://pied.<cliente>.xadm.biz/ pedido listado, status ENVIADO ou CONFIRMADO
Pedido no espelho SELECT pied_x_ped, cod_retorno, msg_retorno FROM contratos WHERE pied_x_ped = '<pedido>'; a linha, 000 antes do ERP e 006 depois
Remessas travadas GET https://int.<cliente>.xadm.biz/api/v1/integracao/remessas?status=TRAVADA (Bearer) vazio; senão, cada item em 1XX com a mensagem do ERP
integrador-client vivo aba Deploy da Central (central.xadm.biz) instalação do cliente com sinal de vida recente (alerta após 6 horas úteis sem sinal)
Log do integrador-client logs\integrador-client.log na pasta do programa ciclos sem erro

Destravar uma remessa (1XX): corrigir a causa (por exemplo, o cadastro que faltava no X-Adm) e re-armar: POST https://int.<cliente>.xadm.biz/api/v1/xadm/retorno/pedido/reenfileirar?chave=<pedido> (Bearer) — as linhas voltam a 000. Se o pedido foi lançado à mão no X-Adm, fechar pelo botão Importado manualmente no painel do app do parceiro.

Problemas comuns

Sintoma Causa provável O que fazer
integrador-client com 401 PSYNC_S2101 chave privada não corresponde à pública do powersync.yaml (ou kid/audience diferentes) conferir o par; republicar o PowerSync
Status não sobe para a nuvem powersync.upload.token diferente do INTEGRADOR_API_TOKEN conferir o token
Todo lote fica em 001 e volta ZIM não respondeu Iniciou Zim em 3 s — normalmente licença ZIM ou pAbast ausente conferir o ZIM com a equipe X-Adm
Linha 120-… não cadastrado o ERP recebeu um filho sem o pai (cliente, produto, pedido) cadastrar/corrigir e re-armar
Pedidos novos pararam de chegar da PIED webhook desativado pela PIED recadastrar o webhook
App do parceiro recebe 401 do integrador INTEGRADOR_API_TOKEN ausente ou diferente no app conferir a variável no Coolify; reenviar a fila pelo painel