---
id: CAP-ACC-TRX-012
title: Return customer money with accountable refunds
feature: FEAT-ACC-TRX-04
product_area: accounting
module: transactions
revision: 1
status: draft
product_intent: proposed
implementation_evidence: partially-observed
supersedes:
  - CAP-ACC-PAY-015
  - CAP-ACC-PAY-016
  - CAP-ACC-PAY-027
  - CAP-ACC-PAY-029
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-accounting:docs/milestones/plans/ACCT-M2-plan.md#D6'
  - 'services-accounting:docs/milestones/plans/ACCT-M2-plan.md#D7'
  - 'services-accounting:docs/milestones/plans/ACCT-M2-plan.md#D8'
  - 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#M2-5'
  - 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#A-5'
purpose: 'Staff return eligible value while keeping its source, approval and outcome inspectable.'
outcomes:
  - 'Staff return eligible value while keeping its source, approval and outcome inspectable.'
  - >-
    Failed refunds restore the local position and uncertain ones continue holding money. Returning applied
    value either credits the original charge or reopens its debt according to the chosen treatment.
concepts:
  - CON-ACC-TRX-003
  - CON-ACC-TRX-004
actors:
  - ACT-ACC-012
  - ACT-ACC-020
  - ACT-ACC-021
  - ACT-ACC-022
  - ACT-ACC-024
surfaces:
  - console
  - api
  - job
permissions:
  - key: accounting.refunds.create
    where_checked: api
    scope: tenant
  - key: accounting.refunds.read
    where_checked: api
    scope: tenant
  - key: accounting.refunds.approve
    where_checked: api
    scope: tenant
  - key: accounting.refunds.execute
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-ACC-TRX-012-01
    proved_by: [ATS-ACC-TRX-011-10, ATS-ACC-TRX-012-01, TST-ACC-TRX-109]
    statement: >-
      Refund requests identify positive refundable value and cannot exceed available unapplied money,
      remaining application value or credit balance.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refunds.integration.spec.js#it
      refuses more than an allocation holds (over_refund) and more than the unapplied money (over_refund)
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-02
    proved_by: [ATS-ACC-TRX-011-10, ATS-ACC-TRX-012-02, ATS-ACC-TRX-012-12, TST-ACC-TRX-107]
    statement: >-
      A request reserves its unapplied source money until success, cancellation or failure, preventing
      concurrent application, credit creation or another refund from using it.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refund-reservation.integration.spec.js#it
      refuses allocating the reserved money (over_application) but allocates money beyond it
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-03
    proved_by: [ATS-ACC-TRX-003-12, ATS-ACC-TRX-012-03, ATS-ACC-TRX-013-10, ATS-ACC-TRX-014-09, TST-ACC-TRX-105]
    statement: >-
      Processor money returns through its original merchant account unless the source lacks a processor
      reference or a processor refund has already been declined.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refund-card-original-method.integration.spec.js#it
      refuses a check refund of the card’s unapplied money, saying the money goes back to the card
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-04
    proved_by: [ATS-ACC-TRX-012-04, TST-ACC-TRX-109, TST-ACC-TRX-249]
    statement: >-
      Refunding an application removes its paid value; a default credit memo preserves settlement, while an
      explicit reopen choice restores the debt.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refunds.integration.spec.js#it
      keeps the invoice settled for the credited 2000 (a credit memo line) and reopens the 1000: the line owes
      1000
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#M2-5'
  - id: BR-CAP-ACC-TRX-012-05
    proved_by: [ATS-ACC-TRX-012-05, TST-ACC-TRX-109, TST-ACC-TRX-250]
    statement: 'Where workspace approval is enabled, requests wait and only a different person can approve them.'
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refunds.integration.spec.js#it
      requests it pending_approval, refusing to execute it (refund_not_requested) or to let the requester
      approve it (self_approval)
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-06
    proved_by: [ATS-ACC-TRX-012-06, TST-ACC-TRX-109]
    statement: >-
      Execution requires requested status, cancellation requires an unpaid refund and a reason, and paid or
      cancelled refunds are final.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refunds.integration.spec.js#it
      refuses executing it again (refund_not_requested) and cancelling it (refund_not_cancellable)
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-07
    proved_by: [ATS-ACC-TRX-012-07, TST-ACC-TRX-109, TST-ACC-TRX-248]
    statement: >-
      Offline execution moves money immediately and derives partially refunded or refunded payment status from
      the accumulated amount.
    kind: calculation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refunds.integration.spec.js#it
      records it offline: executed, the payment partially_refunded with 1000 refunded (FC-11, FC-14)
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-08
    proved_by: [ATS-ACC-TRX-007-12, ATS-ACC-TRX-012-08, ATS-ACC-TRX-012-12, ATS-ACC-TRX-020-09, TST-ACC-TRX-108, TST-ACC-TRX-109, TST-ACC-TRX-251]
    statement: >-
      Processor refunds are recorded before the external call; definite rejection or nonreceipt fails the
      refund and restores applications and reservations.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refunds.integration.spec.js#it
      leaves the payment as it was: nothing unapplied, refunded or pending, its facts unchanged
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-09
    proved_by: [ATS-ACC-TRX-007-12, ATS-ACC-TRX-009-12, ATS-ACC-TRX-012-09, ATS-ACC-TRX-012-12, ATS-ACC-TRX-013-10, ATS-ACC-TRX-014-09, ATS-ACC-TRX-020-09, TST-ACC-TRX-042, TST-ACC-TRX-108, TST-ACC-TRX-109, TST-ACC-TRX-264]
    statement: >-
      Unknown or pending processor outcomes keep the refund processing with money held until confirmed by
      lookup, event or human resolution, without abandonment.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refund-timeout-before-send.integration.spec.js#it
      leaves the refund processing a day on, never failed as never received and never abandoned
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-10
    proved_by: []
    statement: Only check refunds can carry a check number.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: false
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refund-check-number.integration.spec.js#it
      is refused in plain words, naming the method, and stores no refund
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-11
    proved_by: [ATS-ACC-TRX-012-10, TST-ACC-TRX-122]
    statement: >-
      Refunding card-paid value also returns its proportional processing fee rounded downward and credits the
      fee invoice.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/settlements/card-fees.integration.spec.js#it
      takes the fee’s share back with the line: 2000 of 4000 refunded is 2065, the fee invoice credited 65
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-12
    proved_by: [ATS-ACC-TRX-012-11, TST-ACC-TRX-013]
    statement: >-
      Request and cancellation require create authority, approval and execution require their distinct
      sensitive authorities, and immediate execution requires both create and execute.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/e2e/refunds.e2e.spec.js#it is refused approve without
      .approve, execute without .execute and cancel without .create, as a reader (403)
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-012-13
    proved_by: []
    statement: >-
      The product should expose the workspace’s refund-approval setting in the console; only the service
      currently provides it.
    kind: policy
    enforced_at:
      - console
    must_prove: false
    provenance: unknown
    source: FND-ACC-TRX-007
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
scenarios:
  - id: SC-CAP-ACC-TRX-012-01
    given: A check overpayment is available and the member requests part back.
    when: Request a check refund and record its execution.
    then: Offline refund completion reduces available money and derives partially refunded payment standing.
    provenance: test
    source: 'react-console:acceptance/accounting/playwright/journeys/payments/ACT-ACC-0311.spec.ts#ACT-ACC-0311'
  - id: SC-CAP-ACC-TRX-012-02
    given: A payment has allocations on two lines.
    when: 'Refund both, choosing credit treatment for one and reopening for the other.'
    then: A memo maintains the first line’s settlement while the second regains its debt.
    provenance: test
    source: 'react-console:acceptance/accounting/playwright/journeys/payments/ACT-ACC-0312.spec.ts#ACT-ACC-0312'
  - id: SC-CAP-ACC-TRX-012-03
    given: The requested card refund concerns an allocated invoice line.
    when: Execute a refund that the processor definitely declines.
    then: Failure leaves the source application and money at their original position.
    provenance: test
    source: 'react-console:acceptance/accounting/playwright/journeys/payments/ACT-ACC-0314.spec.ts#ACT-ACC-0314'
edge_cases: []
depends_on:
  - CAP-ACC-TRX-006
  - CAP-ACC-TRX-007
  - CAP-ACC-TRX-011
related:
  - CAP-ACC-TRX-014
  - CAP-ACC-TRX-020
journeys:
  - JNY-ACC-TRX-004
  - JNY-ACC-TRX-005
open_questions: []
evidence:
  - >-
    services-accounting at f47cb263875bbc0c5640fba7dae6785ec32695f8:
    modules/transactions/aws/api/refunds.routes.ts (requestRefund, getRefund, listRefunds, approveRefund,
    executeRefund, cancelRefund, listRefundActions, performRefundAction); services/refunds/refund-commands.ts,
    refund-rules.ts, refund-answers.ts; services/actions/refund-actions.ts; db/refunds.table.ts,
    refund-lines.table.ts; docs/accounting/refunds.md;
    docs/debt/refund-reason-metadata-may-carry-personal-data.md; tests e2e/refunds.e2e.spec.js,
    integration/services/refunds/*, integration/services/integrations/refund-confirmation-by-reference,
    integration/services/settlements/card-fees.
  - >-
    react-console at baf6dae382d6f41dce976c7f848667ccc37e076f:
    app/(console)/console/[tenantId]/accounting/refunds/**; components/accounting/refunds/*; journeys
    ACT-ACC-0311 to 0315, 0346; inventory rules RUL-ACC-PAY-038 to 047.
controls: [TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, 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-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-003, TC-PI-005, TC-AI-005, TC-VEN-001, TC-VEN-002, TC-VEN-003, TC-PRV-001, TC-PRV-002]
exercised_by: [FAS-ACC-TRX-04-01, FAS-ACC-TRX-04-02, FAS-ACC-TRX-04-03, FAS-ACC-TRX-04-04, FAS-ACC-TRX-04-05]
suites: [TST-ACC-TRX-013, TST-ACC-TRX-042, TST-ACC-TRX-105, TST-ACC-TRX-107, TST-ACC-TRX-108, TST-ACC-TRX-109, TST-ACC-TRX-122, TST-ACC-TRX-248, TST-ACC-TRX-249, TST-ACC-TRX-250, TST-ACC-TRX-251, TST-ACC-TRX-264]
---

# Return customer money with accountable refunds

## Purpose

Staff return eligible value while keeping its source, approval and outcome inspectable.

## How It Works

Staff identify available receipt value, invoice applications or credit to return. Requesting reserves the selected value so it cannot be spent elsewhere. Where approval is enabled, another person must authorize the request. Offline execution records the payment back immediately. Processor execution can complete, fail definitely or remain uncertain. Failed refunds restore the local position and uncertain ones continue holding money. Returning applied value either credits the original charge or reopens its debt according to the chosen treatment.

## Relationships

- Record receipts collected outside Rhythm supplies or continues the related financial work.
- Collect processor payments and resolve uncertainty supplies or continues the related financial work.
- Provide and spend customer credit supplies or continues the related financial work.
- Unwind billed purchases and their collected value supplies or continues the related financial work.
- Coordinate financial commands across applications supplies or continues the related financial work.
