---
id: WF-MBR-MEM-012
title: Reserve a purchase at placement and fulfil it
trigger: >-
  Commerce places membership items and later sends their payment-authorized
  fulfilment obligations.
product_area: membership
module: memberships
revision: 1
status: draft
design_intent: proposed
implementation_evidence: partially-observed
inference: []
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-MBR-MEM-009
  - CAP-MBR-MEM-014
  - CAP-MBR-MEM-020
moves:
  - STATE-MBR-MEM-001
  - STATE-MBR-MEM-003
  - STATE-MBR-MEM-004
  - STATE-MBR-MEM-011
crosses:
  - SVC-MBR-MEM-commerce-participant
  - SVC-MBR-MEM-memberships
  - SVC-MBR-MEM-applications
  - SVC-MBR-MEM-events
idempotency: >-
  The claim index prevents multiple claim records for a term. Payment
  authorization uniqueness recognizes fulfilled repeats, including the previous
  authorization named by a reauthorization.
concurrency: >-
  Placement orders competing reservations through owner identity and claim
  checks. Fulfilment locks the holding and returns retryable failure while a
  Commerce fence remains.
hops:
  - 'n': 1
    actor_or_service: Commerce placement transaction
    action: >-
      Reserve pending coverage through Commerce’s owner function and create an
      unnumbered holding when needed.
    anchor: >-
      services-membership:db/migrations/20261018044117_commerce_participant.sql:commerce_commit_claims
    seam: sync
    on_failure: >-
      Roll back Commerce placement; the current attribution mismatch rejects its
      commit.
    left_inconsistent: The reservation shares the order’s commit or rollback.
    observer: Commerce checkout result
    provenance: unknown
    source: FND-MBR-MEM-030
  - 'n': 2
    actor_or_service: Commerce
    action: >-
      Deliver the package obligation after the required payment and approval
      conditions.
    anchor: >-
      services-membership:modules/commerce-participant/services/fulfilment/fulfill.ts:fulfill
    seam: queue
    on_failure: Commerce may deliver the obligation again after failure.
    left_inconsistent: >-
      Reserved coverage stays pending while its package obligation is
      unfinished.
    observer: Commerce fulfilment evidence
    provenance: observed
    source: >-
      services-membership:modules/commerce-participant/services/fulfilment/fulfill.ts
      (header)
  - 'n': 3
    actor_or_service: Commerce participant
    action: >-
      Lock the holding, recognize authorization repeats, commit the period,
      number a new holding and record events.
    anchor: >-
      services-membership:modules/commerce-participant/services/fulfilment/fulfill.ts:fulfill
    seam: sync
    on_failure: >-
      Return retryable fence failure, or roll back an error for Commerce
      redelivery.
    left_inconsistent: No partial local change remains.
    observer: Membership lifecycle log
    provenance: test
    source: >-
      services-membership:modules/commerce-participant/tests/integration/participant.integration.spec.ts#answers
      a redelivered authorization with the same records
  - 'n': 4
    actor_or_service: Commerce participant
    action: >-
      Write selected or carried units, grants and children, refresh caches,
      resolve attention, close the claim and link the application.
    anchor: >-
      services-membership:modules/memberships/services/affiliations/affiliation-operations.ts:writeTermAffiliations
    seam: sync
    on_failure: >-
      Dependent writes roll back with fulfilment so Commerce can repeat the
      obligation.
    left_inconsistent: No partial local change remains.
    observer: Published business-event log
    provenance: observed
    source: >-
      services-membership:modules/commerce-participant/services/fulfilment/fulfill.ts
      (header)
  - 'n': 5
    actor_or_service: Commerce participant
    action: >-
      Fulfil dues components by stamping their paying lines and grant components
      by returning the corresponding granted period.
    anchor: >-
      services-membership:modules/commerce-participant/services/fulfilment/fulfill.ts:fulfillComponent
    seam: queue
    on_failure: Ask Commerce to retry the component after its package has committed.
    left_inconsistent: >-
      The affiliation can exist without its paying component reference until
      component fulfilment.
    observer: Commerce fulfilment evidence
    provenance: test
    source: >-
      services-membership:modules/commerce-participant/tests/integration/participant.integration.spec.ts#stamps
      the dues line on the affiliation once the package line
branches:
  - >-
    An unspecified renewal unit set is carried forward, but the current
    fulfilment source labels it as application selection rather than
    inheritance.
waits:
  - >-
    Reserved coverage can remain pending until both payment and required
    approval permit fulfilment.
evidence:
  - >-
    services-membership at 5994c270:
    db/migrations/20261018044117_commerce_participant.sql;
    modules/commerce-participant/services/fulfilment/fulfill.ts;
    services/persistence/commerce-claims.ts;
    docs/migrations/participant/README.md
controls: [TC-AVL-002, TC-AVL-003, TC-AVL-004, TC-AZ-001, TC-AZ-003, TC-AZ-004, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-007, TC-IAM-006, TC-LOG-002, TC-LOG-003, TC-LOG-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, TC-SEC-001, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003]
---

# Reserve a purchase at placement and fulfil it

## What It Does

Purchase placement reserves coverage together with the Commerce order. Later fulfilment commits that period and establishes affiliations, grants, numbering and linked children.

## The Flow

```mermaid
flowchart TD
  H1["Reserve pending coverage through Commerce’s owner function and create an unnumbered holding when needed"]
  H2["Deliver the package obligation after the required payment and approval conditions"]
  H1 --> H2
  H3["Lock the holding, recognize authorization repeats, commit the period, number a new holding and record events"]
  H2 --> H3
  H4["Write selected or carried units, grants and children, refresh caches, resolve attention, close the claim and link the application"]
  H3 --> H4
  H5["Fulfil dues components by stamping their paying lines and grant components by returning the corresponding granted period"]
  H4 --> H5
```

## When Something Fails

The order and reservation roll back together. The current reservation writer uses a history source that commit rejects, blocking ordinary placement. Fulfilment failures preserve pending coverage; component lines request retry until package fulfilment succeeds. Duplicate unit choices can leave a reservation permanently unfulfillable.

## Open Design Questions

The placement attribution incompatibility must be fixed before purchase readiness can be claimed.
