---
id: STATE-COM-ORD-005
title: Order billing
object: DOM-COM-ORD-002
product_area: commerce
module: orders
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
states:
  - name: pending
    meaning: The order has no confirmed invoice link and cannot yet be charged.
  - name: billed
    meaning: The sale invoice and its lines have been linked from Accounting's answer.
  - name: blocked
    meaning: Invoice configuration or an invariant prevents billing and requires correction.
transitions:
  - from: pending
    to: billed
    trigger: 'Placement follow-up, recovery or tender obtains the invoice answer.'
    guard: 'Invoice amounts satisfy the expected minor-unit total, accounting for the tax provider.'
    side_effects:
      - persist invoice and purchased-line financial associations
      - ensure provisional issue before charging
      - accept purchases whose policy needs no immediate money
      - append sale-billing history
    who: 'System (placement, sweep or payment attempt)'
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#billed the order at placement:
      billed, placed, one pro forma sale invoice linked under the first bill key, the line carrying its
      invoice line
  - from: pending
    to: blocked
    trigger: 'Invoice construction, configuration or total checks prevent billing.'
    guard: No additional precondition applies to recording the block.
    side_effects:
      - increment recorded billing attempts
      - create an operational billing-configuration exception
    who: System
    provenance: observed
    source: 'services-commerce:modules/orders/services/billing/bill-order.ts:billOrder'
  - from: blocked
    to: billed
    trigger: Recovery obtains billing after configuration is corrected.
    guard: The retry uses the original key after the ten-minute interval.
    side_effects:
      - perform the common invoice-linking outcome
    who: System (billing sweep)
    provenance: observed
    source: 'services-commerce:modules/orders/services/orders/financial-sweeps.ts:sweepBilling'
  - from: pending
    to: pending
    trigger: The financial call has no answer or usable transport.
    guard: The unanswered outcome retains pending billing.
    side_effects:
      - record the attempt and escalate hour-old missing billing when transport is configured
    who: System
    provenance: observed
    source: 'services-commerce:modules/orders/services/orders/financial-sweeps.ts:sweepBilling'
invalid:
  - from: billed
    to: pending
    why: Sale billing is retained; additional charge documents create separate invoice links.
concurrency: >-
  Accounting keys make repeated requests refer to the same invoice. Billing retries become eligible after ten
  minutes and unresolved billing escalates after an hour. An unconfigured transport makes no attempt.
invariants:
  - INV-DOM-COM-ORD-002-08
evidence:
  - >-
    services-commerce at c8b66a98: modules/orders/db/orders.table.ts (BILLING_STATES);
    services/billing/bill-order.ts, billing-port.ts, billing-request.ts; services/orders/financial-sweeps.ts.
---

# Order billing

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> pending: placed
  pending --> billed: invoice answered
  pending --> blocked: refused or unbuildable
  pending --> pending: no answer, retried
  blocked --> billed: retried after a fix
```

## Transitions Explained

After placement, Commerce requests the sale invoice using a stable key. A valid response supplies invoice and line links; configuration refusal records blocked, while an unanswered request remains pending. Terms use a real invoice and pay-now purchases use a provisional one.

## What Cannot Happen

A payment attempt ensures billing first and stops if the invoice is still unavailable. Later fee and installment invoices add links rather than restarting sale billing.

## Concurrency and Timing

Accounting keys make repeated requests refer to the same invoice. Billing retries become eligible after ten minutes and unresolved billing escalates after an hour. An unconfigured transport makes no attempt.
