---
id: WF-ACC-TRX-011
title: Void or reverse a payment and follow its disputes
trigger: >-
  Staff or processor outcomes initiate receipt cancellation, bank return or
  dispute resolution.
product_area: accounting
module: transactions
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-ACC-TRX-013
moves:
  - STATE-ACC-TRX-007
  - STATE-ACC-TRX-006
  - STATE-ACC-TRX-001
crosses:
  - SVC-ACC-TRX-transactions
hops:
  - 'n': 1
    actor_or_service: Payment reversal
    action: >-
      Check receipt eligibility, reversal behavior, explanation, source-credit
      use and absence of another nonfailed reversal under lock.
    anchor: >-
      services-accounting:modules/transactions/services/payments/payment-reverse.ts:reversePayment
    seam: sync
    on_failure: Reject the command and undo its transaction.
    left_inconsistent: The complete transaction is undone.
    observer: The API response reports the outcome and applicable refusal code.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/payments/payment-reverse.ts:reversePayment;
      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)
  - 'n': 2
    actor_or_service: Integration Platform gateway
    action: >-
      Commit a processing cancellation before calling the provider with the
      reversal key.
    anchor: >-
      services-accounting:modules/transactions/services/payments/payment-reverse.ts:resolveVoidWithProcessor
    seam: sync
    on_failure: >-
      A settled charge cannot be cancelled; a refund is the supported return
      path.
    left_inconsistent: The electronic cancellation remains unresolved.
    observer: The receipt record and recovery worker expose cancellation progress.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/payments/payment-reverse.ts:resolveVoidWithProcessor;
      services-accounting:modules/transactions/tests/integration/services/payments/payment-reversals.integration.spec.js#it
      fails a void the processor says is already settled (payment_settled): the
      reversal failed, the payment untouched
  - 'n': 3
    actor_or_service: Payment reversal
    action: >-
      Complete return by negating allocations, restoring billed debt, crediting
      applicable fees and recording financial and reconciliation effects.
    anchor: >-
      services-accounting:modules/transactions/services/payments/payment-reverse.ts:recordVoidOutcome
    seam: sync
    on_failure: Undo all work in the transaction.
    left_inconsistent: The complete transaction is undone.
    observer: The API response reports the outcome and applicable refusal code.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/payments/payment-reverse.ts:recordVoidOutcome;
      services-accounting:modules/transactions/tests/integration/services/payments/payment-reversals.integration.spec.js#it
      records the void’s settlement item beside the capture: kind void, minus
      2000
  - 'n': 4
    actor_or_service: Disputes
    action: >-
      Open an eligible dispute and close it once; an adverse chargeback outcome
      reverses the full receipt atomically.
    anchor: >-
      services-accounting:modules/transactions/services/payments/payment-reverse.ts:closeDispute
    seam: sync
    on_failure: Reject a final dispute or an amount above the receipt total.
    left_inconsistent: The complete transaction is undone.
    observer: The API response reports the outcome and applicable refusal code.
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/payments/payment-reverse.ts:closeDispute;
      services-accounting:modules/transactions/tests/integration/services/payments/dispute-inquiry-lost.integration.spec.js#it
      writes no payment reversal and leaves the payment succeeded, nothing
      reversed
idempotency: >-
  Staff commands use request keys; event-driven commands use event-derived keys
  and consumption markers.
concurrency: >-
  The database limits nonfailed reversals and requires final removal of live
  allocations.
branches:
  - An adverse inquiry closes the dispute without returning the receipt money.
waits: []
evidence:
  - >-
    services-accounting at f47cb263: services/payments/payment-reverse.ts,
    payment-allocate.ts (voidPayment); services/settlements/card-fees.ts
    (creditCardFeeInvoice).
controls: [TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, 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-CRY-001, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-AVL-001, 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-VEN-001, TC-VEN-002, TC-VEN-003, TC-PRV-001, TC-PRV-002]
---
# Void or reverse a payment and follow its disputes

## What It Does

Receipt reversal explains collected value that no longer stands. Dispute outcome and money outcome remain distinct, especially for inquiries.

## The Flow

```mermaid
flowchart TD
  h0["Payment reversal"]
  h1["Integration Platform gateway"]
  h0 --> h1
  h2["Payment reversal"]
  h1 --> h2
  h3["Disputes"]
  h2 --> h3
```

The numbered hops identify the participating services, synchronization boundary and evidence. Branch conditions in the frontmatter explain where preparation, completion and recovery diverge.

## When Something Fails

Each hop records its rollback, retry or compensation boundary and the result visible to callers or operators. External outcomes can remain unresolved after local preparation commits; the listed recovery behavior defines what remains pending.

## Open Design Questions

Partial chargeback behavior remains a product decision because the implemented reversal returns the full receipt.
