payment-gateway.app Docs
Architecture

Invoicing & Tax Architecture

Comprehensive guide to the invoicing lifecycle, tax engine, and EU VAT OSS reporting.

Invoicing & Tax Architecture

The Payment Gateway combines document lifecycle controls with a configurable tax engine. Tax is not a frontend estimate: checkout previews, transaction creation, manual invoice previews, issued invoices, refunds, chargebacks, and tax reports all use backend tax settings, rates, rules, and immutable tax record snapshots.

The Invoicing Lifecycle

Invoices separate editable drafts from issued documents with controlled, audited corrections. They transition through specific statuses:

  1. draft: The invoice is an editable placeholder. It can be fully modified, populated via the InvoiceCorrectionService, or deleted entirely without an audit trail.
  2. issued: The invoice becomes a finalized accounting document and its invoice number is permanently assigned. Ordinary draft editing is blocked; subsequent changes use the correction workflow below.
  3. Void / reversal workflow: If an issued invoice must be negated, the platform performs a formal void / reversal workflow rather than mutating the invoice in place. The original invoice remains part of the accounting record.
  4. Payment state (computed): Financial states such as open, partially_settled, settled, credited, overpaid, or refund-derived states are computed from settlement totals instead of being persisted as a mutable invoice status.

Invoice Corrections

Once an invoice reaches the issued state, standard mutations are blocked. The invoice correction workflow can update seller/client snapshots, including a buyer Peppol routing address, and can replace line items when financial-correction eligibility checks pass.

Issued-invoice corrections require a nonblank reason and append audit history with the timestamp and acting user when available. Financial corrections preserve previous and new line items and totals in that history, recalculate tax with the backend engine, and keep the assigned invoice number. Draft line items must be changed through ordinary draft editing.

Financial corrections are rejected for booked invoices, invoices with credit notes or credited/refunded totals, and invoices with multiple linked transactions. If one transaction is linked, it must resolve within the organization and have no refund or chargeback history; the corrected currency and gross total must match that transaction. The correction synchronizes its item/tax snapshot without changing the recorded payment amount. An invoice with no linked transaction is not subject to that payment-total constraint.

Correction is not a refund operation. Use the refund and credit-note workflows to record a reversal. The software's correction controls do not replace the organization's responsibility to assess applicable accounting and legal requirements.

Sequential Number Allocation

Unlike transaction.externalReference, which holds the merchant-provided identifier, invoice numbers are allocated sequentially and must remain unique within an organization. The platform does not promise that the numeric series has no gaps: provider failures, collision avoidance, and an administrator's audited forward adjustment can intentionally leave unused numbers.

The system uses an isolated invoice_sequences MongoDB collection to securely $inc and format document numbers synchronously. Organizations configure per-document layouts that define prefixes, optional middle text and suffixes, start numbers, digit width, calendar-vs-fiscal year behavior, visible period detail, and reset policy.

Supported layouts include:

  • INV-2026-00001
  • INV-2026-03-00001
  • INV-2026-03-27-00001
  • INV-20260327-00001
  • INV2027AR00001

The backend calculates the visible calendar or fiscal period from the actual issue date. Sites inherit the organization-wide numbering layout and sequence policy. They may override prefixes, but they do not create independent per-site sequences or their own fiscal/calendar rules.

The Admin Backend exposes a dedicated active-sequence control; it does not reuse or mutate the layout's starting-number setting. Preview and mutation both resolve the active bucket through the shared legal-timezone numbering utilities. Mutation requires the reviewed current sequence and a fingerprint of the persisted legal-timezone/layout settings, revalidates both immediately before a MongoDB compare-and-set update, and records organization, actor principal, bucket, before/after formatted numbers, reason, timestamp, and outcome in invoice_sequence_adjustments. The sequence document references the adjustment ID so an applied mutation retains durable evidence. Pending or ambiguous audit outcomes are reconciled against that reference on later sequence reads.

Both Admin and Main Backend allocators continue using the existing invoice_sequences collection. This keeps automatic checkout invoicing, manual invoice issue, recurring invoices, and the operator control on one organization-owned allocation mechanism.

Tax Integration Model

Tax behavior is configured per organization in Settings > Tax and then applied consistently across buyer-facing and operator-facing flows.

The platform stores enough tax metadata to explain a calculation later: seller country, buyer country, buyer type, supply type, tax treatment, tax rate code, tax evidence, net amount, tax amount, gross amount, and the source document or transaction.

Supported Tax Capabilities

  • Configurable rates and rules: Tax rates are organization-scoped and effective-dated. Tax rules match seller country, buyer country, buyer type, supply type, priority, and active date.
  • EU VAT OSS: Supports cross-border EU B2C destination-rate handling when OSS is enabled and matching rules/rates are configured. Automatic OSS fallback can use the buyer country's standard rate for EU cross-border B2C sales.
  • EU B2B reverse charge: VAT IDs can be validated through VIES, and validated EU B2B buyers can be treated as reverse-charge where rules permit it.
  • Small-business exemption: Organizations can mark themselves exempt and store the legal reference shown on tax decisions and documents.
  • UK VAT handling: UK VAT rules support B2B reverse charge, digital services, and low-value goods checks when UK VAT configuration is enabled.
  • US and Canada registration settings: The settings model stores US nexus and Canadian GST/HST/PST registration data. Actual calculation still depends on the tax rates and rules configured for the merchant's scenario.
  • IOSS registration metadata: IOSS registration fields are available for merchant configuration. Current tax calculation behavior should be validated against the merchant's import workflow before relying on automatic IOSS treatment.

[!IMPORTANT] The gateway calculates and records tax from your configured settings. Merchants remain responsible for confirming that settings, rates, rules, evidence retention, and filings match their legal obligations.

VAT Rate Versioning

When a tax rate is updated, it is never changed in place. Instead, a new TaxRate record is created with an EffectiveFrom UTC timestamp. When generating a transaction or invoice, the tax engine resolves the applicable rate against the relevant tax-point timestamp and locks the decimal result onto the source record and canonical tax records.

Tax can be calculated from net prices or extracted from gross prices. The organization-level pricesIncludeTax setting is the default, and checkout line items can carry their own amount type. Rounding is centralized through the organization tax rounding method.

Duplicate-payment VAT profiles and preview

Duplicate-payment VAT configuration is kept outside the ordinary rate and rule tables. Organization administrators save immutable, effective-dated advice profiles for an exact jurisdiction, registration scheme, supply scenario, outcome, and evidence set. An organization-wide compare-and-set revision serializes changes across profile IDs, while append-only version rows preserve actor and request provenance. Historical applicability uses the duplicate receipt time and retains earlier nonoverlapping versions.

The Admin preview resolves each stable supply component with the shared pure resolver and returns immutable profile and context references. It is bounded to 100 components and batch-loads unique organization-owned versions. It makes no payment, document, return, or TaxRecord write. Built-in Germany, Austria, and United Kingdom profiles remain unqualified candidate guidance, and posting capability is unavailable. See Duplicate-payment VAT profiles for the merchant workflow, evidence requirements, coverage states, and synthetic examples.

Checkout Tax Preview And Transaction Snapshot

Hosted checkout uses the Main Backend runtime tax preview endpoint before payment submission:

The preview is informational until the transaction is created. On creation and completion, the backend recalculates or materializes the tax snapshot, stores totalNet, totalTax, totalGross, taxBreakdown, taxDecision, and tax evidence on the transaction, then creates canonical tax records for reporting. Completion tax finalization is serialized per transaction before automatic invoice generation, so repeated checkout status polling or provider callbacks cannot replace tax records out of order. Transactions linked to invoices defer to invoice-side tax handling to avoid double-counting.

Manual Draft Invoices And Tax Preview

Manual draft invoices, recurring-generated invoices, and transaction tax calculations intentionally share the same backend tax rules.

  • If a draft invoice line omits taxRate, the backend auto-calculates the rate from seller configuration, buyer billing country, client tax-country fallback, item type, and the effective tax rate at the invoice tax point.
  • If a draft invoice line includes taxRate, that line is treated as an explicit manual override.
  • If a draft invoice line omits taxRateCode, the Admin UI keeps the VAT field in automatic mode and shows the previewed backend result separately. Selecting a VAT rate code is an explicit manual override; the Auto action clears that override and returns the line to automatic rule resolution.
  • The Admin API exposes POST /api/v1/invoices/preview-tax so dashboard flows and API key integrations can resolve the canonical tax result before creating or updating a draft invoice.

This keeps the operator-facing invoice editor consistent with the transaction tax engine instead of relying on a frontend-only rate guess.

When an invoice is issued, the platform writes canonical tax records for the invoice according to the organization's tax recognition mode:

  • accrual: tax is recognized at the invoice tax point / issue timing.
  • cash: tax records are deferred until the invoice is fully settled.

Credit notes create their own tax records that offset the original invoice according to the configured credit-note adjustment mode.

Checkout VAT Validation Resolution

Checkout VAT ID validation is intentionally split into two layers:

  • Checkout settings decide the buyer-facing validation preference for a Site or Organization: none, format, or vies.
  • Tax settings decide whether the merchant is actually allowed to use VIES-backed VAT treatment, via the organization tax capability flags.

At runtime, the Main Backend resolves an effective checkout VAT validation mode before the checkout page is rendered:

  • none stays none
  • format stays format
  • vies stays vies only when the organization tax settings have VIES validation enabled
  • vies is downgraded to format when tax VIES capability is disabled

This prevents a hosted checkout from showing successful live VIES validation to a buyer when the backend tax engine would not honor that validation for tax treatment.

In practice, this means:

  • merchants configure the preferred checkout UX in Settings > Checkout
  • merchants configure reverse-charge and VIES tax capability in Settings > Tax
  • the hosted checkout always consumes the resolved runtime mode exposed by the Main Backend session response

EU VAT OSS Evidence Retention

Operating under the Union OSS scheme mandates that merchants collect and preserve proof of the buyer's establishment.

When a transaction is categorized as EU B2C cross-border OSS, the engine collects location evidence such as billing country, shipping country, IP geolocation country, payment-method country, and phone-prefix country. If strict OSS evidence mode is enabled, the checkout can be blocked when fewer than two evidence sources are available or when evidence sources conflict. Evidence is stored with the transaction and copied into tax records for audit and reporting.

Refunds, Chargebacks, And Credit Notes

Tax reporting does not mutate the original sale. Reversals are represented as separate adjustment records.

Materialized refund and fund-impacting chargeback tax records carry negative net, tax, and gross amounts and link back to the latest sale tax record where available. Their tax-record lines preserve the original line-level country, supply type, and VAT rate code where that source snapshot exists, so mixed goods and digital-service sales reverse into the same countries they were originally reported in. Provider, admin, and rebuild paths use one deterministic allocation mechanism based on stored historical amounts. It does not invent untaxed residuals or cap conflicting source data to make an adjustment balance. Missing, conflicting, or insufficient historical basis remains unresolved; current tax settings are not evidence of historical exemption. Won chargebacks are not reportable reductions: any active chargeback tax record is voided when the dispute is won. A verified provider return does not by itself create a tax record or credit note; receipt-backed return obligations remain pending until an authoritative allocation and document workflow materializes them.

Canonical Tax Records, Reports, And Rebuilds

For supported tax events, the Admin Backend also persists canonical tax records in the tax_records MongoDB collection. These rows are the audit trail behind Tax by country, Revenue by country, and VAT OSS screens: they support drill-down from aggregates to recognized net/tax/gross amounts, buyer/tax country, recognition mode (accrual or cash), and links back to transactions, invoices, credit notes, refunds, or chargebacks.

Report APIs accept an IANA timezone for period boundaries and filenames, and a source filter where relevant (transactions, invoices, or both). VAT OSS endpoints are keyed by calendar year and quarter. File exports are implemented as GET download endpoints: CSV, OSS XML, or Elster CSV for Germany.

Pending versioned repairs execute automatically after an upgrade, including organizations with retained tax records but disabled automatic calculation. The version is completed only after accounting readback verification. Successful work is not repeated on every restart. Related accounting mutations and reports honor an organization maintenance gate while diagnostics remain available.

The tax settings page also exposes Repair reporting records for advanced canonical reporting recovery. This repairs stored evidence without applying today's rules to old accounting documents:

  • issued invoices and issued credit notes are rebuilt from stored document snapshots, persisted line totals, tax treatment, tax-rate codes, recognition dates, and original document links
  • standalone finalized transactions are rebuilt from their stored transaction tax snapshot by default
  • invoice-linked transactions are skipped when the invoice has the authoritative tax record, so mixed transaction/invoice reports do not double-count the same sale
  • materialized refund, credit-note, and chargeback adjustments reduce report totals through negative canonical records instead of mutating the original sale; a pending receipt-return obligation is not yet a report row
  • invoice-linked chargeback credit notes are issued only once the dispute is lost or accepted and the historical allocation is resolved; open and under-review disputes remain payment-risk adjustments, and won disputes do not create credit notes
  • legacy gross-only chargeback allocations are checked against the historical sale basis, even when their stored net plus tax already equals gross
  • a repaired transaction reconciles event allocations, item and tax breakdowns, cached adjustment totals, the live tax snapshot, taxSummary, taxRecordIds, and active canonical adjustment records in one organization-scoped transaction with concurrency checks
  • missing, conflicting, foreign-organization, insufficient, or unrepresentable historical basis is reported as unresolved without changing that transaction; a rebuild with unresolved items is not a fully reconciled result
  • repeating a successful rebuild makes no semantic changes and creates no additional records

For legacy transactions, actual incoming refunds and disputes are still recorded when historical tax basis is unresolved, including their gross amounts and status. Their derived net/tax allocation remains absent, tax snapshots stay unchanged, and tax records or credit notes requiring that allocation are deferred. This is not a zero-tax classification and does not mean reporting is reconciled.

Calculate missing historical tax is a separate, explicit operation. Enabling automatic calculation alone never starts it. An operator previews an inclusive start/exclusive end range and gross/net price treatment, then confirms that exact completed preview. Changed sources or configuration require renewed review. Eligible standalone transactions use their original tax-point date and applicable dated rules/rates; their dependent adjustments are reconciled with the new basis while paid gross is preserved. Existing valid snapshots, including legitimate zero-tax decisions, remain unchanged. Invoice-linked transactions are excluded from new calculation and require the document correction workflow. Issued documents are not rewritten by repair or historical calculation.

An eligible receipt that alone pays its original non-invoice order uses the normal completion tax engine. New receipts freeze the calculation-relevant seller settings at capture, including whether tax was enabled. Later settings changes do not reclassify that sale. Held-receipt release retains the same captured settings. For older receipts without this snapshot, settings must be provably dated no later than capture; missing or ambiguous settings remain explicit review work.

Historical-calculation preview can identify eligible unposted original-sale receipts and confirmation queues their completion tax work. The confirmed job is bound to the previewed evidence and seller settings; changed evidence requires a fresh preview. Queuing work is not proof of posting. Already-posted records and authoritative no-tax outcomes remain unchanged. Partial or multi-receipt sales, duplicate or excess funds, and reassigned supply bases retain their separate receipt-tax review workflow. Issued invoice records remain authoritative for invoice-linked payments. Receipt-backed returns and tax corrections retain the restrictions described in receipt allocation.

Missing tax dates, source evidence or effective configuration remain unresolved rather than guessed. Historical calculation currently supports per-line calculation only. Status survives a page refresh and distinguishes planned, committed, unchanged, excluded, unresolved and unprocessed outcomes. A partially repaired run is not fully consistent reporting.

VAT OSS uses the same active tax records and line-level tax basis as the other reports. Goods and shipping lines resolve destination from shipping country with billing as fallback; digital service, tax, and discount lines resolve destination from billing country. Mixed goods and digital-service documents therefore keep separate line-level countries and rate codes, while document-level country remains summary metadata. EU cross-border B2C goods and services are OSS candidates; non-EU destination lines are treated as exports and stay out of VAT OSS.

Receipt facts, completeness, and historical OSS corrections

Reporting also consumes materialized additional-receipt and signed receipt-correction tax records. These records retain the receipt's frozen seller country, destination, currency, historical rate, receipt tax point, original supply period, and lineage. Reports do not reclassify them from current tax settings. Issued invoice coverage still prevents an invoice-linked sale from being counted twice, but it does not erase independent additional consideration from a separate receipt.

Report totals and receipt-tax completeness are read from one organization-scoped MongoDB snapshot. Draft review remains available when completeness is unavailable, unresolved, malformed, or not snapshot-consistent, but CSV and Union OSS XML/Elster exports fail closed. The reason list is a bounded diagnostic sample; the reported blocker counts cover the complete indexed period scope. A clear standalone check made outside the report snapshot is not a filing-ready cutoff.

Historical Union OSS corrections require two explicit staff actions:

The filed baseline may carry the exact registration identifier as additive schema-2 evidence. New OSS receipt qualification requires that immutable identifier to match the qualified advice. Schema-1 baselines remain readable for existing reporting and correction history and are never rewritten or inferred from mutable organization settings.

  1. Record immutable evidence of the tax amount actually filed for the original member state, quarter, consumption country, and EUR currency. The filing reference, evidence reference, evidence SHA-256, filing time, actor, and recorded time are retained. Missing history is not treated as zero and is not reconstructed from current report totals.
  2. Authorize one frozen signed correction for an explicit supported later quarter with a reason and idempotency key. The audit record preserves the original supply period separately from the receipt tax-point period, receipt and discovery times, prior declared amount, signed delta, corrected declared amount, and remaining delta.

Authorized corrections are projected separately from ordinary sales, refunds, and chargebacks, so a negative correction is not rewritten as a positive value or counted as a sale. Replaying the same authorization returns the same audit record; reusing its key for different facts or selecting an earlier return is rejected. Concurrent authorizations serialize against the filed-history head.

The supported portal outputs are the Union OSS variants only: Elster CSV v2 correction rows and the Austrian Union OSS XML correction structure. They do not submit a return, validate a portal account, supply legal advice, support Non-Union/IOSS correction formats, or prove that a draft has been accepted by a tax authority. Operators must still review the generated file and file it through the relevant authority.

On this page