---
id: CAP-COM-CAT-016
title: Choose the best permitted promotional result
feature: FEAT-COM-CAT-04
product_area: commerce
module: catalog
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
intent_sources:
  - 'services-commerce:docs/milestones/decisions/COMM-M1-D12-andrew-2026-10-19.md'
  - >-
    services-commerce:docs/milestones/decisions/COMM-M1-D12-evaluation-algorithm.md#7.
    Andrew’s answers
  - >-
    services-commerce:docs/milestones/COMM-M1-set-up-what-you-sell.md#D12-F1 to
    D12-F5
  - >-
    services-commerce:docs/milestones/COMM-M1b-promotions-and-codes.md#Decisions
    (D-R3)
purpose: >-
  Commerce compares pricing and discount alternatives under the customer’s
  combination rules.
outcomes:
  - A buyer is does not worse off for entering a code.
  - >-
    Line-level allocations retain a common monetary basis for tax and later
    financial processing.
  - A use is counted exclusively when a promotion actually gave something.
concepts:
  - CON-COM-CAT-005
  - CON-COM-CAT-004
actors:
  - ACT-COM-005
  - ACT-COM-003
  - ACT-COM-007
surfaces:
  - portal
  - console
  - api
permissions:
  - key: commerce.checkouts.update
    where_checked: api
    scope: tenant
  - key: commerce.orders.create
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-COM-CAT-016-01
    statement: >-
      Price selection returns the cheapest result permitted by the customer’s
      pricing and promotion combination rules.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/alternatives.spec.js#is
      the same answer for the same input
    origin: COMM-M1 D12 (docs/milestones/decisions/COMM-M1-D12-andrew-2026-10-19.md)
  - id: BR-CAP-COM-CAT-016-02
    statement: >-
      Combinable promotions discount audience prices; noncombinable promotions
      discount Standard instead, with the cheaper valid outcome retained for
      every audience.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/alternatives.spec.js#2.
      combine = no, member: audience pricing $80.00 against $100.00 less 25 % =
      $75.00; the promotional price wins
    origin: COMM-M1 D12 (docs/milestones/decisions/COMM-M1-D12-andrew-2026-10-19.md)
  - id: BR-CAP-COM-CAT-016-03
    statement: >-
      The evaluator explores all combinations of up to four noncombinable
      promotions, then considers additional promotions in entry order and
      retains only improvements.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/alternatives.spec.js#tries
      the fifth and later one at a time in entry order
    origin: >-
      COMM-M1 D12 Q1
      (docs/milestones/decisions/COMM-M1-D12-evaluation-algorithm.md)
  - id: BR-CAP-COM-CAT-016-04
    statement: >-
      Line benefits precede order benefits, and each group applies
      priority-ordered automatic promotions before entry-ordered codes against
      the previous result.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/stacking.spec.js#D12
      Q2: puts the line-level promotions before the order-level amounts, each
      group automatic then codes
    origin: >-
      COMM-M1 D12 Q2
      (docs/milestones/decisions/COMM-M1-D12-evaluation-algorithm.md)
  - id: BR-CAP-COM-CAT-016-05
    statement: >-
      Exclusive benefits replace automatic discounts on their covered lines and
      cannot share a line with another code; combinations of up to four
      exclusive codes compete only when they reduce the total.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/alternatives.spec.js#Q5:
      every combination of the exclusive codes: the better of two exclusive
      codes wins whatever the order entered
    origin: >-
      COMM-M1 D12 Q5
      (docs/milestones/decisions/COMM-M1-D12-evaluation-algorithm.md)
  - id: BR-CAP-COM-CAT-016-06
    statement: >-
      Alternatives compare totals before tax and shipping, minimum purchase uses
      qualifying lines after line discounts, and tied results retain audience
      pricing without consuming the code.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/alternatives.spec.js#Q4:
      a tie goes to audience pricing, and the tied code is not used up
    origin: >-
      COMM-M1 D12 Q3, Q4, Q7
      (docs/milestones/decisions/COMM-M1-D12-evaluation-algorithm.md)
    note: The retired allocation identifier remains reserved after consolidation.
  - id: BR-CAP-COM-CAT-016-08
    statement: >-
      Percentage benefits round to whole minor units with exact halves
      increasing the discount in the buyer’s favour.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/benefits.spec.js#takes
      15% off 3333 as 500 (499.95 rounded half up)
    origin: COMM-M1 D12-F3 (docs/milestones/COMM-M1-set-up-what-you-sell.md)
  - id: BR-CAP-COM-CAT-016-09
    statement: >-
      Order discounts and caps allocate proportionally to eligible lines by
      largest remainder, with earlier lines breaking ties and each allocation
      retained for tax and accounting.
    kind: calculation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/allocation.spec.js#shares
      3000 over 10000, 5000 and 2500 as 1714, 857, 429: the largest fraction
      gets the unit
    origin: >-
      COMM-M1 D12 point 6
      (docs/milestones/decisions/COMM-M1-D12-andrew-2026-10-19.md)
  - id: BR-CAP-COM-CAT-016-10
    statement: >-
      Tax, shipping and fee lines and promotion-excluded products receive no
      ordinary discount; shipping benefits reduce the rated shipping charge to
      no less than zero, with tax on its net amount.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/apply-promotions.spec.js#never
      touches a tax, shipping or fee line, nor a product excluded from
      promotions
    origin: COMM-M1 D4 (docs/milestones/COMM-M1-set-up-what-you-sell.md)
  - id: BR-CAP-COM-CAT-016-11
    statement: >-
      Code refusal follows the defined sequence of identity, state, dates,
      currency, usage, purchaser restrictions, authentication, eligibility,
      matching lines and minimum purchase, using customer messages that conceal
      private limits and rules.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/validation.spec.js#answers
      the first refusal in the order of 10.3: an inactive code before an
      exhausted one
    origin: none
  - id: BR-CAP-COM-CAT-016-12
    statement: >-
      Valid but ineffective codes remain recorded as unapplied without consuming
      usage, including line conflicts and business-unit mismatch; invalid codes
      prevent placement.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/apply-promotions.spec.js#refuses
      a promotion whose benefit is zero on every qualifying line (an amount off
      a line already free)
    origin: >-
      COMM-M1 D12 point 8
      (docs/milestones/decisions/COMM-M1-D12-andrew-2026-10-19.md)
    note: D-REC-10 extends point 8 to each nothing-qualifies case; it awaits Andrew.
  - id: BR-CAP-COM-CAT-016-13
    statement: >-
      Unavailable eligibility decisions refuse qualification, and restricted
      anonymous buyers receive a sign-in request before eligibility rejection.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/validation.spec.js#fails
      closed on an indeterminate verdict, for must_match and for must_not_match
      alike
    origin: none
  - id: BR-CAP-COM-CAT-016-14
    statement: >-
      The breakdown identifies line discounts and better audience or automatic
      alternatives, while invoice discount descriptions use customer-facing
      promotion names.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/reason-codes.spec.js#says
      in the customer’s words that the audience price was better, with both
      totals
    origin: >-
      COMM-M1 D12 point 8
      (docs/milestones/decisions/COMM-M1-D12-andrew-2026-10-19.md)
    note: Product has not confirmed the invoice-description recommendation.
  - id: BR-CAP-COM-CAT-016-15
    statement: >-
      Unavailable selling-area checks leave parts unapplied during preview and
      prevent placement with a retry message and no saved sale.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/parts.spec.js#refuses
      a code promotion_check_unavailable when a part is listed unavailable, and
      discounts nothing
    origin: COMM-M1b D-R3 (docs/milestones/COMM-M1b-promotions-and-codes.md)
  - id: BR-CAP-COM-CAT-016-16
    statement: >-
      Concurrent placement respects usage limits, with exactly one hundred
      successful uses when two hundred placements compete for one hundred
      available uses.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/integration/services/persistence/redemption-concurrency.integration.spec.js#applies
      exactly 100 and answers the other 100 code_exhausted
    origin: COMM-M1 plan A15 (promotions D-05) (docs/milestones/plans/COMM-M1-plan.md)
scenarios:
  - id: SC-CAP-COM-CAT-016-01
    given: The buyer holds Member pricing and enters a noncombinable quarter-off code
    when: Compare the audience amount with the discounted Standard amount
    then: >-
      Seventy-five-dollar promotional pricing beats the eighty-dollar audience
      amount
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/alternatives.spec.js#2.
      combine = no, member: audience pricing $80.00 against $100.00 less 25 % =
      $75.00; the promotional price wins
  - id: SC-CAP-COM-CAT-016-02
    given: >-
      Student pricing is sixty dollars against a seventy-five-dollar promotional
      alternative
    when: Enter the same noncombinable code as Student
    then: >-
      Audience pricing remains selected, usage stays unchanged and an
      explanation is returned
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/alternatives.spec.js#3.
      combine = no, student at $60.00: audience pricing wins, EARLY25 consumes
      no use, and the buyer is told why
  - id: SC-CAP-COM-CAT-016-03
    given: Automatic Fall pricing beats the exclusive VIP5 benefit
    when: Evaluate the entered VIP5 code
    then: Fall remains applied and VIP5 is unused with its reason
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/unit/pricing/alternatives.spec.js#5.
      exclusive code against the automatic outcome: VIP5 (5 %) would give
      $76.00, Fall 10 % gives $72.00; VIP5 is dropped and consumes no use
edge_cases:
  - id: SC-CAP-COM-CAT-016-04
    given: The code has capacity for one hundred uses
    when: Run two hundred simultaneous placements
    then: One hundred apply and the others receive exhausted-capacity refusals
    provenance: test
    source: >-
      services-commerce:modules/promotions/tests/integration/services/persistence/redemption-concurrency.integration.spec.js#applies
      exactly 100 and answers the other 100 code_exhausted
depends_on:
  - CAP-COM-CAT-013
  - CAP-COM-CAT-014
  - CAP-COM-CAT-015
related:
  - CAP-COM-CAT-017
  - CAP-COM-CAT-018
journeys:
  - JNY-COM-CAT-005
evidence:
  - >-
    Pinned service inputs: modules/promotions/services/pricing/** (the pure
    evaluation library), services/checkout/**, services/eligibility/**,
    services/areas/**, services/redemptions/**; db/checkout-promotions.table.ts,
    order-line-discounts.table.ts; tests (unit pricing, eligibility, areas;
    integration checkout candidates, checkout promotions, redemptions,
    concurrency)
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-TEN-004, TC-CRY-001, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-004, TC-LOG-005, TC-AVL-004, TC-AVL-005, 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]
---

# Choose the best permitted promotional result

## Purpose

Commerce compares pricing and discount alternatives under the customer’s combination rules.

## How It Works

Checkout supplies candidate promotions and the buyer’s pricing bases for assessment. Selling-area providers identify which lines each part covers. The evaluator considers permitted alternatives and selects the lower valid result. Line and order benefits produce retained allocations and explanations. Some entered codes remain unapplied because another outcome is better; invalid claims can instead prevent placement. Provider unavailability and concurrent capacity checks require different treatment at preview and placement. The product should confirm outstanding unapplied-code and invoice-description recommendations.

## Relationships

The calculate and explain a buyer’s item price capability supplies related configuration or assessment used in this work.

The prepare and control a promotion’s lifecycle capability supplies related configuration or assessment used in this work.

The issue promotion codes with controlled access capability supplies related configuration or assessment used in this work.

The retain and review promotion usage capability supplies related configuration or assessment used in this work.

The preview a promotion against a sample cart capability supplies related configuration or assessment used in this work.
