Skip to content

ADR-301: Commerce — Quote, Order, Invoice, TaxInvoice

Status: Accepted

Contexto

O ciclo financeiro B2B da MIDDAG é fragmentado: quotes criados manualmente, orders criados à mão no WooCommerce, invoices buscados no Stripe por email, NFSe emitidas uma a uma no portal ISSNet (emissor NFSe municipal, Brasília/DF). Não existe pipeline automatizado de proposta-a-pagamento. A operação dual-entity (BR + GLOBAL) com moedas BRL + USD adiciona complexidade — a conta Stripe errada significa fatura errada e reembolso. O WooCommerce é o motor de commerce mas não oferece nativamente: organizations, quotes com lifecycle, dual-entity routing, nem NFSe.

Decisão

4 Domínios no Bounded Context Commerce

DomínioTipoResponsabilidadeFonte de Dados
QuoteCOREPropostas comerciais com lifecycle de 8 estadosPlugin (CPT) + woocommerce-quotes (satélite)
OrderCORERegistros de compraWooCommerce (HPOS) via adapter
InvoiceCOREFaturas financeirasStripe via adapter
TaxInvoiceOPTIONALNotas fiscais NFSe brasileirasISSNet (SOAP) via adapter

Quote Lifecycle (8 estados)

draft → sent → viewed → accepted → paid → fulfilled

                            expired ←──┘ (timeout configurável)
                            rejected ←──── (cliente recusa)
EstadoSignificadoTransição seguinte
draftCriado, ainda não enviado ao cliente→ sent
sentEnviado ao cliente (link do portal)→ viewed, expired
viewedCliente abriu o quote no portal→ accepted, rejected, expired
acceptedCliente aceitou (aceite digital no portal)→ paid
paidPagamento confirmado (Stripe/Banco Inter)→ fulfilled
fulfilledEntitlement provisionadoEstado terminal
expiredTimeout sem ação do clienteEstado terminal (re-enviável)
rejectedCliente recusou explicitamenteEstado terminal (re-enviável)
refundedEstorno processado após pagamentoEstado terminal

Nota: O 9o estado refunded cobre o cenário excepcional de estorno pós-pagamento (paid -> refunded). O estorno cancela o WC Order e sincroniza status com HubSpot.

Automação Quote → Order → Payment → Entitlement

Pipeline de 6 etapas, maioria automatizada:

  1. Deal HubSpot → Quote criado (sync automático ou manual)
  2. Quote enviado → Cliente visualiza no portal
  3. Cliente aceita → WC Order criada automaticamente
  4. Pagamento → Stripe/Banco Inter processa (webhook confirma)
  5. Entitlement provisionado → Auto-provisioning por classe
  6. Fulfilled → Cliente notificado

Detalhes em REF-301-03.

Dual-Entity Routing (BR vs GLOBAL)

Cada transação é roteada para a entidade legal correta (MIDDAG BR ou MIDDAG GLOBAL) com base em: tax ID do cliente (CNPJ→BR, EIN/VAT→GLOBAL), billing_entity da Organization, entity tag do produto, ou moeda preferencial como fallback. Admin pode override por transação.

Detalhes em REF-301-01.

Multi-Moeda BRL + USD

Dois preços fixos por produto (preferido) ou conversão automática via faixas de câmbio configuráveis (low/medium/high). Preço BR intencionalmente mais alto que LLC (incentiva compras internacionais pela LLC). UST tem valores independentes por moeda (não apenas conversão).

Detalhes em REF-301-02.

WooCommerce Como Motor de Commerce

WooCommerce é o backbone de orders, pagamentos e subscriptions — mas invisível para o cliente final. O cliente interage via portal NextJS (REST API) ou admin UI (Inertia), nunca vê terminologia ou UI do WooCommerce. OrderAdapter traduz WC orders → domain Order. SubscriptionAdapter abstrai WC Subscriptions. InvoiceAdapter traduz Stripe invoices → domain Invoice.

Backoffice exclusivo: Nenhuma página, formulário ou interface WooCommerce é exposta ao usuário final. O acesso acontece exclusivamente via WP admin pela equipe de operações. O checkout não é WooCommerce tradicional — o pedido já existe (criado pela equipe ou por integração) e o cliente no portal apenas executa o pagamento.

WC Subscriptions resolve toda a complexidade de recorrência: proration, upgrades, downgrades e recuperação de pagamento. O SubscriptionAdapter abstrai esses mecanismos para o domínio.

Plugins satélite (externos, open-source):

PluginResponsabilidadeRelação com middag-account
woocommerce-banco-interGateway Banco Inter (Pix + Boleto)Integração via hooks WC de pagamento
woocommerce-quotesEntidade Quote no WC (CPT, checkout flow)middag-account consome via hooks e API interna

Ambos os plugins são mantidos pela MIDDAG e planejados para lançamento open-source. O plugin middag-account integra-se com eles via hooks WooCommerce — nunca acopla diretamente ao código interno dos plugins satélite.

Invoice (Adapter Stripe)

Invoice é adapter somente-leitura do Stripe. Webhooks sincronizam estado. Invoice vinculado a Organization e Entitlement (via Order). PDF do Stripe disponível para download no portal.

TaxInvoice (NFSe via ISSNet — OPTIONAL, apenas BR)

Domínio OPTIONAL — relevante apenas para entidade BR. Submissão via API SOAP ISSNet. Polling para status. XML/PDF vinculado ao Invoice de origem.

Detalhes de integração Stripe (12 webhooks, dual-account, cron sync) e ISSNet (SOAP, certificado, PDF) em REF-301-04.

Consequências

Positivas:

  • Pipeline automatizado elimina criação manual de orders e setup manual pós-pagamento
  • Quote com 8 estados permite analytics do pipeline (tempo até aceite, taxa de conversão)
  • Dual-entity routing previne erros de conta Stripe/sistema fiscal
  • WC invisível para cliente — experiência B2B profissional, não loja de e-commerce

Negativas:

  • Quote lifecycle de 8 estados adiciona complexidade de máquina de estados
  • Dual-entity routing requer StripeAccountResolver (não existente no tema — bloqueador #4)
  • Dependência de webhooks Stripe e WC para pipeline funcionar end-to-end
  • TaxInvoice com ISSNet SOAP é frágil (polling, formato XML legado)

Referências

  • REF-301-01 — Dual-Entity Routing Rules
  • REF-301-02 — Multi-Currency Model
  • REF-301-03 — Quote-to-Entitlement Pipeline
  • REF-301-04 — Invoice & TaxInvoice Spec
  • ADR-202 — Entitlement (auto-provisioning downstream do pipeline)
  • ADR-103 — Plugin Ecosystem (WC como dependência, satélites)
  • operations/02-business-lines.md §2 — Dual-entity, §5 — Receita