---
id: docs.disputes
title: "Disputes"
canonical: https://docs.secureprocessing.app/disputes
description: "What happens when a cardholder charges back, how the money moves, and how to answer it in time."
last_verified: 2026-11-06
---

# Disputes

A dispute is a cardholder telling their own bank to take a payment back. The money leaves your balance while the case is decided, you answer it with evidence, and the card network decides. This page is honest about the part of that which is done by hand.

## How a dispute reaches you

Disputes are handled by hand. A chargeback arrives here as an email from the bank with a case reference, and somebody at Secure Processing reads it and records it. It is worth knowing because it decides the timings below.

When that happens you get a `dispute.created` webhook, and an email with the deadline in the subject line goes to your account's owner, who cannot turn it off, and by default to everyone else on your team who can answer disputes. The dispute also appears in your dashboard under Disputes, and the payment it came from has `disputed: true`.

> **Note:** You cannot create a dispute yourself, and there is no `POST /v1/disputes`. A chargeback is something the card network asserted; a business declaring one about its own payment would be moving its own money into reserve and back out again.

## An inquiry is not a chargeback

Sometimes the cardholder’s bank asks a question before taking anything — a retrieval request. Those arrive with a status beginning `warning_`, and **no money is held**. Answer it well and it may never become a chargeback.

If the network escalates it anyway, the same dispute moves from `warning_needs_response` to `needs_response`, the money is held at that moment, and you get a `dispute.funds_withdrawn` event. It is never a second dispute.

| Status | What it means |
|---|---|
| warning_needs_response | An inquiry. Nothing has been taken. Answer it. |
| warning_under_review | Your answer to an inquiry is with the bank. |
| warning_closed | The inquiry ended. No money moved at any point. |
| needs_response | A chargeback. The amount is out of your balance and evidence is due. |
| under_review | Your evidence is with us and on its way to the bank. |
| won | The bank found for you. The held amount is back in your balance. |
| lost | The bank found for the cardholder. The money stays gone. |

## What happens to the money

Opening a chargeback moves the disputed amount out of your **available** balance and into a reserve. Winning moves it back; losing writes it off. Every step is a balance transaction you can see, and the ids are on the dispute object.

| When | What moves | On your statement |
|---|---|---|
| The dispute is opened | The disputed amount leaves your available balance | a dispute line, negative |
| You win | The same amount comes back | a dispute_reversal line, positive |
| You lose | Nothing further — it left at the start | no extra line, by design |
| A handling fee is charged | The fee leaves your available balance | a dispute line: amount 0, fee positive (what we charged, as on a charge), net negative |

> **Note:** 🔴 **Your available balance can go negative.** A chargeback usually arrives weeks after the payment, by which time you have been paid out — so there is nothing left to take, and the balance goes below zero. That is not an error; it is the amount you owe us. No further payout is made until your takings bring it back above zero.

The amount in the ledger is in Belize dollars at the rate the payment was taken at, which is why the dispute object carries both `amount` (the payment's currency) and `settlement_amount` (BZD).

## Answering it

Evidence uses Stripe’s field names, so a library or a habit you already have will fit. Fields merge — sending the shipping section does not erase the receipt you sent yesterday — and sending `null` clears one.

```bash
curl https://api.secureprocessing.app/v1/disputes/dp_4fH7jK9mN2pQ5rT8vX1zA3bC \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "evidence": {
      "shipping_carrier": "DHL",
      "shipping_tracking_number": "CP123456789BZ",
      "product_description": "One dive mask, collected in store"
    }
  }'
```

The file fields — `receipt`, `shipping_documentation`, `customer_communication` and the rest — take a `file_` id. Uploading a file is session-only, so attach documents from the dashboard: they are often invoices naming a customer or a signed delivery note, and an API key is a long-lived credential in an environment variable.

When you are ready, send it. You can do this in the same call:

```bash
curl https://api.secureprocessing.app/v1/disputes/dp_4fH7jK9mN2pQ5rT8vX1zA3bC \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{ "submit": true }'
```

> **Note:** ⚠️ **Submission is final, and it does not mean the bank has it yet.** There is no system at the bank to post a bundle to, so a person here forwards it. Submitting freezes the evidence — the bundle they read has to be the bundle your record shows — and you will hear the outcome when the bank answers, which is their timeline and not ours.

## The deadline

`evidence_details.due_by` comes from the cardholder’s bank and cannot be extended. A dispute with no answer is lost by default, so this is the one field on the object worth alerting on.

We email the owner, and by default everyone else on your team who can answer disputes, three days before the deadline and again the day before. We stop there: a third email on the morning it expires would arrive too late to act on. After the deadline the reminders stop and a person here chases the bank instead.

## Accepting one

If you are not going to contest a dispute, say so and we will stop asking:

```bash
curl -X POST https://api.secureprocessing.app/v1/disputes/dp_4fH7jK9mN2pQ5rT8vX1zA3bC/close \
  -H "Authorization: Bearer sk_test_..."
```

The method is called `close` because that is what Stripe calls it, and it means the same thing: you accept the loss. It moves no money on its own and it does not mark the dispute lost — the network has not decided yet, and we will not debit you ahead of them. A chargeback becomes `under_review`, an inquiry `warning_under_review`, and no further evidence is accepted.

You can accept only while the dispute is waiting for your response. Once you have submitted evidence the case is already with the bank, and accepting answers `400` and changes nothing. If you decide to concede after submitting, email support with the dispute id and we will tell the bank.

## Events

| Event | When |
|---|---|
| dispute.created | A chargeback or an inquiry was raised. The deadline is in evidence_details. |
| dispute.funds_withdrawn | The amount left your available balance. An inquiry does not fire this. |
| dispute.updated | Evidence saved or submitted, you accepted, or an inquiry escalated. |
| dispute.funds_reinstated | You won and the money is back. |
| dispute.closed | The bank answered. status is won, lost, or warning_closed. |

## Fees

A lost chargeback may carry a handling fee, charged to your available balance as its own balance transaction. It is not automatic and it is not a percentage: somebody decides it, it is on the dispute as `dispute_fee`, and the reason is in `outcome_note`. There is never a fee on a dispute you won.
