---
id: STATE-COM-CAT-010
title: Promotion redemption
object: DOM-COM-CAT-005
product_area: commerce
module: catalog
revision: 1
status: draft
design_intent: confirmed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
states:
  - name: applied
    meaning: 'Placement retained the discount, terms and allocations and counted the promotion and any code use.'
  - name: released
    meaning: Capacity has been restored while monetary evidence remains unchanged.
  - name: reversed
    meaning: 'The vocabulary declares this released-capacity state, but no implementation path writes it.'
transitions:
  - from: applied
    to: released
    trigger: Order void releases retained uses.
    guard: The use must still count as applied.
    side_effects:
      - 'Locked code and campaign counters decrease, and both histories record release.'
      - The retained reason identifies order voiding.
    who: 'Order void (always, not configurable)'
    provenance: documented
    source: >-
      services-commerce:modules/promotions/services/redemptions/redemption-release.ts:releaseVoidedOrderRedemptions
  - from: applied
    to: released
    trigger: Cancellation fully cancels every allocated line.
    guard: The redemption’s retained cancellation-release choice must permit release.
    side_effects:
      - Capacity is restored with attributed history.
      - The retained reason identifies order cancellation.
    who: 'Order cancellation, enforcement handling'
    provenance: documented
    source: >-
      services-commerce:modules/promotions/services/redemptions/redemption-release.ts:releaseRedemptionsForCancelledLines
  - from: applied
    to: released
    trigger: An authorized staff request supplies a release reason.
    guard: 'Override authority, a release reason and an applied use are required.'
    side_effects:
      - Release updates capacity and both histories with the requesting actor and explanation.
    who: Selling configuration administrator (commerce.promotions.override)
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-redemptions.e2e.spec.js#refuses a release
      without a reason, 400
invalid:
  - from: released
    to: applied
    why: Database protection prevents restoring an applied use after release.
  - from: released
    to: released
    why: A repeated staff release reports the existing release and restores no additional capacity.
concurrency: >-
  Placement and release lock code and promotion counters in a consistent order. Release changes applied
  redemptions only, preventing double capacity restoration while preserving monetary evidence.
invariants:
  - INV-DOM-COM-CAT-005-10
  - INV-DOM-COM-CAT-005-11
  - INV-DOM-COM-CAT-005-12
  - INV-DOM-COM-CAT-005-13
evidence:
  - >-
    services-commerce at c8b66a98: modules/promotions/db/promotion-redemptions.table.ts (REDEMPTION_STATUSES,
    RELEASE_REASONS); services/persistence/promotion-redemptions.ts (recordRedemption, releaseRedemptions);
    services/redemptions/redemption-release.ts; services/promotions/promotion-workflow.ts (releaseRedemption).
  - >-
    services-commerce at c8b66a98: modules/orders/services/orders/void-order.ts;
    modules/orders/services/cancellations/cancellation-workflow.ts (the callers).
---

# Promotion redemption

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> applied: order placed
  applied --> released: void, full cancellation, staff release
  released --> [*]
```

## Transitions Explained

Applied: Placement retained the discount, terms and allocations and counted the promotion and any code use. Released: Capacity has been restored while monetary evidence remains unchanged. Reversed: The vocabulary declares this released-capacity state, but no implementation path writes it.

## What Cannot Happen

Database protection prevents restoring an applied use after release. A repeated staff release reports the existing release and restores no additional capacity.

## Concurrency and Timing

Placement and release lock code and promotion counters in a consistent order. Release changes applied redemptions only, preventing double capacity restoration while preserving monetary evidence.
