---
id: CAP-COM-FUL-007
title: Complete the financial work requested by a post-sale document
feature: FEAT-COM-FUL-02
product_area: commerce
module: fulfillment
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes:
  - CAP-COM-REG-020
  - CAP-COM-REG-023
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources: []
purpose: Post-sale financial changes progress through recoverable steps.
outcomes:
  - Document-directed financial settlement avoids duplicate payment execution.
  - Finance can identify and recover a failed financial step.
concepts:
  - CON-COM-FUL-003
actors:
  - ACT-COM-012
  - ACT-COM-008
  - ACT-COM-013
surfaces:
  - job
  - api
  - console
preconditions: []
postconditions: []
permissions:
  - key: commerce.adjustments.read
    where_checked: api
    scope: tenant
  - key: commerce.adjustments.retry
    where_checked: api
    scope: tenant
  - key: commerce.adjustments.resolve
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-COM-FUL-007-01
    statement: >-
      A cancellation, return, amendment or void document has at most one
      financial adjustment, and repeated requests return that adjustment.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#creates
      the adjustment once (the second request answers the first) with its steps
      pending
    origin: none
  - id: BR-CAP-COM-FUL-007-02
    statement: >-
      Adjustment planning fixes the sequence as original-invoice credit memo,
      any fee invoice, freed-money credit and fee application, then refund or
      credit of the remainder; unpaid lines need only a memo and zero fees
      create no fee invoice.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#plans
      the memo, the fee, the credit from the freed money, its application to the
      fee and the refund of the remainder, in that order, each under its key
    origin: none
  - id: BR-CAP-COM-FUL-007-03
    statement: >-
      An amendment applies freed money to its new invoice before crediting any
      remainder.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#applies
      the freed money to an amendment’s new invoice before the remainder (11
      §7.1, P7): a credit and its application by invoice id, then the credit of
      what is left
    origin: none
  - id: BR-CAP-COM-FUL-007-04
    statement: >-
      Each financial step uses its own document-derived key, is marked submitted
      before sending and stores Accounting's reference before advancing, so
      recovery resends an interrupted step under the same key.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
      the step submitted when the command throws, and the resume re-sends the
      same key
    origin: >-
      D-P5-06 (build decision, not a product ruling):
      services-commerce:docs/migrations/operations/README.md#D-P5-06
  - id: BR-CAP-COM-FUL-007-05
    statement: >-
      Permanent refusal fails the adjustment with an exception; retryable
      refusal retains pending work and counts attempts, raising no exception
      until five attempts are exhausted.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
      a retryable refusal pending for the next run, with the attempt counted and
      no exception
    origin: none
  - id: BR-CAP-COM-FUL-007-06
    statement: >-
      A processor-pending refund does not consume failure attempts, completes on
      its refund event and fails with a Finance exception if the processor
      reports failure.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#is
      held pending at the processor, never failed, however many times it is
      asked again, with no exception
    origin: >-
      COMM-M1 R7-2 (repair report, not a product ruling):
      services-commerce:docs/milestones/COMM-M1-repairs-7-report.md#R7-2
  - id: BR-CAP-COM-FUL-007-07
    statement: >-
      The originating document controls when its financial adjustment is
      requested, and the worker moves money only after that request.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/adjustments/adjustment-worker.ts:executeAdjustment
    origin: none
  - id: BR-CAP-COM-FUL-007-08
    statement: >-
      Sensitive retry authority lets staff resume a failed adjustment from its
      failed step with a reason and close its exception on completion; completed
      adjustments reject retry.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#retries
      the failed adjustment on its route: the refund alone re-sent, completed; a
      reader is refused
    origin: none
  - id: BR-CAP-COM-FUL-007-09
    statement: >-
      Staff can resolve an externally settled failed adjustment with a reason
      and resolution, closing its exception and rejecting another resolution.
    kind: lifecycle
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#resolves
      the other failed adjustment offline on its route, with its exception, and
      refuses a repeat
    origin: none
  - id: BR-CAP-COM-FUL-007-10
    statement: >-
      Adjustment lists require an order or state filter, while an individual
      adjustment includes its full step list.
    kind: validation
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#lists
      the order’s adjustments and the failed ones, answers one with its steps,
      and refuses a query naming neither an order nor a state
    origin: none
  - id: BR-CAP-COM-FUL-007-11
    statement: >-
      Accounting commands retain step keys, decimal-text memo quantities and
      immediately issued Commerce fee invoices, classify refusals for retry, and
      leave server errors or missing document identities for recovery.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#answers
      a refusal as failed with Accounting’s code, retryable for the refusals a
      later attempt may change and permanent for a decline
    origin: none
  - id: BR-CAP-COM-FUL-007-12
    statement: >-
      A financial event resumes active adjustments for the affected orders,
      allowing a later refund confirmation to finish the originating document.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: false
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/facts/financial-facts-handler.integration.spec.js#completes
      the adjustment once the refund event is received
    origin: >-
      COMM-M1 R6-2 (repair report, not a product ruling):
      services-commerce:docs/milestones/COMM-M1-repairs-6-report.md#R6-2
scenarios:
  - id: SC-CAP-COM-FUL-007-01
    given: A cancellation fee was processed before its refund was declined.
    when: Retry the failed adjustment as staff.
    then: Only the remaining refund step is resent and the adjustment completes.
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#resumes
      from the failed step alone on the retry: only the refund is sent again,
      and completes
edge_cases:
  - id: SC-CAP-COM-FUL-007-02
    given: The processor says a refund is still pending.
    when: Resume the adjustment repeatedly.
    then: >-
      Processing remains pending without consuming failure attempts or raising
      an exception.
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#is
      held pending at the processor, never failed, however many times it is
      asked again, with no exception
constraints: []
depends_on: []
related:
  - CAP-COM-FUL-008
  - CAP-COM-FUL-009
  - CAP-COM-FUL-015
journeys:
  - JNY-COM-FUL-004
open_questions: []
evidence:
  - repository: services-commerce
    sources:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#creates
        the adjustment once (the second request answers the first) with its
        steps pending
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#plans
        the memo, the fee, the credit from the freed money, its application to
        the fee and the refund of the remainder, in that order, each under its
        key
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#applies
        the freed money to an amendment’s new invoice before the remainder (11
        §7.1, P7): a credit and its application by invoice id, then the credit
        of what is left
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
        the step submitted when the command throws, and the resume re-sends the
        same key
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
        a retryable refusal pending for the next run, with the attempt counted
        and no exception
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#is
        held pending at the processor, never failed, however many times it is
        asked again, with no exception
      - >-
        services-commerce:modules/fulfillment/services/adjustments/adjustment-worker.ts:executeAdjustment
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#retries
        the failed adjustment on its route: the refund alone re-sent, completed;
        a reader is refused
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#resolves
        the other failed adjustment offline on its route, with its exception,
        and refuses a repeat
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#lists
        the order’s adjustments and the failed ones, answers one with its steps,
        and refuses a query naming neither an order nor a state
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#answers
        a refusal as failed with Accounting’s code, retryable for the refusals a
        later attempt may change and permanent for a decline
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/facts/financial-facts-handler.integration.spec.js#completes
        the adjustment once the refund event is received
  - repository: react-console
    sources: []
controls: [TC-IAM-006, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-CRY-001, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-LOG-001, TC-LOG-002, TC-LOG-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-VEN-001, TC-VEN-002, TC-VEN-003, TC-PRV-001, TC-PRV-002]
---

# Complete the financial work requested by a post-sale document

## Purpose

Post-sale financial changes progress through recoverable steps.

## How It Works

A cancellation, return, amendment or void requests its financial work at the appropriate point. Commerce records a plan of Accounting commands for that document. The worker advances through the plan and retains each returned financial reference. Interrupted work resumes from its recorded progress. Processor-pending refunds remain waiting for their later outcome. Staff can retry failed work or record an external settlement through the service. The product should explain which financial step is waiting and who can resolve it.

## Relationships

- Review and resolve operations findings supplies or consumes related delivery records.
- Detect stalled and inconsistent order work supplies or consumes related delivery records.
- Process returned goods through inspection and disposition supplies or consumes related delivery records.
