---
id: DOM-ACC-TRX-003
title: Payment
realises: CON-ACC-TRX-003
product_area: accounting
module: transactions
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-ACC-TRX-transactions
lifecycle: STATE-ACC-TRX-006
custom_fields: none
identity: >-
  Each receipt receives a time-ordered workspace identity and payment sequence
  number, beginning at one million. Processor collection first creates an intent
  whose identity supplies the gateway retry key. Related refund, reversal,
  dispute, settlement and remittance records retain separate identities.
attributes:
  - name: customer
    kind: reference
    required: true
    computed: false
    notes: Names the customer whose debts this receipt may settle and remains fixed.
  - name: payer
    kind: reference
    required: false
    computed: false
    notes: >-
      Identifies the sender separately from the customer without extending
      payment eligibility.
  - name: 'business unit, currency and amount'
    kind: money
    required: true
    computed: false
    notes: Records a positive receipt in an enabled unit currency and remains fixed.
  - name: payment method and behaviour
    kind: reference
    required: true
    computed: false
    notes: Preserves the selected method and its collection behavior at receipt time.
  - name: cash destination
    kind: reference
    required: true
    computed: false
    notes: >-
      Identifies the matching bank account for offline receipts or merchant
      account for processor receipts.
  - name: 'reference, memo and notes'
    kind: text
    required: false
    computed: false
    notes: >-
      Holds editable receipt descriptions while retaining any mandatory
      reference.
  - name: payment and accounting dates
    kind: date
    required: true
    computed: false
    notes: >-
      Uses today's date by default for offline receipts and requires an open
      accounting period.
  - name: status
    kind: enum
    required: true
    computed: true
    notes: >-
      Represents successful collection, bank clearing, refund progress or a
      completed reversal.
  - name: maintained amounts
    kind: money
    required: true
    computed: true
    notes: >-
      Tracks allocation, refund, reversal and credit movements, with remaining
      money calculated by the database.
  - name: processor and references
    kind: text
    required: false
    computed: false
    notes: >-
      Retains provider references needed for recovery without storing the
      payment instrument token.
  - name: intent
    kind: collection
    required: false
    computed: false
    notes: >-
      Explains collection progress and keeps lookup and human-review information
      on the committed attempt.
  - name: allocations
    kind: collection
    required: false
    computed: false
    notes: >-
      Places receipt money on invoice lines through retained entries and their
      explicit opposite entries.
  - name: reversals
    kind: collection
    required: false
    computed: false
    notes: >-
      Describes cancellation, return or chargeback, allowing only one nonfailed
      reversal.
  - name: disputes
    kind: collection
    required: false
    computed: false
    notes: Tracks an inquiry or chargeback from opening through its final outcome.
  - name: refunds · lines
    kind: collection
    required: false
    computed: false
    notes: >-
      Describes money returned from receipt balances, invoice allocations or
      customer credit.
  - name: settlement
    kind: reference
    required: false
    computed: false
    notes: >-
      Links the coordinated settlement to this receipt, its intent and credit
      applications.
  - name: remittance
    kind: reference
    required: false
    computed: false
    notes: >-
      Identifies the group receipt that produced the member payment or remitter
      remainder.
  - name: card-fee invoice
    kind: reference
    required: false
    computed: true
    notes: Links the additional card charge to the invoice created for it.
  - name: settled at
    kind: timestamp
    required: false
    computed: false
    notes: >-
      Records bank clearing, after which the capture is ready for
      reconciliation.
relationships:
  - to: DOM-ACC-TRX-001
    cardinality: many-to-many through allocations
    ownership: >-
      The receipt owns allocation and refund records; the invoice retains
      ownership of its billed lines.
    cross_service: false
  - to: DOM-ACC-TRX-004
    cardinality: one-to-many
    ownership: >-
      The independent credit record draws from this receipt and restores that
      money on void.
    cross_service: false
  - to: DOM-ACC-TRX-005
    cardinality: many-to-one
    ownership: >-
      The customer account reads remaining receipt money as a negative open
      item.
    cross_service: false
  - to: DOM-ACC-TRX-006
    cardinality: one-to-one
    ownership: >-
      Receipt-related documents each implement the common transaction-record
      structure.
    cross_service: false
invariants:
  - id: INV-DOM-ACC-TRX-003-01
    statement: >-
      A receipt requires a positive amount denominated in a currency enabled for
      its business unit.
    enforced_at:
      - api
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/receive-offline.integration.spec.js#it
      refuses an amount in another currency (currency_mismatch)
  - id: INV-DOM-ACC-TRX-003-02
    statement: >-
      Offline collection requires a bank account matching the receipt's unit and
      currency.
    enforced_at:
      - api
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/receive-offline.integration.spec.js#it
      refuses a bank account of another unit (cash_account_mismatch)
  - id: INV-DOM-ACC-TRX-003-03
    statement: Receipt numbering begins at one million and allows gaps.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/receive-offline.integration.spec.js#it
      numbers the tenant’s first payment 1,000,000, succeeded, in the bank
      account and the unit’s batch
  - id: INV-DOM-ACC-TRX-003-04
    statement: >-
      Recorded collection method, behavior, amount, customer, payer and
      destination cannot be replaced.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/payment-methods.integration.spec.js#it
      refuses any other writer a change of a payment’s method (the write-once
      trigger, RHF01)
  - id: INV-DOM-ACC-TRX-003-05
    statement: >-
      Allocated, refunded, reversed, credited-out and unapplied amounts
      partition the receipt, with nonnegative unapplied money and pending
      refunds bounded by it.
    enforced_at:
      - database
    provenance: documented
    source: >-
      services-accounting:docs/architecture/accounting-2.0/06-integrity-model.md#2.
      Generated balances with CHECK bounds
  - id: INV-DOM-ACC-TRX-003-06
    statement: >-
      Collection commits its intent before charging and uses that attempt
      identity to prevent duplicate charging and duplicate recorded payments.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/tender.integration.spec.js#it
      resolves the intent succeeded, naming the payment, claimed and resolved,
      with the batch chosen at initiation
  - id: INV-DOM-ACC-TRX-003-07
    statement: >-
      Recording captured money caps allocations at the debt then remaining and
      retains any excess on the receipt.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/tender.integration.spec.js#it
      is capped at what the line owes then and the rest stays unapplied: the
      charged money is never refused
  - id: INV-DOM-ACC-TRX-003-08
    statement: >-
      Allocation targets must be eligible issued lines for the receipt's
      customer, unit and currency.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/customer-guard.integration.spec.js#it
      refuses allocating unapplied money to another customer’s invoice, leaving
      the payment unapplied
  - id: INV-DOM-ACC-TRX-003-09
    statement: >-
      Concurrent allocation cannot exceed either the line debt or the receipt's
      spendable money.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/allocate.integration.spec.js#it
      serialize, and the second is refused by the database’s balance CHECK, not
      by code
  - id: INV-DOM-ACC-TRX-003-10
    statement: >-
      Undoing an allocation appends an opposite entry referencing the retained
      original.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/allocate.integration.spec.js#it
      refuses an UPDATE of an allocation row
  - id: INV-DOM-ACC-TRX-003-11
    statement: >-
      Only one nonfailed payment reversal is allowed and a reversed receipt
      retains no live allocations.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/payment-reversals.integration.spec.js#it
      refuses reversing it again (payment_not_live) and replays the same key as
      the same reversal
  - id: INV-DOM-ACC-TRX-003-12
    statement: >-
      A payment-backed credit still in use prevents reversal of its source
      receipt.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/payment-reversals.integration.spec.js#it
      refuses a payment with a credit made from it that is not void
      (payment_has_credit)
  - id: INV-DOM-ACC-TRX-003-13
    statement: >-
      Refund requests reserve their source money within its available amount
      until payment, cancellation or failure.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refund-reservation.integration.spec.js#it
      refuses allocating the reserved money (over_application) but allocates
      money beyond it
  - id: INV-DOM-ACC-TRX-003-14
    statement: >-
      Where approval is configured, the refund requester cannot approve the same
      refund.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refunds.integration.spec.js#it
      requests it pending_approval, refusing to execute it
      (refund_not_requested) or to let the requester approve it (self_approval)
  - id: INV-DOM-ACC-TRX-003-15
    statement: Payment or cancellation closes the refund lifecycle.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/refunds/refunds.integration.spec.js#it
      refuses executing it again (refund_not_requested) and cancelling it
      (refund_not_cancellable)
  - id: INV-DOM-ACC-TRX-003-16
    statement: >-
      Settlement holds selected credit pending its outcome and releases the
      reservation on failure.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/settlements/settlements.integration.spec.js#it
      refuses with the decline (processor_declined), the settlement failed with
      the code, the reservation released, nothing applied
  - id: INV-DOM-ACC-TRX-003-17
    statement: >-
      A group receipt reconciles its total to member lines and any explicitly
      stated remainder.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/remittances/remittance-refusals.integration.spec.js#it
      refuses a remainder left unstated: the total of 200.00 over a line of
      180.00 is a mismatch, not an inferred remainder
  - id: INV-DOM-ACC-TRX-003-18
    statement: >-
      Opening a dispute requires an eligible processor receipt and an amount
      within its total; closure is final.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/payment-reversals.integration.spec.js#it
      refuses closing a closed dispute (dispute_not_open), a dispute of a check
      (reversal_kind_mismatch) and an amount beyond the payment
  - id: INV-DOM-ACC-TRX-003-19
    statement: >-
      Card capture is eligible for reconciliation immediately, while a bank
      capture becomes eligible on clearing.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/payments/tender.integration.spec.js#it
      records the capture as one eligible settlement item keyed
      payment:<id>:capture, on Stripe’s timing (the account names no processor)
  - id: INV-DOM-ACC-TRX-003-20
    statement: >-
      Receipt-related tables supply no custom-field storage and the module
      registration does not declare that capability.
    enforced_at:
      - api
      - service
    provenance: documented
    source: >-
      services-accounting:docs/milestones/plans/ACCT-M2-plan.md#7a. Entity
      capabilities (R2-ARCH-001)
physical:
  - payments
  - payment_intents
  - payment_allocations
  - payment_reversals
  - payment_events
  - disputes
  - refunds
  - refund_lines
  - settlements
  - remittances
  - remittance_lines
  - stripe_customers
  - stripe_settings
  - payments_v
  - refunds_v
evidence:
  - >-
    services-accounting at f47cb263: modules/transactions/db/payments.table.ts,
    payment-intents.table.ts, payment-allocations.table.ts,
    payment-reversals.table.ts, payment-events.table.ts, disputes.table.ts,
    refunds.table.ts, refund-lines.table.ts, settlements.table.ts,
    remittances.table.ts, remittance-lines.table.ts, payment-vocabularies.ts;
    services/payments/*, refunds/*, settlements/*, remittances/*.
  - >-
    services-accounting at f47cb263:
    docs/architecture/accounting-2.0/02-decisions.md (D-01, M2-1 to M2-12, A-8,
    A-9, A-13, A-17; §2.11 D-01 to D-10), 05-lifecycles.md §2, §4, §5;
    docs/milestones/plans/ACCT-M2-plan.md §7a.
---
# Payment

## What It Models

Payment describes a receipt, how it was collected and how the resulting money was used. Its supporting records explain processor attempts, allocations, returns, disputes and coordinated collection.

## Identity and Attributes

The original collection details remain attached to the receipt. Maintained amounts describe subsequent use, while processor references and intent records support recovery of uncertain collection outcomes.

## Relationships

Allocations connect receipts to invoice debt, and payment-backed credit transfers remaining receipt value into a separate credit record. Refunds and reconciliation movements explain money returned or cleared.

## Invariants

Database bounds protect the financial amounts and ledger entries. Service commands establish collection eligibility, approval requirements and the permitted form of reversal.

## How It Is Stored and Shared

Transactions owns receipt-related records. Staff access uses the corresponding record permissions; Commerce uses its tender and reversal service capabilities. Integration events and scheduled lookups supply processor outcomes.

## Open Design Questions

Partial chargebacks, external refund reasons and the broader multi-customer receipt model remain unresolved. The implemented payment recommendations still require Andrew’s approval.
