---
id: CAP-ACC-TRX-011
title: Provide and spend customer credit
feature: FEAT-ACC-TRX-04
product_area: accounting
module: transactions
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes:
  - CAP-ACC-PAY-010
  - CAP-ACC-PAY-011
  - CAP-ACC-PAY-012
  - CAP-ACC-PAY-013
  - CAP-ACC-PAY-014
  - CAP-ACC-PAY-028
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-accounting:docs/milestones/plans/ACCT-M2-plan.md#D4'
  - 'services-accounting:docs/milestones/plans/ACCT-M2-plan.md#D5'
  - 'services-accounting:docs/milestones/plans/ACCT-M2-plan.md#D6'
  - 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#M2-2'
  - 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#A-9'
purpose: Staff retain customer value for later settlement without confusing it with invoice reduction.
outcomes:
  - Staff retain customer value for later settlement without confusing it with invoice reduction.
  - >-
    Unused credit can be voided, returning payment-backed value to its source. Competing requests cannot spend
    the same remaining value twice.
concepts:
  - CON-ACC-TRX-004
  - CON-ACC-TRX-003
actors:
  - ACT-ACC-012
  - ACT-ACC-021
surfaces:
  - console
  - api
permissions:
  - key: accounting.credits.create
    where_checked: api
    scope: tenant
  - key: accounting.credits.read
    where_checked: api
    scope: tenant
  - key: accounting.credits.update
    where_checked: api
    scope: tenant
  - key: accounting.credit-applications.create
    where_checked: api
    scope: tenant
  - key: accounting.credit-applications.read
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-ACC-TRX-011-01
    proved_by: [ATS-ACC-TRX-011-01, TST-ACC-TRX-004, TST-ACC-TRX-037]
    statement: >-
      Manually issued credit identifies the customer, unit, currency, reason and that unit’s liability and
      expense accounts.
    kind: validation
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/e2e/credits.e2e.spec.js#it refuses a manual credit
      without its accounts, and a payment’s credit without its payment (400)
    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-011-02
    proved_by: [ATS-ACC-TRX-003-12, ATS-ACC-TRX-008-09, ATS-ACC-TRX-011-02, ATS-ACC-TRX-011-10, ATS-ACC-TRX-013-10, ATS-ACC-TRX-014-09, TST-ACC-TRX-037, TST-ACC-TRX-247]
    statement: >-
      Payment-backed credit inherits the payment’s customer, unit and currency and transfers no more than its
      unapplied value out of the payment while the credit remains live.
    kind: calculation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      refuses more than the payment holds unapplied (over_application)
    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-011-03
    proved_by: [ATS-ACC-TRX-007-12, ATS-ACC-TRX-008-09, ATS-ACC-TRX-009-12, ATS-ACC-TRX-011-03, ATS-ACC-TRX-011-10, ATS-ACC-TRX-012-12, TST-ACC-TRX-037, TST-ACC-TRX-256]
    statement: >-
      Available credit equals issued value less applications, refunds and reservations; positive balance is
      open, zero is used, and database checks prevent overspending.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      refuses more than the credit holds (insufficient_credit), the database’s CHECK, writing nothing
    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-011-04
    proved_by: [ATS-ACC-TRX-007-12, ATS-ACC-TRX-009-12, ATS-ACC-TRX-011-04, ATS-ACC-TRX-014-09, TST-ACC-TRX-037]
    statement: >-
      Only a numbered batched credit application puts credit on invoice lines, using payment-style target
      selection and producing paid status when a line is settled.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      raises the line’s amount_paid: a line settled by store credit reads open until fully paid, then paid
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#M2-2'
  - id: BR-CAP-ACC-TRX-011-05
    proved_by: [ATS-ACC-TRX-011-05, TST-ACC-TRX-037, TST-ACC-TRX-257]
    statement: Credit can settle invoices belonging to its own customer only.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      refuses a credit of another customer than the invoice’s bill-to (credit_customer_mismatch)
    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-011-06
    proved_by: [ATS-ACC-TRX-011-06, TST-ACC-TRX-037]
    statement: >-
      Application rejects credit after its expiry date or outside its permitted order type, although no worker
      marks credits expired.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      refuses a credit that expired before the application date (credit_expired)
    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-011-07
    proved_by: [ATS-ACC-TRX-011-03, TST-ACC-TRX-037, TST-ACC-TRX-256]
    statement: Concurrent applications serialize so they cannot both consume the same remaining credit.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      serializes two concurrent applications of one credit: one succeeds, the other is refused by the database
    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-011-08
    proved_by: [ATS-ACC-TRX-011-07, TST-ACC-TRX-037, TST-ACC-TRX-246]
    statement: >-
      Undoing an application creates one dated opposing application with a reason, restores the credit and
      invoice balances, and prevents a second reversal.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      marks the first reversed and gives the money back to the credit, which is open again
    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-011-09
    proved_by: [ATS-ACC-TRX-011-08, ATS-ACC-TRX-011-10, ATS-ACC-TRX-013-10, TST-ACC-TRX-037]
    statement: >-
      Voiding requires unused, unreserved and unrefunded credit before posting; payment-backed credit then
      restores its source payment’s available value.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      refuses voiding a credit with money applied (credit_has_applications)
    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-011-10
    proved_by: []
    statement: Eligible customer credit is presented oldest first within its unit and currency.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/e2e/credits.e2e.spec.js#it lists Ada’s open credits in
      alpha USD, oldest first
    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-011-11
    proved_by: [ATS-ACC-TRX-011-09, TST-ACC-TRX-004]
    statement: >-
      Credit operations use credit authorities, while application and reversal use credit-application
      authorities.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/e2e/credits.e2e.spec.js#it is refused the application
      routes without their permissions (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-011-12
    proved_by: []
    statement: >-
      Application rows and database-maintained credit amounts cannot be directly edited by the application
      role.
    kind: invariant
    enforced_at:
      - database
    must_prove: false
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/credits/credits.integration.spec.js#it
      refuses an UPDATE and a DELETE of an application line
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#D-01'
scenarios:
  - id: SC-CAP-ACC-TRX-011-01
    given: Staff want to compensate a member with goodwill value.
    when: 'Issue credit, pay two lines with it, then undo one application.'
    then: >-
      Credit settles the selected lines and the reversal restores both its available value and the affected
      debt.
    provenance: test
    source: 'react-console:acceptance/accounting/playwright/journeys/payments/ACT-ACC-0309.spec.ts#ACT-ACC-0309'
  - id: SC-CAP-ACC-TRX-011-02
    given: Credit and invoice belong to different members of one unit.
    when: Apply that credit directly to the unrelated invoice.
    then: Customer mismatch rejects the application without moving value.
    provenance: test
    source: 'react-console:acceptance/accounting/playwright/journeys/payments/ACT-ACC-0322.spec.ts#ACT-ACC-0322'
edge_cases: []
depends_on: []
related:
  - CAP-ACC-TRX-006
  - CAP-ACC-TRX-009
  - CAP-ACC-TRX-012
  - CAP-ACC-TRX-013
journeys:
  - JNY-ACC-TRX-004
evidence:
  - >-
    services-accounting at f47cb263875bbc0c5640fba7dae6785ec32695f8:
    modules/transactions/aws/api/credits.routes.ts (createCredit, getCredit, listCredits, listOpenCredits,
    voidCredit, listCreditActions, performCreditAction, applyCredit, getCreditApplication,
    listCreditApplications, reverseCreditApplication); services/credits/credit-commands.ts, credit-reads.ts,
    credit-answers.ts; services/actions/credit-actions.ts; services/persistence/credits.ts,
    credit-applications.ts; db/credits.table.ts, credit-applications.table.ts,
    credit-application-lines.table.ts; docs/accounting/credits.md; tests e2e/credits.e2e.spec.js,
    integration/services/credits/credits.integration.spec.js,
    integration/services/persistence/credits.queries.
  - >-
    react-console at baf6dae382d6f41dce976c7f848667ccc37e076f:
    app/(console)/console/[tenantId]/accounting/credits/**, creditApplications/**;
    components/accounting/credits/*, components/accounting/credit-applications/*; journeys ACT-ACC-0309, 0310,
    0322, 0323, 0345; inventory rules RUL-ACC-PAY-027 to 029, 033 to 037 (RUL-ACC-PAY-036 is stale).
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-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-AVL-001, 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-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-004, TST-ACC-TRX-037, TST-ACC-TRX-246, TST-ACC-TRX-247, TST-ACC-TRX-256, TST-ACC-TRX-257]
---

# Provide and spend customer credit

## Purpose

Staff retain customer value for later settlement without confusing it with invoice reduction.

## How It Works

Staff create goodwill credit or transfer available receipt money into credit. Accounting retains its customer, unit, currency and available balance. Applications spend that value on eligible invoice lines. Expiry and order restrictions can prevent a requested application. Reversal restores the credit and debt through a new opposing document. Unused credit can be voided, returning payment-backed value to its source. Competing requests cannot spend the same remaining value twice.

## Relationships

- Record receipts collected outside Rhythm supplies or continues the related financial work.
- Complete invoice settlement with credit and money supplies or continues the related financial work.
- Return customer money with accountable refunds supplies or continues the related financial work.
- Record receipts that were voided or returned supplies or continues the related financial work.
