---
id: WF-COM-FUL-014
title: 'Receive, inspect and disposition returned goods'
trigger: 'An authorized return reaches label creation, receiving or disposition.'
product_area: commerce
module: fulfillment
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
implements:
  - CAP-COM-FUL-015
moves:
  - STATE-COM-FUL-008
  - STATE-COM-FUL-005
crosses:
  - SVC-COM-FUL-shipping
  - SVC-COM-FUL-inventory
  - SVC-COM-FUL-fulfillment
idempotency: >-
  Receipt replay returns the recorded receipt without repeating receiving.
  Terminal disposition refuses repetition, and disposition movements use stable
  keys.
concurrency: >-
  Receipt and disposition operations lock their receiving record and retain
  return quantities together. Financial continuation begins after those local
  commits.
hops:
  - 'n': 1
    actor_or_service: Returns port (Orders' return issued)
    action: >-
      Create a packed return-label shipment towards the return warehouse and
      obtain its label through the carrier workflow.
    anchor: >-
      services-commerce:modules/shipping/services/returns/return-label.ts:createReturnLabelShipment
    seam: sync
    on_failure: >-
      Use label uncertainty handling; no shipped source units can prevent label
      creation.
    left_inconsistent: A label attempt can remain uncertain.
    observer: Return document and shipment history.
    provenance: observed
    source: 'services-commerce:modules/shipping/services/returns/return-label.ts'
  - 'n': 2
    actor_or_service: Shipping API (receive)
    action: >-
      Record keyed receiving within remaining authorization and advance return
      quantities without stock movement.
    anchor: >-
      services-commerce:modules/shipping/services/returns/return-receiving.ts:receiveReturn
    seam: sync
    on_failure: Reject excess quantity or a terminal return.
    left_inconsistent: A refused receipt retains no additional received units.
    observer: Return receiving record.
    provenance: observed
    source: 'services-commerce:modules/shipping/services/returns/return-receiving.ts'
  - 'n': 3
    actor_or_service: Return document (after commit)
    action: >-
      After receipt commit, request money when refund-on-receipt policy and
      complete receiving permit it.
    anchor: >-
      services-commerce:modules/orders/services/returns/return-workflow.ts:followReturnReceipt
    seam: sync
    on_failure: >-
      Return the error even though receiving stands; receipt replay does not run
      this continuation.
    left_inconsistent: >-
      Goods are recorded received while money work may never have been
      requested.
    observer: Request error and absent money continuation.
    provenance: inferred
    source: >-
      services-commerce:modules/shipping/services/returns/return-receiving.ts:receiveReturn
      (followReturnReceipt after the transaction; the replay path returns before
      it)
  - 'n': 4
    actor_or_service: Shipping API (inspect)
    action: >-
      Retain line condition and discrepancy, moving the receipt to inspected
      after all lines are inspected.
    anchor: >-
      services-commerce:modules/shipping/services/returns/return-receiving.ts:inspectReturnReceipt
    seam: sync
    on_failure: Refuse a terminal dispositioned receipt.
    left_inconsistent: Receiving already recorded remains unchanged.
    observer: Receipt inspection state.
    provenance: observed
    source: 'services-commerce:modules/shipping/services/returns/return-receiving.ts'
  - 'n': 5
    actor_or_service: 'Shipping API (disposition, one transaction)'
    action: >-
      Apply allowed disposition quantities: restock with original cost,
      quarantine without cost restoration, no ledger effect for scrap or
      customer return, or restock elsewhere for transfer.
    anchor: >-
      services-commerce:modules/shipping/services/returns/return-receiving.ts:dispositionReturnReceipt
    seam: sync
    on_failure: >-
      Rollback the disposition transaction when quantity, policy or unsupported
      replacement checks refuse it.
    left_inconsistent: A failed disposition retains no new stock movement.
    observer: Movements and cost restoration.
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#restocks
      the two units at the bin they shipped from: the return_restock movement
      naming the disposition, on hand up two, the two reliefs reversed at 1500
      with the restore_cogs fact of 3000
  - 'n': 6
    actor_or_service: Return document (after commit)
    action: >-
      After physical disposition, run the return adjustment and finish the
      document when money permits.
    anchor: >-
      services-commerce:modules/orders/services/returns/return-workflow.ts:followReturnReceipt
    seam: sync
    on_failure: >-
      Return failure after commit; terminal disposition refuses replay and the
      reconciler has no active returns continuation.
    left_inconsistent: Goods can be dispositioned without credit or refund completion.
    observer: Return financial status and request error.
    provenance: inferred
    source: >-
      services-commerce:modules/orders/services/returns/return-workflow.ts:followReturnReceipt;
      modules/operations/services/reconciler/reconciler.ts (returns_overdue
      skipped)
branches:
  - >-
    Withdrawal before anything arrives cancels the return label shipment and
    voids its label.
  - >-
    A label the customer pays for has its cost deducted from the refund by the
    return workflow.
waits:
  - The customer's parcel arriving.
evidence:
  - >-
    services-commerce at c8b66a98: modules/shipping/services/returns/*.ts;
    services/persistence/return-receipts.ts;
    modules/orders/services/returns/return-workflow.ts;
    modules/purchasing/services/cost (restore).
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-CRY-001, TC-DAT-001, TC-DAT-002, TC-DAT-003, 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]
---

# Receive, Inspect and Disposition Returned Goods

## What It Does

Returns can obtain an incoming label, then record receiving, inspection and disposition. Receiving changes authorized quantities without moving stock. Disposition chooses the allowed physical result and writes the corresponding stock and cost effects before financial continuation.

## The Flow

```mermaid
sequenceDiagram
  participant O as Orders return
  participant H as Shipping API
  participant I as Stock ledger
  participant C as Cost
  participant M as Money step
  O->>H: issue return label shipment
  H->>H: receive (once, by key)
  H->>M: on receipt policy: request money
  H->>H: inspect
  H->>I: disposition: restock or quarantine movements
  H->>C: restore original cost
  H->>M: after commit: credit memo, refund, complete
```

## When Something Fails

Receipt replay returns the stored result without retrying failed money work. Disposition replay is refused after completion, and the returns reconciler check is skipped. Goods can therefore be received or dispositioned without the expected credit or refund.
