---
id: STATE-COM-ORD-006
title: Payment attempt
object: DOM-COM-ORD-002
product_area: commerce
module: orders
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
states:
  - name: pending
    meaning: The attempt and request key are stored before dispatch.
  - name: submitted
    meaning: The payment request has been sent and awaits resolution.
  - name: succeeded
    meaning: 'Accounting confirmed payment, settlement or conversion to terms.'
  - name: declined
    meaning: The attempt ended with a processor or Accounting refusal.
  - name: uncertain
    meaning: 'The final result is unknown, so recovery retains the original attempt.'
  - name: voided
    meaning: An available status with no current producer.
transitions:
  - from: pending
    to: submitted
    trigger: The recorded attempt proceeds to remote dispatch.
    guard: >-
      The eligible order has billing, required provisional issue and a valid policy-compliant instrument and
      amount within its deadline.
    side_effects:
      - append attempted-payment history
    who: 'Staff, portal buyer or the uncertain-payment sweep'
    provenance: observed
    source: 'services-commerce:modules/orders/services/tender/tender-order.ts:tenderOrder'
  - from: submitted
    to: succeeded
    trigger: Accounting confirms the money movement.
    guard: The successful response determines the outcome.
    side_effects:
      - accept when successful legs satisfy the required amount
      - derive and persist the latest financial projection
    who: System
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#accepts the order on the leg
      that completes the total (08 row 14), the first leg captured
  - from: submitted
    to: declined
    trigger: Accounting or the processor reports a declined outcome.
    guard: The refusal response determines the outcome.
    side_effects:
      - preserve placed status and invoice for a later payment
    who: System
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#answers 200 declined with the
      processor’s code, the order still placed with its pro forma, the attempt declined
  - from: submitted
    to: uncertain
    trigger: The request loses its answer or the intent remains unresolved.
    guard: The incomplete response determines uncertainty.
    side_effects:
      - set the sale to unresolved-payment processing
    who: System
    provenance: observed
    source: 'services-commerce:modules/orders/services/tender/tender-order.ts'
  - from: uncertain
    to: succeeded
    trigger: Recovery identifies the original successful payment.
    guard: The same-key result confirms capture.
    side_effects:
      - retain the original payment rather than create another charge
    who: 'Buyer, staff or the uncertain-payment sweep'
    provenance: test
    source: >-
      services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#accepts the order once
      Accounting holds the payment, with one charge and the payment on the attempt
  - from: uncertain
    to: declined
    trigger: Recovery identifies a declined original attempt.
    guard: The original attempt resolves without captured money.
    side_effects:
      - return the sale to placed processing
    who: 'Buyer, staff or the uncertain-payment sweep'
    provenance: observed
    source: 'services-commerce:modules/orders/services/tender/tender-order.ts'
invalid:
  - from: declined
    to: submitted
    why: A different payment instrument after decline starts a new attempt and key.
  - from: succeeded
    to: declined
    why: Reversal creates financial refund work rather than relabeling captured payment as declined.
concurrency: >-
  The order lock and unique keys protect attempt recording. The uncertain-payment pass runs every minute and
  escalates unresolved attempts after fifteen minutes. Voided is declared without a current writer.
invariants:
  - INV-DOM-COM-ORD-002-07
  - INV-DOM-COM-ORD-002-12
evidence:
  - >-
    services-commerce at c8b66a98: modules/orders/db/order-tenders.table.ts; services/tender/tender-order.ts,
    tender-refusals.ts, tender-kinds-of-profile.ts; services/persistence/orders.ts (recordTender,
    resolveTender).
---

# Payment attempt

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> pending: recorded
  pending --> submitted: Accounting called
  submitted --> succeeded
  submitted --> declined
  submitted --> uncertain: answer lost
  uncertain --> succeeded: resumed, found
  uncertain --> declined: resumed, not captured
```

## Transitions Explained

An attempt records its identity and request key before calling Accounting. The answer resolves success, decline or uncertainty. Recovery resumes unresolved work under the original key; a declined attempt leaves the order available for a new payment.

## What Cannot Happen

An open attempt excludes a competing payment instrument. Declined attempts need a new sequence, and refunds reverse successful payments without rewriting them as declined. Commerce retains no card numbers.

## Concurrency and Timing

The order lock and unique keys protect attempt recording. The uncertain-payment pass runs every minute and escalates unresolved attempts after fifteen minutes. Voided is declared without a current writer.
