---
id: WF-COM-ORD-004
title: Take a payment and settle an uncertain one
trigger: A payment request or unresolved-payment recovery starts attempt processing.
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-007
  - CAP-COM-ORD-006
  - CAP-COM-ORD-009
moves:
  - STATE-COM-ORD-006
  - STATE-COM-ORD-004
  - STATE-COM-ORD-005
crosses:
  - SVC-COM-ORD-orders
  - SVC-ACC-TRX-transactions
idempotency: >-
  Attempt sequence determines the Accounting key. Any pending attempt is resumed with its original data, while
  a payment after decline uses a new sequence and key.
concurrency: >-
  The order lock and unique key serialize attempt creation, but the remote payment occurs outside that lock.
  Split legs are sequential; payment outcomes and void still need guarded state recording.
hops:
  - 'n': 1
    actor_or_service: Orders route
    action: >-
      Authorize the caller and payment state, resume existing work, ensure billing and provisional issue, and
      reconcile any Accounting tax discrepancy.
    anchor: 'services-commerce:modules/orders/services/tender/tender-order.ts:tenderOrder'
    seam: sync
    on_failure: 'Invalid payment state, elapsed deadline, missing invoice or tax mismatch stops a new attempt.'
    left_inconsistent: No new attempt has been recorded.
    observer: Observed through the requesting buyer or staff member.
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#refuses a second tender of the
      accepted order, 409 order_not_tenderable
  - 'n': 2
    actor_or_service: Orders route
    action: >-
      Validate method, instrument, amount and policy limits, then request merchant-account eligibility for
      business unit, currency and method.
    anchor: 'services-commerce:modules/orders/services/accounting/merchant-account-eligibility.ts'
    seam: sync
    on_failure: >-
      Validation refuses before recording; unavailable eligibility is logged and permits the attempt to
      continue.
    left_inconsistent: Validation leaves no partial attempt.
    observer: Observed through the requesting buyer or staff member.
    provenance: observed
    source: 'services-commerce:modules/orders/services/tender/tender-refusals.ts'
  - 'n': 3
    actor_or_service: Orders persistence
    action: 'Store the keyed, sequenced pending attempt and mark it submitted before dispatch.'
    anchor: 'services-commerce:modules/orders/services/persistence/orders.ts:recordTender'
    seam: sync
    on_failure: Database failure stops dispatch to Accounting.
    left_inconsistent: No remote charge was requested by the failed recording.
    observer: Observed through sale history (tender recorded).
    provenance: observed
    source: 'services-commerce:modules/orders/services/persistence/orders.ts:recordTender'
  - 'n': 4
    actor_or_service: Accounting
    action: >-
      Request allocated payment for card, bank or offline methods; use credits and any card remainder for
      settlement; convert provisional invoices for terms, preserving the purchase-order reference.
    anchor: 'services-commerce:modules/orders/services/accounting/accounting-api.ts'
    seam: sync
    on_failure: >-
      Decline permits a later attempt; unanswered or unresolved requests place the sale in payment
      uncertainty.
    left_inconsistent: A remote payment may exist before Commerce knows its outcome.
    observer: Observed through the requesting buyer or staff member (declined or uncertain answer); sale history.
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#answers uncertain, the order
      tender_uncertain, the attempt uncertain naming Accounting’s intent
  - 'n': 5
    actor_or_service: Orders
    action: >-
      Persist the answer, accepting when successful legs cover the required amount, then evaluate gates,
      refresh the mirror and ensure any deposit schedule.
    anchor: 'services-commerce:modules/orders/services/orders/accept-order.ts:acceptOrder'
    seam: sync
    on_failure: Follow-up failures are logged and recoverable register or mirror work waits for its pass.
    left_inconsistent: Acceptance can precede current delivery gates or mirror figures.
    observer: Observed through the sale detail screen; recovery-pass logs.
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#tells the story on the
      history: placed, billed, the tender recorded, submitted and resolved, the transition to accepted
  - 'n': 6
    actor_or_service: Uncertain-payment sweep
    action: >-
      Resume unresolved attempts from Accounting intent or order payments each minute, escalating after
      fifteen minutes.
    anchor: 'services-commerce:modules/orders/services/tender/tender-order.ts:retryUncertainTender'
    seam: schedule
    on_failure: A failing order does not stop the pass; no transport means no processing.
    left_inconsistent: Uncertainty continues to block voiding until a definitive answer arrives.
    observer: Observed through tender-uncertain exception; recovery-pass log.
    provenance: observed
    source: 'services-commerce:modules/orders/services/orders/financial-sweeps.ts:sweepFinancials'
branches:
  - Portal collection respects a single-payment restriction; staff can collect in separate legs.
  - >-
    Later installment collection uses the same tender boundary with installment classification and the stored
    payment method.
waits:
  - A declined collection can be attempted again until expiry causes void.
evidence:
  - >-
    services-commerce at c8b66a98: modules/orders/aws/api/tenders.routes.ts; services/tender/*.ts;
    services/accounting/*.ts; services/orders/accept-order.ts, financial-sweeps.ts;
    tests/e2e/billing-and-tender.e2e.spec.js.
  - >-
    react-console at baf6dae3: components/commerce/order-flows/take-payment-dialog.tsx;
    lib/commerce/order-flows/live.ts.
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-DAT-004, 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]
---

# Take a payment and settle an uncertain one

## What It Does

Payment records a keyed attempt, asks Accounting for the money movement and resolves the resulting sale state. Recovery preserves unresolved attempts rather than making a competing charge.

## The Flow

```mermaid
sequenceDiagram
  participant C as Clerk or buyer
  participant O as Orders
  participant X as Accounting
  participant S as Uncertain-payment sweep
  C->>O: pay (kind, amount, instrument)
  O->>O: resume open attempt, or bill first, check policy
  O->>O: record attempt (key, sequence)
  O->>X: payment, settlement or convert (key)
  alt succeeded and covered
    O->>O: accept order, gates, mirror
  else declined
    O-->>C: declined, try again
  else lost
    O->>O: order uncertain
    S->>X: resume under the same key (every minute)
  end
```

## When Something Fails

Decline permits another attempt within the deadline. Lost answers retain uncertainty and are revisited using the original attempt, with escalation after fifteen minutes. Acceptance remains committed when gate or mirror follow-ups fail. Financial reversal uses separate void or change settlement.

## Open Design Questions

The organization's payer behavior still relies on Accounting's stated contract rather than integrated payment proof.
