---
id: STATE-ACC-TRX-012
title: Credit application lifecycle
object: DOM-ACC-TRX-004
product_area: accounting
module: transactions
revision: 1
status: draft
design_intent: confirmed
origin: >-
  Andrew, 2026-10-16: credit applications are the only mechanism, a document
  with a number and a batch
  (services-accounting:docs/architecture/accounting-2.0/02-decisions.md#1. The
  assessment's decisions, D-01 to D-07 (Andrew, 2026-10-17))
implementation_evidence: observed
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
states:
  - name: not created
    meaning: No application record exists.
  - name: pending
    meaning: A settlement holds credit without placing it on invoice debt yet.
  - name: applied
    meaning: Credit has been placed on billed lines.
  - name: cancelled
    meaning: Settlement failure released the pending reservation.
  - name: reversed
    meaning: An opposing application restored the earlier financial position.
transitions:
  - from: not created
    to: applied
    trigger: place credit directly
    guard: >-
      Customer, unit, currency, expiry, order category and both source and
      target balances must be eligible.
    side_effects:
      - assign application number and batch
      - increase line paid amounts
      - append application facts
    who: >-
      Staff with credit-application create permission or the Commerce tender
      function.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/credits/credit-commands.ts;
      services-accounting:modules/transactions/services/settlements/settlement-commands.ts;
      services-accounting:modules/transactions/db/credit-applications.table.ts;
      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
  - from: not created
    to: pending
    trigger: reserve credit for settlement
    guard: >-
      The customer's selected open credit is considered by explicit selection
      before automatic oldest-first selection.
    side_effects:
      - increase held credit value
    who: Settlement coordination.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/credits/credit-commands.ts;
      services-accounting:modules/transactions/services/settlements/settlement-commands.ts;
      services-accounting:modules/transactions/db/credit-applications.table.ts;
      services-accounting:modules/transactions/tests/integration/services/settlements/settlements.integration.spec.js#it
      refuses with the decline (processor_declined), the settlement failed with
      the code, the reservation released, nothing applied
  - from: pending
    to: applied
    trigger: complete reserved application
    guard: Collection must succeed or the settlement need no money.
    side_effects:
      - insert capped application lines
      - move held value to spent value
    who: Settlement coordination or scheduled recovery.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/credits/credit-commands.ts;
      services-accounting:modules/transactions/services/settlements/settlement-commands.ts;
      services-accounting:modules/transactions/db/credit-applications.table.ts;
      services-accounting:modules/transactions/tests/integration/services/settlements/settlements.integration.spec.js#it
      applies the open credit’s 500 first and takes a check of 8000 for the
      rest: completed with its payment
  - from: pending
    to: cancelled
    trigger: release a failed settlement hold
    guard: Collection failure or abandonment must be established.
    side_effects:
      - release held credit value
    who: Settlement coordination or scheduled recovery.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/credits/credit-commands.ts;
      services-accounting:modules/transactions/services/settlements/settlement-commands.ts;
      services-accounting:modules/transactions/db/credit-applications.table.ts;
      services-accounting:modules/transactions/tests/integration/services/settlements/settlement-retry.integration.spec.js#it
      runs a new attempt under the key: a new settlement, completed with a
      payment, stored under the key with its attempt number
  - from: applied
    to: reversed
    trigger: restore an applied credit
    guard: The original must be unreversed and a reason supplied.
    side_effects:
      - create today's opposing application
      - restore invoice debt and credit availability
    who: Staff with credit-application create permission.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/credits/credit-commands.ts;
      services-accounting:modules/transactions/services/settlements/settlement-commands.ts;
      services-accounting:modules/transactions/db/credit-applications.table.ts;
      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
invalid:
  - from: reversed
    to: applied
    why: Using the restored credit requires a new application after reversal.
  - from: cancelled
    to: applied
    why: >-
      Released reservations cannot be applied; another settlement must create a
      new hold.
concurrency: >-
  One credit is locked for competing applications, and settlement holds remain
  until the coordinated outcome.
invariants:
  - INV-DOM-ACC-TRX-004-04
  - INV-DOM-ACC-TRX-004-08
  - INV-DOM-ACC-TRX-004-10
evidence:
  - >-
    services-accounting at f47cb263: services/credits/credit-commands.ts;
    services/settlements/settlement-commands.ts;
    db/credit-applications.table.ts;
    docs/architecture/accounting-2.0/05-lifecycles.md §3.
---
# Credit application lifecycle

## The Lifecycle

Pending applications represent credit reservations. Completion and cancellation are settlement-driven, while direct application creates applied records immediately.

```mermaid
stateDiagram-v2
  direction LR
  state "not created" as s0
  state "pending" as s1
  state "applied" as s2
  state "cancelled" as s3
  state "reversed" as s4
  s0 --> s2 : place credit directly
  s0 --> s1 : reserve credit for settlement
  s1 --> s2 : complete reserved application
  s1 --> s3 : release a failed settlement hold
  s2 --> s4 : restore an applied credit
```

## Transitions Explained

The transition rows identify the initiating action, eligibility checks, resulting records and responsible caller. They retain the pinned evidence for each path.

## What Cannot Happen

The invalid-transition rows describe final-state protection and unsupported paths; command eligibility remains distinct from the declared state vocabulary.

## Concurrency and Timing

One credit is locked for competing applications, and settlement holds remain until the coordinated outcome. Pending duration follows settlement collection recovery.
