# Disputes

> When a customer's bank reverses a payment, Ownrecord books the chargeback and the fee when the money is taken, freezes the customer's wallets, alerts support, and builds the evidence pack you submit to the processor. Inquiries take nothing until they escalate. Won disputes are reversed; lost ones raise the customer's risk.

A **dispute** (a chargeback) starts when a cardholder asks their bank to reverse a payment. The bank takes the money back through your payment processor, usually with a dispute fee, and gives you a deadline to respond with evidence. As the seller of record you carry this risk: Ownrecord books it in your ledger, tells your team, and prepares the evidence from what it recorded when the sale happened.

Disputes belong to the brand of the disputed payment and to its mode: test-mode disputes come from the fake processor's dispute cards, live ones from your processor's webhooks.

## When a dispute opens

The processor's `dispute.created` webhook does this in one step:

- **The dispute** is recorded with its amount, the processor's reason (for example `fraudulent`), the dispute fee and the deadline to respond (`evidenceDueBy`). Its status is `needs_response`.

- **The customer's wallets are frozen**, unless you turned that off in the brand's settings (`policies.disputeWalletFreeze`, on by default). Frozen wallets take no new reservations or leases; credits still arrive.

- **The chargeback is posted** to the ledger when the processor takes the money: for a regular dispute at once, effective when the processor reported it (an inquiry posts nothing, see below):

  | Entry                                                | Why                                                                          |
  | ---------------------------------------------------- | ---------------------------------------------------------------------------- |
  | Credit `processor_clearing`, the disputed amount     | The processor took the money back.                                           |
  | Debit `wallet:available`, the unused credits         | For a disputed top-up, the credits not yet used come back out of the wallet. |
  | Debit `chargeback_losses`, the rest                  | What the customer already used, or a sale that wasn't credits.               |
  | Debit `processor_fees` / credit `processor_clearing` | The dispute fee, when the processor reports one in the dispute's currency.   |

  Every posting links the dispute, the payment and the customer, so reconciliation and reports can follow it.

- **The payment** becomes `disputed`.

- **Support is alerted** (`DISPUTE_CREATED`, high: support, finance and owners), with a link to the dispute's page.

- **`dispute.created`** goes to your webhook endpoints, and `wallet.frozen` for each frozen wallet.

## Inquiries

An **inquiry** (Stripe's `warning_needs_response`) is a bank asking about a payment before it decides to reverse it. No money is taken, so Ownrecord books nothing: the processor clearing account mirrors the processor's balance. The inquiry is recorded as a dispute with `inquiry: true`, support is alerted and the wallets are frozen as for a chargeback, and you can answer it with the evidence pack.

- If the bank lets it go (`warning_closed`), the dispute closes as `won` with no ledger effect, and the wallets are unfrozen.
- If the bank escalates it to a chargeback, the processor takes the money and sends `dispute.funds_withdrawn`: the chargeback (with the fee) is posted then, the dispute becomes a regular one (`inquiry: false`, `needs_response`, with the new deadline), and `dispute.updated` goes to your endpoints. Evidence you submitted for the inquiry has to be built and submitted again.

For a regular dispute the processor sends `dispute.funds_withdrawn` too; the chargeback was posted at `dispute.created` and isn't posted again. `fundsWithdrawnAt` on the dispute says when the money was taken.

## The evidence pack

On the dispute's page, **Build evidence pack** collects what Ownrecord recorded about the sale into one PDF:

| Section                 | From                                                                                              |
| ----------------------- | ------------------------------------------------------------------------------------------------- |
| Invoice                 | The payment's invoice or receipt; its issued PDF is sent along as the receipt.                    |
| IP country              | The IP country (and truncated network) captured at checkout, with the billing and card countries. |
| Usage                   | The customer's usage since the payment, per meter, and the credits it used.                       |
| Terms acceptance        | When the customer accepted the terms at checkout.                                                 |
| Sign-in history         | The customer's sign-ins to the customer portal, when there are any.                               |
| Withdrawal-right waiver | For EU and UK consumers: the express consent to immediate performance, with its text version.     |

A section with nothing recorded says so. Preview the PDF, build it again if something changed, then **Submit evidence**: the pack's text, the PDF and the receipt go to the processor, which sends them to the bank. Evidence is submitted once, before the deadline; the dispute is then `under_review`.

Over the API: `POST /api/v1/disputes/{id}/evidence` builds the pack, `GET /api/v1/disputes/{id}/evidence` returns its content, and `POST /api/v1/disputes/{id}/submit_evidence` submits it. A processor without a dispute evidence API refuses the submission (`dispute_evidence_unsupported`): download the PDF and submit it in the processor's dashboard.

## When a dispute closes

The processor's `dispute.closed` webhook records the outcome:

- **Won**: the withdrawal, if there was one, is reversed (debit `processor_clearing`, credit `chargeback_losses`), and the credits taken back return to the wallet as `refund_reversal` grants with their original expiry. Credits whose grant expired in the meantime go where their expiry would have put them (breakage, under the brand's breakage policy). The dispute fee isn't reversed. The payment's status goes back to what it was, and the wallets the dispute froze are unfrozen once no other dispute of the customer is open.
- **Lost**: the chargeback stays (it's posted now if the processor never reported the withdrawal: a lost dispute's money is gone), the wallets stay frozen, and the customer's risk becomes `elevated` with the dispute as the reason (`customer.updated`).

Either way, `dispute.closed` goes to your webhook endpoints. Redelivered webhooks change nothing: each dispute is recorded once per processor dispute, and its postings once.

## Who does what

Support handles disputes (`disputes:write`: build and submit the evidence, assign, notes); finance and viewers can read them. Submitting evidence is a financial operation for agents and apps, so your approval policies apply. Notes are for your team and are never sent to the processor.
