← Projects

Integração fiscal entre Shopify e CloudInvoice

Worker em TypeScript que transforma cada pedido pago em documento fiscal no CloudInvoice, com idempotência, criação de cliente e produto sob demanda e abate de estoque.

TypeScriptCloudflare WorkersShopify APICloudInvoice APIWebhooks
Status
In production
Year
2026
Context
Varejo de moda · operação em Portugal
0
Documentos fiscais emitidos no ensaio
Produção
Cadeia provada, aguardando a 1ª venda
Integração fiscal entre Shopify e CloudInvoice

Project write-up available in Portuguese only for now.

O problema

A loja vendia online e alguém abria o CloudInvoice, o ERP fiscal da empresa, para lançar cada pedido à mão. Além do tempo, era fonte constante de erro: série fiscal trocada, armazém errado, família de produto que não batia com o cadastro. E a mesma razão social também tem operação física, então o documento precisava sair isolado por série, armazém e família. Sem isso, a contabilidade das duas frentes se misturava.

O que construí

Um Worker na Cloudflare, em TypeScript, entre a Shopify e o CloudInvoice:

  • Escuta o webhook de pedido pago da loja.
  • Traduz o pedido para o formato do documento fiscal, aplicando as regras de série, armazém e família da empresa.
  • Cria cliente e produto sob demanda quando o pedido traz alguém ou algo que ainda não existe no cadastro, em vez de falhar e exigir cadastro manual antes.
  • Abate o estoque na mesma operação.
  • Emite o documento e devolve o número gerado.

Decisões técnicas

Idempotência antes de tudo. Webhook não é entregue exatamente uma vez, é entregue pelo menos uma vez. Sem uma chave de idempotência amarrada ao pedido, uma reentrega gera fatura duplicada, e em documento fiscal isso é problema contábil, não bug de software. Cada pedido é marcado antes da emissão, e reprocessamento devolve o documento já criado em vez de emitir outro.

Worker em vez de servidor. O volume é baixo e irregular, com picos em campanha e silêncio no resto. Sem servidor, não há máquina ociosa custando dinheiro nem host esquecido sem atualização, que é o tipo de coisa que vira incidente de segurança seis meses depois. Escala sozinho no pico.

Modo ensaio. Testar integração fiscal é diferente de testar o resto: um erro aqui não produz log vermelho, produz documento legal que alguém precisa anular depois. Por isso construí um modo que percorre a cadeia inteira contra a empresa real, monta o documento, confere o total e apaga o rascunho no fim, sem emitir nada.

Falha explícita, e visível de fora. Quando o CloudInvoice recusa o documento, o erro fica registrado com o pedido que o causou, em vez de ser engolido. Além disso, um endpoint de saúde expõe a última fatura emitida e um monitor externo avisa por e-mail quando ele para de responder. Integração que falha em silêncio é pior que integração que não existe: ninguém percebe até fechar o mês.

Como verifiquei

O ensaio rodou em produção, contra a empresa real. Um pedido de teste gerou o rascunho com o total exato, na série certa, criando pelo caminho o produto de portes que ainda não existia no cadastro. O rascunho foi apagado no fim. Nenhum documento fiscal foi emitido.

Foi conferindo esse documento contra o pedido, campo a campo, que apareceu um erro que o log não mostrava: o preço líquido era arredondado antes de o sistema fiscal reaplicar o imposto, e o total fechava com diferença de centavos. Só aparecia na comparação.

Também reprocessei o mesmo pedido para confirmar que a idempotência segura a duplicata, e exercitei os caminhos de cliente novo e de produto novo.

O que ainda falta: a primeira venda real. A cadeia está provada em produção e a loja está em fase de lançamento.