---
id: WF-COM-ORD-003
title: Bill an order through Accounting
trigger: 'Placement follow-up, eligible billing retry or a payment requiring an invoice starts billing.'
product_area: commerce
module: orders
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
implements:
  - CAP-COM-ORD-006
  - CAP-COM-ORD-005
  - CAP-COM-ORD-007
moves:
  - STATE-COM-ORD-005
  - STATE-COM-ORD-004
crosses:
  - SVC-COM-ORD-orders
  - SVC-ACC-TRX-transactions
idempotency: >-
  Sale invoice creation and provisional issue retain stable order-derived keys. Repeated remote requests and
  unique invoice links resolve to the same invoice.
concurrency: >-
  Independent billing callers can request the same remote invoice; stable keys and unique links converge their
  responses in short recording transactions.
hops:
  - 'n': 1
    actor_or_service: Billing
    action: >-
      Construct invoice lines from gross item prices, discounts and their shares, configured charge products
      and the policy's provisional, batch or deposit treatment.
    anchor: 'services-commerce:modules/orders/services/billing/invoice-request.ts'
    seam: sync
    on_failure: Unbuildable invoice configuration blocks billing and creates an exception.
    left_inconsistent: Accounting has received no invoice request.
    observer: 'Observed through observed through staff, through the billing-blocked exception.'
    provenance: test
    source: 'services-commerce:modules/orders/tests/e2e/order-discount-tax.e2e.spec.js'
  - 'n': 2
    actor_or_service: Accounting
    action: 'Request invoice creation, and real-invoice issue, using the sale billing key.'
    anchor: 'services-commerce:modules/orders/services/billing/billing-port.ts:createInvoice'
    seam: sync
    on_failure: Configuration refusal records blocked; unanswered requests retain pending and attempt information.
    left_inconsistent: Accounting may already hold an invoice whose response Commerce lost.
    observer: >-
      Observed through observed through billing state on the order; billing-blocked and placed-without-invoice
      exceptions.
    provenance: observed
    source: 'services-commerce:modules/orders/services/billing/bill-order.ts:billOrder'
  - 'n': 3
    actor_or_service: Billing
    action: >-
      Check invoice totals, reconcile Accounting tax when applicable, link invoice and line identities, mark
      billed and ensure provisional issue before payment.
    anchor: 'services-commerce:modules/orders/services/billing/bill-order.ts:billOrder'
    seam: sync
    on_failure: Total disagreement blocks processing; failed provisional issue can be retried by the payment path.
    left_inconsistent: A linked provisional invoice may remain unissued.
    observer: 'Observed through sale history (billed, repriced to invoice).'
    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
  - 'n': 4
    actor_or_service: Acceptance
    action: 'Accept terms, no-payment and zero-total purchases, including the console terms delivery-gate treatment.'
    anchor: 'services-commerce:modules/orders/services/orders/accept-order.ts:acceptOrder'
    seam: sync
    on_failure: Gate or mirror follow-up failures are logged while acceptance remains committed.
    left_inconsistent: Delivery evaluation and financial projection can lag acceptance.
    observer: Observed through the sale detail screen; function logs.
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#bills a real invoice at
      placement and accepts the order on terms, the obligation waiting on the invoice
  - 'n': 5
    actor_or_service: Billing sweep
    action: >-
      Retry eligible pending or blocked billing under the same key after ten minutes, escalating missing
      invoices after an hour.
    anchor: 'services-commerce:modules/orders/services/orders/financial-sweeps.ts:sweepBilling'
    seam: schedule
    on_failure: Per-order failures are logged and processing continues; an unconfigured transport skips the pass.
    left_inconsistent: Unreachable or unconfigured Accounting leaves orders awaiting billing.
    observer: Observed through observed through operational exceptions; sweep results in the function log.
    provenance: observed
    source: 'services-commerce:modules/orders/services/orders/financial-sweeps.ts:sweepBilling'
branches:
  - 'Subsequent fees, installments and changes advance the billing-key sequence.'
waits:
  - Configuration correction allows a later pass to recover a blocked sale.
evidence:
  - >-
    services-commerce at c8b66a98: modules/orders/services/billing/*.ts; services/orders/accept-order.ts,
    financial-sweeps.ts; services/accounting/commerce-accounting-client.ts;
    tests/e2e/billing-and-tender.e2e.spec.js, order-discount-tax.e2e.spec.js,
    application-adjustments.e2e.spec.js.
controls: [TC-IAM-006, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-CRY-001, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-004, TC-LOG-005, TC-AVL-004, TC-MON-001, TC-MON-002, TC-MON-004, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002]
---

# Bill an order through Accounting

## What It Does

Billing establishes the sale receivable in Accounting and records invoice and line links. It can also accept purchases whose terms require no immediate payment.

## The Flow

```mermaid
sequenceDiagram
  participant O as Orders
  participant X as Accounting
  participant S as Billing sweep
  O->>X: create invoice (billing key)
  alt answered
    X-->>O: invoice
    O->>O: check totals, link invoice and lines, billed
    O->>O: accept if terms or nothing to pay
  else refused
    O->>O: blocked, exception for staff
  else no answer
    O->>O: still pending
    S->>X: retry under the same key (every ten minutes)
  end
```

## When Something Fails

Stable keys recover invoices even after the creation response is lost. Configuration refusal creates blocked processing and an exception; retry can heal it after correction. Missing billing escalates after an hour. An unconfigured transport skips attempts without that recovery signal.

## Open Design Questions

Shared scheduling permits earlier pass failures to delay invoice recovery.
