---
id: WF-COM-ORD-002
title: Place an order
trigger: A buyer or staff member requests placement of an open cart; assessment can be performed during placement.
product_area: commerce
module: orders
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-COM-ORD-005
  - CAP-COM-ORD-002
  - CAP-COM-ORD-004
  - CAP-COM-ORD-012
  - CAP-COM-ORD-006
moves:
  - STATE-COM-ORD-001
  - STATE-COM-ORD-002
  - STATE-COM-ORD-003
  - STATE-COM-ORD-004
  - STATE-COM-ORD-005
crosses:
  - SVC-COM-ORD-checkout
  - SVC-COM-ORD-orders
  - SVC-COM-ORD-participants
  - SVC-PFM-ELG-eligibility
  - SVC-ACC-TRX-transactions
idempotency: >-
  The required request key replays the completed response or reports an in-progress request. Placement also
  recognizes the key stored on a placed cart and rejects a different key; checkout uniqueness protects against
  duplicate sales.
concurrency: >-
  The placement lock serializes requests for one cart and detects intervening edits. Canonically ordered claim
  functions determine the winner for scarce resources, rolling back a losing transaction.
hops:
  - 'n': 1
    actor_or_service: Checkout route
    action: >-
      Authorize placement, recognize a previously placed cart, require an open nonempty cart, preprocess it
      and resolve policy, business unit and currency.
    anchor: 'services-commerce:modules/orders/services/placement/place-order.ts:placeOrder'
    seam: sync
    on_failure: Refusal preserves the cart without creating a sale.
    left_inconsistent: No order is partially placed.
    observer: Observed through the requesting buyer or staff member; refusals are recorded on the cart's trail.
    provenance: test
    source: 'services-commerce:modules/checkout/tests/e2e/placement.e2e.spec.js'
  - 'n': 2
    actor_or_service: 'Selling applications, pricing and promotions'
    action: >-
      Before the transaction, check the shipping party and obtain fresh ten-second preparation, reaffirming
      holds and assessing prices, rules and offers at one instant.
    anchor: 'services-commerce:modules/checkout/services/checkout/checkout-assessment.ts:assessCheckout'
    seam: sync
    on_failure: >-
      Blockers refuse placement; missing application or promotion-area answers return retryable
      unavailability.
    left_inconsistent: No order or transactional claim is committed.
    observer: Observed through the requesting buyer or staff member; the cart action trail records the refusal.
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#refuses a placement made after
      the T-shirt was gone with the same 409 claim_conflict, never a preparation refusal
  - 'n': 3
    actor_or_service: Placement price binding
    action: >-
      Bind recalculated item prices, quantities, totals and audiences against the saved preview, and compare
      discounts and fees.
    anchor: 'services-commerce:modules/orders/services/placement/price-binding.ts'
    seam: sync
    on_failure: Changed prices or offers require a fresh review with the recalculated figures.
    left_inconsistent: Placement has not committed a sale.
    observer: Observed through the requesting buyer or staff member.
    provenance: test
    source: 'services-commerce:modules/checkout/tests/e2e/engine-pricing.e2e.spec.js'
  - 'n': 4
    actor_or_service: 'Shipping, fee, tax and installments'
    action: >-
      Resolve discounted shipping, fees, frozen addresses, taxes, charge products and an installment quote for
      the intended lines.
    anchor: 'services-commerce:modules/orders/services/placement/place-order.ts:placeOrder'
    seam: sync
    on_failure: >-
      Invalid inputs refuse placement; tax refusal uses a bad-request response and unanswered Accounting calls
      return unavailability.
    left_inconsistent: The proposed lines remain uncommitted.
    observer: Observed through the requesting buyer or staff member.
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/accounting-tax.e2e.spec.js#is a tax_quote_refused problem
      on the preview and refuses the placement, placing nothing
  - 'n': 5
    actor_or_service: Placement transaction
    action: >-
      Lock and version-check the cart; recheck rules, audiences and offers; prepare and freeze items; commit
      ordered claims; insert the numbered sale and policy snapshot; redeem offers and create delivery
      obligations; finish the cart as placed.
    anchor: 'services-commerce:modules/orders/services/placement/place-order.ts:placeOrder'
    seam: sync
    on_failure: >-
      A claim, eligibility, redemption or invariant failure rolls back the transaction and records refusal
      afterwards.
    left_inconsistent: Shared claim rows and Commerce writes roll back together; allocated numbers can leave gaps.
    observer: >-
      Observed through the requesting buyer or staff member; the cart action trail; a broken promotion-sum
      invariant reaches the caller as a server error.
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#rolled the first seat claim
      back with the transaction, and left the booth held for the buyer to retry with
  - 'n': 6
    actor_or_service: Selling application (lease mode)
    action: Confirm placed leases with their owning applications after the database commit.
    anchor: 'services-commerce:modules/orders/services/placement/lease-confirmation.ts:confirmLease'
    seam: sync
    on_failure: Missing answers retain held leases for the reservation pass; expiry or conflict records mismatch.
    left_inconsistent: The sale can stand with unconfirmed leased resources.
    observer: Observed through sale history (claim confirmed or unconfirmed); operational exceptions.
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#confirms it on the sweep: the
      ledger committed, the participant’s claim committed, claim_confirmed on the order
  - 'n': 7
    actor_or_service: Billing
    action: 'Request sale billing after placement, accepting terms or no-payment purchases when billing succeeds.'
    anchor: 'services-commerce:modules/orders/services/billing/bill-order.ts:billPlacedOrder'
    seam: sync
    on_failure: Billing failure is converted to pending or blocked processing rather than undoing placement.
    left_inconsistent: 'The recorded sale can await its invoice, with payment unavailable until billing succeeds.'
    observer: Observed through the sale detail screen (billing state); placed-without-invoice exception after an hour.
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#leaves the order placed and
      pending with one attempt; the buyer’s tender bills it first and proceeds
branches:
  - The original request key retrieves the sale already placed from the cart; a different key is refused.
  - >-
    Immediate-payment and deposit policies start their payment window at placement; terms and no-payment
    policies omit it.
waits:
  - 'Immediate-payment sales await collection within the configured window, ordinarily thirty minutes.'
evidence:
  - >-
    services-commerce at c8b66a98: modules/orders/services/placement/place-order.ts, price-binding.ts,
    claims-at-placement.ts, lease-confirmation.ts, tender-window.ts;
    modules/orders/services/persistence/orders.ts; modules/checkout/tests/e2e/placement.e2e.spec.js,
    idempotency.e2e.spec.js, holds-and-claims.e2e.spec.js.
  - 'react-console at baf6dae3: lib/commerce/composer/live.ts (placement under the cart identity as key).'
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-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-004, TC-LOG-005, 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]
---

# Place an order

## What It Does

Placement creates one numbered sale from an open cart after authoritative recalculation. Its commit includes resource claims, offer redemption and delivery registration, with the agreed policy and purchase details preserved.

## The Flow

```mermaid
sequenceDiagram
  participant C as Clerk or buyer
  participant K as Checkout and placement
  participant A as Selling application
  participant P as Pricing and eligibility
  participant DB as Commerce database
  participant X as Accounting
  C->>K: place (idempotency key)
  K->>A: prepare every item (outside a transaction)
  K->>P: price, rules, promotions, tax
  K->>K: compare with the preview
  K->>DB: one transaction: lock cart, claims via application functions, order, redemptions, obligations, cart placed
  K->>A: confirm leases (after commit)
  K->>X: bill the order (after commit)
  K-->>C: the order, billed or pending
```

## When Something Fails

Preparation refusals create no sale. The placement transaction rolls back Commerce and application claim rows together. After commit, unanswered leases wait for confirmation and billing stays pending or blocked for recovery; neither reverses placement. Tax refusal and invariant errors have different response shapes.

## Open Design Questions

Placement detects a missing shipping charge product that preview does not expose. Recovery after commit still depends on a healthy shared sweeper.
