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 isneeds_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 amountThe processor took the money back. Debit wallet:available, the unused creditsFor a disputed top-up, the credits not yet used come back out of the wallet. Debit chargeback_losses, the restWhat the customer already used, or a sale that wasn't credits. Debit processor_fees/ creditprocessor_clearingThe 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.createdgoes to your webhook endpoints, andwallet.frozenfor 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 aswonwith 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), anddispute.updatedgoes 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, creditchargeback_losses), and the credits taken back return to the wallet asrefund_reversalgrants 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
elevatedwith 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.