---
id: CAP-COM-ORD-006
title: Invoice a sale through Accounting
feature: FEAT-COM-ORD-02
product_area: commerce
module: orders
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - CAP-COM-BIL-001
  - CAP-COM-BIL-004
  - CAP-COM-BIL-005
  - CAP-COM-BIL-011
  - CAP-COM-BIL-022
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#A1'
  - 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#D6'
  - 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#D9'
  - 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#D11'
  - 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#D12'
  - 'services-commerce:docs/milestones/plans/COMM-M1-plan.md#A20'
purpose: The sale reaches Accounting with amounts and explanations that can support payment and later corrections.
outcomes:
  - Pay-now billing begins with a pro forma and terms billing begins with a real invoice.
  - Invoice amounts reconcile with the order and explain their discounts.
concepts:
  - CON-COM-ORD-002
actors:
  - ACT-COM-014
  - ACT-COM-018
surfaces:
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: commerce.orders.create
    where_checked: api
    scope: tenant
  - key: commerce.orders.tender
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-COM-ORD-006-01
    proved_by: [ATS-COM-ORD-001-20, ATS-COM-ORD-005-17, ATS-COM-ORD-005-19, ATS-COM-ORD-006-01, ATS-COM-ORD-006-16, ATS-COM-ORD-007-19, ATS-COM-ORD-008-12, ATS-COM-ORD-010-12, ATS-COM-ORD-015-15, TST-COM-ORD-075]
    statement: >-
      Commerce saves the order before requesting its issued Accounting invoice, using a stable billing key for
      retries, with a pro forma for pay-now sales and a real invoice for terms sales.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    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
    origin: 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#A1'
  - id: BR-CAP-COM-ORD-006-02
    proved_by: [ATS-COM-ORD-006-02, ATS-COM-ORD-006-13, TST-COM-ORD-128]
    statement: An invoice that remains draft after an issue request blocks payment on the order.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/unit/billing/issue-before-tender.spec.js#answers an issue
      Accounting answers still a draft as a refusal, invoice_not_issued, so the order is blocked and not
      tendered
    origin: none
  - id: BR-CAP-COM-ORD-006-03
    proved_by: [ATS-COM-ORD-006-03, TST-COM-ORD-075, TST-COM-ORD-095]
    statement: >-
      Unanswered billing remains pending for a same-key sweep retry, and an order unbilled for more than an
      hour raises an operational exception without charging a payment.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/integration/services/orders/financial-sweeps.integration.spec.js#escalates
      an order placed over an hour ago whose billing gets no answer, placed_without_invoice, and counts the
      attempt
    origin: 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#A1'
  - id: BR-CAP-COM-ORD-006-04
    proved_by: [ATS-COM-ORD-006-04, TST-COM-ORD-126]
    statement: >-
      Unbuildable or configuration-refused invoices block billing and raise an exception, with the sweep able
      to retry after staff correct the configuration.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/unit/billing/invoice-request.spec.js#refuses an order discount
      its lines do not carry, 409 unallocated_order_discount, with both figures
    origin: none
  - id: BR-CAP-COM-ORD-006-05
    proved_by: [ATS-COM-ORD-006-05, TST-COM-ORD-126]
    statement: >-
      Invoice discount explanations list promotion display names in application order followed by any
      order-discount share, omit internal codes and mark truncated long explanations.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/unit/billing/invoice-request.spec.js#joins the promotions' names
      in sequence order, then the order-discount share
    origin: 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#D12'
  - id: BR-CAP-COM-ORD-006-06
    proved_by: [ATS-COM-ORD-006-06, ATS-COM-ORD-006-15, TST-COM-ORD-080, TST-COM-ORD-126]
    statement: >-
      An order discount is allocated proportionally across item prices without negative lines, with tax on
      each net amount so a later line credit uses that line’s discounted value and tax.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/order-discount-tax.e2e.spec.js#shares the $30.00 over the
      lines as $17.14, $8.57 and $4.29, the nets $82.86, $41.43 and $20.71
    origin: 'services-commerce:docs/milestones/plans/COMM-M1-plan.md#A20'
    examples:
      positive: >-
        A thirty-dollar discount over values of one hundred, fifty and twenty-five dollars allocates seventeen
        dollars fourteen cents, eight dollars fifty-seven cents and four dollars twenty-nine cents.
      negative: Billing does not represent the discount as a negative item line.
  - id: BR-CAP-COM-ORD-006-07
    proved_by: [ATS-COM-ORD-006-07, TST-COM-ORD-073, TST-COM-ORD-077]
    statement: >-
      Application and product-price adjustments become the invoiced unit price, rounded half away from zero
      and explained by a rounding adjustment when needed, preserving quantity, price and discount arithmetic.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/application-adjustments.e2e.spec.js#rounds the unit price
      half away from zero to $96.67 and keeps the line at $290.01
    origin: 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#D11'
  - id: BR-CAP-COM-ORD-006-08
    proved_by: [ATS-COM-ORD-006-08, TST-COM-ORD-019]
    statement: >-
      Billing requires invoice and order totals to reconcile to the minor unit; a changed Accounting tax
      amount updates the order once and refuses the first payment attempt with both amounts.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/accounting-tax.e2e.spec.js#refuses the first tender 409
      invoice_tax_mismatch, naming both figures, the new total and the shipped line as the cause
    origin: none
  - id: BR-CAP-COM-ORD-006-09
    proved_by: [ATS-COM-ORD-006-09, TST-COM-ORD-145]
    statement: >-
      Billing accepts terms orders, orders requiring no payment and zero-total pay-now orders; other pay-now
      and deposit orders still require payment.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/unit/tender/tender-rules.spec.js#accepts a terms order, a
      no-tender order and a zero-total pay-now order; a pay-now and a deposit order wait for their tender
    origin: 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#A1'
  - id: BR-CAP-COM-ORD-006-10
    proved_by: [ATS-COM-ORD-006-10, TST-COM-ORD-075]
    statement: >-
      Console orders accepted on terms can open the default paid-in-full delivery condition before payment,
      while an explicit pay-first product policy and portal terms orders continue to wait.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#opens the gate of the console
      order when it is billed: the invoice is unpaid and the line is no longer waiting
    origin: 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#D6'
  - id: BR-CAP-COM-ORD-006-11
    proved_by: [ATS-COM-ORD-006-11, ATS-COM-ORD-006-14, TST-COM-ORD-104]
    statement: Billing attaches each Accounting invoice-line reference to its order line for later money reads.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/integration/services/persistence/orders.queries.integration.spec.js#answers
      the line whole with its purchase, the invoice line id billing wrote, and the provenance of its price
    origin: none
  - id: BR-CAP-COM-ORD-006-12
    proved_by: [ATS-COM-ORD-006-12, TST-COM-ORD-077]
    statement: >-
      The order fee becomes an undiscounted invoice line on its configured fee product using the pricing
      description.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/extension-line-adjustments.e2e.spec.js#requests the invoice
      with the fee as a line of the product, undiscounted
    origin: 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#D9'
scenarios:
  - id: SC-CAP-COM-ORD-006-01
    given: The documented pay-now example totals two hundred thirteen dollars.
    when: Staff place it for billing.
    then: Accounting receives an issued pro forma for that amount while the order still awaits payment.
    provenance: documented
    source: 'services-commerce:docs/milestones/plans/COMM-M2-plan.md#3. How it works for the user'
edge_cases:
  - id: SC-CAP-COM-ORD-006-02
    given: Billing cannot find an open batch for the applicable policy.
    when: 'Attempt billing, configure the batch and allow retry processing.'
    then: Billing first blocks with an exception and later proceeds when the missing configuration is available.
    provenance: unknown
    source: FND-COM-ORD-032
constraints: []
depends_on:
  - CAP-COM-ORD-005
related:
  - CAP-COM-ORD-007
  - CAP-COM-ORD-010
  - CAP-COM-ORD-014
journeys:
  - JNY-COM-ORD-001
  - JNY-COM-ORD-002
open_questions: []
evidence:
  - 'Examined reference: services-commerce:docs/milestones/plans/COMM-M1-plan.md#A20'
  - 'Examined reference: services-commerce:docs/milestones/plans/COMM-M2-plan.md#3. How it works for the user'
  - 'Examined reference: services-commerce:docs/milestones/plans/COMM-M2-plan.md#A1'
  - 'Examined reference: services-commerce:docs/milestones/plans/COMM-M2-plan.md#D11'
  - 'Examined reference: services-commerce:docs/milestones/plans/COMM-M2-plan.md#D12'
  - 'Examined reference: services-commerce:docs/milestones/plans/COMM-M2-plan.md#D6'
  - 'Examined reference: services-commerce:docs/milestones/plans/COMM-M2-plan.md#D9'
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/accounting-tax.e2e.spec.js#refuses the
    first tender 409 invoice_tax_mismatch, naming both figures, the new total and the shipped line as the
    cause
  - >-
    Examined reference: services-commerce:modules/orders/tests/e2e/application-adjustments.e2e.spec.js#rounds
    the unit price half away from zero to $96.67 and keeps the line at $290.01
  - >-
    Examined reference: 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
  - >-
    Examined reference: services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#opens the
    gate of the console order when it is billed: the invoice is unpaid and the line is no longer waiting
  - >-
    Examined reference:
    services-commerce:modules/orders/tests/e2e/extension-line-adjustments.e2e.spec.js#requests the invoice
    with the fee as a line of the product, undiscounted
  - >-
    Examined reference: services-commerce:modules/orders/tests/e2e/order-discount-tax.e2e.spec.js#shares the
    $30.00 over the lines as $17.14, $8.57 and $4.29, the nets $82.86, $41.43 and $20.71
  - >-
    Examined reference:
    services-commerce:modules/orders/tests/integration/services/orders/financial-sweeps.integration.spec.js#escalates
    an order placed over an hour ago whose billing gets no answer, placed_without_invoice, and counts the
    attempt
  - >-
    Examined reference:
    services-commerce:modules/orders/tests/integration/services/persistence/orders.queries.integration.spec.js#answers
    the line whole with its purchase, the invoice line id billing wrote, and the provenance of its price
  - >-
    Examined reference: services-commerce:modules/orders/tests/unit/billing/invoice-request.spec.js#joins the
    promotions' names in sequence order, then the order-discount share
  - >-
    Examined reference: services-commerce:modules/orders/tests/unit/billing/invoice-request.spec.js#refuses an
    order discount its lines do not carry, 409 unallocated_order_discount, with both figures
  - >-
    Examined reference:
    services-commerce:modules/orders/tests/unit/billing/issue-before-tender.spec.js#answers an issue
    Accounting answers still a draft as a refusal, invoice_not_issued, so the order is blocked and not
    tendered
  - >-
    Examined reference: services-commerce:modules/orders/tests/unit/tender/tender-rules.spec.js#accepts a
    terms order, a no-tender order and a zero-total pay-now order; a pay-now and a deposit order wait for
    their tender
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]
exercised_by: [FAS-COM-ORD-02-01, FAS-COM-ORD-02-02, FAS-COM-ORD-02-03, FAS-COM-ORD-02-05, FAS-COM-ORD-06-03]
suites: [TST-COM-ORD-019, TST-COM-ORD-073, TST-COM-ORD-075, TST-COM-ORD-077, TST-COM-ORD-080, TST-COM-ORD-095, TST-COM-ORD-104, TST-COM-ORD-126, TST-COM-ORD-128, TST-COM-ORD-145]
---

# Invoice a sale through Accounting

## Purpose

The sale reaches Accounting with amounts and explanations that can support payment and later corrections. Billing progress remains visible when an external answer is delayed.

## How It Works

After placement, Commerce prepares the invoice request for Accounting. The request carries item prices, discount explanations and separately billable charges. Commerce issues the invoice before allowing a payment to proceed. An unavailable response leaves billing work to retry, while a configuration refusal needs correction. Staff can distinguish pending billing from blocked billing on the order. Completed billing links the Accounting records that later financial work reads.

## Relationships

Placement supplies the frozen sale, payment relies on an issued invoice, and order inspection exposes Accounting links and financial progress.
