Skip to content

Ecommerce accounting architecture

Attribute Value
Contract version 1.0-draft
Pilot Shopify to Accountify to Odoo 19 Online
Posting profile order_invoice_v1
Platform dependency Accountify platform specification v0.3
Required contract set Ecommerce contract registry

This document set is normative for ecommerce ingestion and posting. The contract registry defines the complete Shopify pilot set, ownership, precedence, and readiness boundary. The platform specification remains normative for tenant isolation, identity, operation handling, Odoo execution profiles, authorization, resilience, and common API behavior.

Objectives

  • Ingest source commerce and financial evidence without coupling source schemas to Odoo.
  • Produce reproducible canonical records and accounting decisions from versioned inputs and policies.
  • Post only allowlisted, tenant-authorized commands to Odoo.
  • Reconcile gross commerce activity through fees, refunds, disputes, payouts, bank transactions, and Odoo clearing accounts.
  • Preserve evidence sufficient to explain every posted amount and safely replay non-mutating transformations.

Non-goals for the pilot

  • Real-time general-ledger posting.
  • Automatic handling of tax or accounting cases that have not been approved in a tenant policy.
  • Direct Airbyte-to-Odoo data activation.
  • A complete customer-data lake.
  • Cross-tenant source or Odoo credentials.
  • A generic endpoint that accepts arbitrary Odoo models, methods, domains, fields, or context.

Runtime architecture

flowchart LR Shop[Shopify API and webhooks] Airbyte[Airbyte replication] Inbox[Ingestion inbox] Raw[(Encrypted raw evidence)] Canon[Canonicalizer] Core[(Canonical commerce)] Policy[Policy and mapping engine] Ops[(Integration operations)] Worker[Odoo posting worker] Odoo[Client Odoo Online] Readback[Readback worker] Recon[Settlement reconciler] Bank[Odoo bank transactions] Marts[(Operational marts)] Shop --> Airbyte --> Inbox Shop -->|signed webhooks| Inbox Inbox --> Raw Inbox --> Canon --> Core Core --> Policy --> Ops --> Worker --> Odoo Odoo --> Readback --> Core Core --> Recon Bank --> Recon Recon --> Marts Readback --> Marts

Airbyte incremental replication is at least once and cursor-based. The implementation must tolerate duplicate records and must run completeness reconciliation because source changes can be missed when a connector cannot observe deletion or a source fails to update its cursor. See the Airbyte sync-mode contract.

Component ownership

Component Owns Must not own
Source platform Original orders, transactions, fulfillments, refunds, payouts, disputes Accountify accounting classification
Airbyte Scheduled extraction and raw destination writes Posting decisions, canonical IDs, Odoo calls
Ingestion service Trusted tenant attribution, webhook verification, deduplication, run evidence Accounting policy
Canonicalizer Versioned source-to-canonical transforms Odoo mutation
Policy engine Mapping validation and deterministic posting intent Legal ledger state
Operation service Durable commands, approval, idempotency, attempts, leases, audit Source extraction
Odoo Posted invoices, credit notes, payments, reconciliation, stock and valuation Raw source history and cross-client reporting
Reconciliation service Source-to-settlement-to-bank evidence and exceptions Silent write-offs
Warehouse marts Rebuildable operational and analytical views Transactional workflow state

Required identifiers

No source ID or Odoo ID is globally unique. Every reference uses the applicable composite identity:

Source:    (tenant_id, source_connection_id, source_object_type, source_object_id)
Canonical: (tenant_id, canonical_object_type, canonical_object_id)
Odoo:      (tenant_id, odoo_connection_id, company_id, odoo_model, odoo_record_id)
Event:     (tenant_id, source_connection_id, source_event_id)

Every boundary payload includes contract_version, tenant_id, correlation_id, occurred_at, and observed_at. Every amount includes amount as a decimal string and currency_code as ISO 4217.

Pilot end-to-end flow

  1. Provision a tenant, Shopify connection, Airbyte connection, Odoo connection, allowed company, secrets, and policy version.
  2. Run source and Odoo capability scans. Block enablement on missing required streams, fields, groups, journals, taxes, warehouses, or wrapper evidence.
  3. Backfill Shopify into the raw destination. Stamp trusted tenant and connection metadata in the ingestion envelope.
  4. Enable signed webhooks. Deduplicate webhook deliveries and schedule out-of-band canonicalization.
  5. Canonicalize immutable commerce events and current entity snapshots.
  6. Validate source totals, currency, tax, SKU, customer, warehouse, journal, payment, and fee mappings.
  7. Create an approved posting intent under order_invoice_v1 and persist an integration_operation before queue delivery.
  8. Execute the allowlisted Odoo command, classify timeout-unknown safely, and read back authoritative state.
  9. Ingest settlements and payouts, allocate financial lines, match the bank transaction, and reconcile the Odoo clearing account.
  10. Publish operational projections and marts only from confirmed canonical, Odoo readback, and reconciliation facts.

Contract map

Change control

  • Source adapters, canonical schemas, policies, command payloads, events, and readback schemas are independently versioned.
  • Breaking changes require a migration and dual-read or dual-write plan where in-flight work exists.
  • An operation always stores the exact adapter, canonical schema, mapping, policy, and command versions used.
  • Changes that affect tax, posting grain, journal selection, recognition date, rounding, clearing, or write-off behavior require accounting-owner approval.
  • Changes that weaken tenant isolation, secret handling, webhook verification, idempotency, or readback require security-owner approval.