---
id: WF-ACC-TRX-005
title: Record money received by hand and place it on invoices
trigger: >-
  Staff or coordinated settlement and remittance commands record offline
  receipts and place their money.
product_area: accounting
module: transactions
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-ACC-TRX-006
  - CAP-ACC-TRX-008
moves:
  - STATE-ACC-TRX-006
  - STATE-ACC-TRX-001
crosses:
  - SVC-ACC-TRX-transactions
hops:
  - 'n': 1
    actor_or_service: Payment receive
    action: >-
      Resolve the current configured method or accepted legacy alias, check
      channel and reference eligibility, and preserve its behavior.
    anchor: >-
      services-accounting:modules/transactions/services/payments/payment-receive.ts:receivePayment
    seam: sync
    on_failure: Reject eligibility before persisting the command.
    left_inconsistent: The complete transaction is undone.
    observer: The API response reports the outcome and applicable refusal code.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/payments/payment-method-rules.ts:missingReferenceRefusal
  - 'n': 2
    actor_or_service: Payment receive
    action: >-
      Validate receipt value, currency, bank destination, batch and open period
      before assigning its number.
    anchor: >-
      services-accounting:modules/transactions/services/payments/payment-receive.ts:receivePayment
    seam: sync
    on_failure: Reject the command and undo its transaction.
    left_inconsistent: The complete transaction is undone.
    observer: The API response reports the outcome and applicable refusal code.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/payments/payment-receive.ts:receivePayment;
      services-accounting:modules/transactions/tests/integration/services/payments/receive-offline.integration.spec.js#it
      refuses a payment naming no batch in a unit with no batch assignment rule
      (batch_required), writing nothing
  - 'n': 3
    actor_or_service: Allocation plan
    action: >-
      Resolve eligible customer lines and convert any targeted quotation in the
      receipt batch before allocation.
    anchor: 'services-accounting:modules/transactions/services/allocation-plan.ts'
    seam: sync
    on_failure: Reject excess allocation or a target belonging to another customer.
    left_inconsistent: The complete transaction is undone.
    observer: The API response reports the outcome and applicable refusal code.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/allocation-plan.ts;
      services-accounting:modules/transactions/tests/integration/services/payments/receive-offline.integration.spec.js#it
      converts an unconverted pro forma the first payment names, in the
      payment’s batch, and pays it (Commerce’s first payment makes it real)
  - 'n': 4
    actor_or_service: Allocation ledger trigger
    action: >-
      Insert bounded allocation entries together and append their dated
      financial facts.
    anchor: >-
      services-accounting:modules/transactions/services/payments/payment-allocate.ts:allocatePayment
    seam: sync
    on_failure: >-
      The database rejects the competing allocation when available value is
      insufficient.
    left_inconsistent: The complete transaction is undone.
    observer: The API response reports the outcome and applicable refusal code.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/payments/payment-allocate.ts:allocatePayment;
      services-accounting:modules/transactions/tests/integration/services/payments/allocate.integration.spec.js#it
      serialize, and the second is refused by the database’s balance CHECK, not
      by code
  - 'n': 5
    actor_or_service: Reallocation
    action: >-
      Move selected receipt money by inserting opposite original allocations and
      new target allocations atomically.
    anchor: >-
      services-accounting:modules/transactions/services/payments/payment-allocate.ts:reallocatePayment
    seam: sync
    on_failure: Reject an allocation that has already been negated and undo the move.
    left_inconsistent: The complete transaction is undone.
    observer: The API response reports the outcome and applicable refusal code.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/payments/payment-allocate.ts:reallocatePayment;
      services-accounting:modules/transactions/tests/integration/services/payments/allocate.integration.spec.js#it
      writes a reversing row for the 5000 and a new row for the 4000, the
      original marked reversed in full
idempotency: >-
  Direct receipt and allocation commands use request keys; parent operations
  supply derived keys for their component receipts.
concurrency: >-
  Database financial bounds and ordered locking prevent competing placements
  from overspending the receipt.
branches:
  - >-
    Unplaced money remains on the receipt and contributes to the customer
    financial position.
waits: []
evidence:
  - >-
    services-accounting at f47cb263: services/payments/payment-receive.ts,
    payment-allocate.ts, payment-method-rules.ts, allocation-plan.ts.
controls: [TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, 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-CRY-001, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PRV-001, TC-PRV-002]
---
# Record money received by hand and place it on invoices

## What It Does

Offline collection records money already received. Allocation is separate from collection, allowing later placement and correction without replacing the receipt.

## The Flow

```mermaid
flowchart TD
  h0["Payment receive"]
  h1["Payment receive"]
  h0 --> h1
  h2["Allocation plan"]
  h1 --> h2
  h3["Allocation ledger trigger"]
  h2 --> h3
  h4["Reallocation"]
  h3 --> h4
```

The numbered hops identify the participating services, synchronization boundary and evidence. Branch conditions in the frontmatter explain where preparation, completion and recovery diverge.

## When Something Fails

Each hop records its rollback, retry or compensation boundary and the result visible to callers or operators. External outcomes can remain unresolved after local preparation commits; the listed recovery behavior defines what remains pending.

## Open Design Questions

The unresolved matters are recorded in the module findings; this workflow does not establish additional product approval.
