> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paynext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Disputes

> Track chargebacks and retrieval requests across processors with one dispute object, the disputes API, and dispute webhooks.

When a cardholder or their issuing bank contests a charge, PayNext records it as a dispute and links it to the payment it was raised against. Disputes from supported processors arrive in the same shape, with the same stages, statuses, and reason categories, so you can track response deadlines and outcomes in one place.

A payment can carry more than one dispute over its lifetime.

## The dispute object

```json theme={"system"}
{
  "id": "dsp_7c1a2b3c-4d5e-6f70-8a9b-0c1d2e3f4a5b",
  "payment_id": "pay_e8a1b2c3-d4f5-6789-abcd-ef0123456789",
  "external_id": "dp_1Nx2yZAbCdEfGh",
  "stage": "DISPUTE",
  "status": "NEEDS_RESPONSE",
  "reason": "FRAUDULENT",
  "disputed_at": "2026-08-01T10:15:00Z",
  "respond_by": "2026-08-15T23:59:59Z",
  "details": {
    "processor_reason_code": "fraudulent",
    "network_reason_code": "10.4"
  },
  "created_at": "2026-08-01T10:20:00Z",
  "updated_at": "2026-08-01T10:20:00Z"
}
```

| Field | Description |
| :- | :- |
| `id` | PayNext dispute ID, in the format `dsp_` + UUID. |
| `payment_id` | ID of the disputed payment, in the format `pay_` + UUID. |
| `external_id` | The dispute identifier assigned by the processor. |
| `stage` | Where the dispute sits in the network's process. See [Dispute stages](#dispute-stages). |
| `status` | The dispute's current status. See [Dispute statuses](#dispute-statuses). |
| `reason` | The reason category, normalized across processors. See [Dispute reasons](#dispute-reasons). |
| `disputed_at` | When the dispute was raised. |
| `respond_by` | Deadline for your response. Omitted when the processor didn't supply one. |
| `resolved_at` | When the dispute first reached a final status. Omitted while the dispute is open. |
| `details` | Processor-specific reference values. See [Dispute details](#dispute-details). Included by `GET /disputes/{id}` and dispute webhooks, never by `GET /disputes`. Omitted when the processor supplied no details. |
| `created_at` | When the dispute was first recorded in PayNext. |
| `updated_at` | When the dispute was last updated in PayNext. |

Timestamps use ISO 8601. The dispute object has no amount or currency—read `amount` and `currency_code` from the disputed payment with `GET /payments/{id}`.

### Dispute details

`details` carries the processor's own values for reference. Which keys appear depends on the processor, and a key with no value is `null`.

| Key | Description |
| :- | :- |
| `processor_reason_code` | The processor's own reason value. `reason` holds the normalized category. |
| `network_reason_code` | The card network's reason code, for example `10.4` (Visa) or `4837` (Mastercard). |
| `is_visa_rdr` | Braintree only. `true` when the dispute was resolved automatically through [Visa Rapid Dispute Resolution](/guides/fraud-prevention/visa-rdr), otherwise `false`. |
| `paypal_status` | PayPal only. PayPal's own dispute status. |
| `paypal_dispute_life_cycle_stage` | PayPal only. PayPal's own life-cycle stage, for example `PRE_ARBITRATION`. |
| `paypal_dispute_channel` | PayPal only. PayPal's own dispute channel value. |
| `paypal_outcome_code` | PayPal only. PayPal's own outcome code. |

## Dispute stages

A dispute can start as a retrieval request and move to a formal dispute. The stage changes independently of the status.

<div className="block dark:hidden">
  ```mermaid theme={"system"}
  flowchart LR
      R(["※ Retrieval"]) --> D(["※ Dispute"])
      PA(["PayPal pre-arbitration"]) -.->|Reported as| D
      AR(["PayPal arbitration"]) -.->|Reported as| D

      style R fill:#f1f5f9,stroke:#64748b,color:#334155
      style D fill:#f1f5f9,stroke:#64748b,color:#334155
      style PA fill:#f3e8ff,stroke:#9333ea,color:#581c87
      style AR fill:#f3e8ff,stroke:#9333ea,color:#581c87
  ```
</div>

<div className="hidden dark:block">
  ```mermaid theme={"system"}
  flowchart LR
      R(["※ Retrieval"]) --> D(["※ Dispute"])
      PA(["PayPal pre-arbitration"]) -.->|Reported as| D
      AR(["PayPal arbitration"]) -.->|Reported as| D

      style R fill:#1e293b,stroke:#475569,color:#cbd5e1
      style D fill:#1e293b,stroke:#475569,color:#cbd5e1
      style PA fill:#3b0764,stroke:#9333ea,color:#e9d5ff
      style AR fill:#3b0764,stroke:#9333ea,color:#e9d5ff
  ```
</div>

| Stage | Description |
| :- | :- |
| `RETRIEVAL` | The issuer requested transaction documentation before deciding whether to file a formal dispute. |
| `DISPUTE` | A formal dispute (chargeback) has been filed against the payment. |

PayPal's pre-arbitration and arbitration stages are both reported as `DISPUTE`. PayPal's own stage value stays available in `details.paypal_dispute_life_cycle_stage`.

## Dispute statuses

A dispute usually moves from `NEEDS_RESPONSE` through `EVIDENCE_SUBMITTED` and `UNDER_REVIEW` to a final status. It can also reach a final status straight from `NEEDS_RESPONSE`. Dashed arrows show a dispute reopening.

<div className="block dark:hidden">
  ```mermaid theme={"system"}
  flowchart LR
      A(["※ Needs response"]) --> B(["※ Evidence submitted"])
      B --> C(["↻ Under review"])

      C --> W(["✓ Won"])
      C --> L(["× Lost"])
      C --> AC(["× Accepted"])
      C --> P(["✓ Prevented"])

      A -->|Deadline missed| L
      A --> AC
      A --> P

      B -.->|Reopened| A
      C -.->|Reopened| A

      style A fill:#f1f5f9,stroke:#64748b,color:#334155
      style B fill:#f1f5f9,stroke:#64748b,color:#334155
      style C fill:#f1f5f9,stroke:#64748b,color:#334155
      style W fill:#dcfce7,stroke:#16a34a,color:#14532d
      style L fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
      style AC fill:#fef9c3,stroke:#ca8a04,color:#713f12
      style P fill:#fef9c3,stroke:#ca8a04,color:#713f12
  ```
</div>

<div className="hidden dark:block">
  ```mermaid theme={"system"}
  flowchart LR
      A(["※ Needs response"]) --> B(["※ Evidence submitted"])
      B --> C(["↻ Under review"])

      C --> W(["✓ Won"])
      C --> L(["× Lost"])
      C --> AC(["× Accepted"])
      C --> P(["✓ Prevented"])

      A -->|Deadline missed| L
      A --> AC
      A --> P

      B -.->|Reopened| A
      C -.->|Reopened| A

      style A fill:#1e293b,stroke:#475569,color:#cbd5e1
      style B fill:#1e293b,stroke:#475569,color:#cbd5e1
      style C fill:#1e293b,stroke:#475569,color:#cbd5e1
      style W fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style L fill:#7f1d1d,stroke:#dc2626,color:#fecaca
      style AC fill:#713f12,stroke:#ca8a04,color:#fef08a
      style P fill:#713f12,stroke:#ca8a04,color:#fef08a
  ```
</div>

| Status | Final | Description |
| :- | :- | :- |
| `NEEDS_RESPONSE` | | The dispute is open and awaiting your evidence or response. |
| `EVIDENCE_SUBMITTED` | | Evidence has been submitted and is awaiting a decision. |
| `UNDER_REVIEW` | | The network or issuer is reviewing the case. |
| `WON` | ✓ | The dispute was resolved in your favor. |
| `LOST` | ✓ | The dispute was resolved against you, including when the response deadline passed. |
| `ACCEPTED` | ✓ | You accepted the dispute without contesting it. |
| `PREVENTED` | ✓ | The dispute was stopped before it became a chargeback. |

* Once a dispute reaches a final status, it never changes again, and `resolved_at` records when that happened.
* A dispute can already be final when PayNext first records it.
* An open dispute can move back to `NEEDS_RESPONSE` from `UNDER_REVIEW` or `EVIDENCE_SUBMITTED` when your response is needed again.

<Note>
  There is no `EXPIRED` status. A dispute whose response deadline passes without a response is reported as `LOST`.
</Note>

## Dispute reasons

| Reason | The cardholder claims |
| :- | :- |
| `FRAUDULENT` | They didn't authorize the charge. |
| `UNRECOGNIZED` | They don't recognize the charge. |
| `PRODUCT_NOT_RECEIVED` | They didn't receive the goods or services they paid for. |
| `PRODUCT_UNACCEPTABLE` | The goods or services were defective, damaged, or not as described. |
| `SUBSCRIPTION_CANCELED` | They were charged for a subscription after canceling it. |
| `CREDIT_NOT_PROCESSED` | A promised refund or credit wasn't processed. |
| `DUPLICATE` | They were charged more than once for the same purchase. |
| `GENERAL_NONCOMPLIANT` | Any other reason, including claims that the payment didn't follow card network rules. |

## List and retrieve disputes

Use `GET /disputes` to list your organization's disputes and `GET /disputes/{id}` to retrieve one.

```bash theme={"system"}
curl -G https://api.paynext.com/disputes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-API-Version: 2.0.0" \
  --data-urlencode "status=NEEDS_RESPONSE" \
  --data-urlencode "sort=respond_by" \
  --data-urlencode "order=asc"
```

The list returns `data` (an array of dispute objects) and `meta`, which includes the pagination fields `page`, `pages`, `limit`, and `total`.

| Parameter | Description |
| :- | :- |
| `status` | Filter by status. Case-insensitive. |
| `stage` | Filter by stage. Case-insensitive. |
| `payment_id` | Filter by the disputed payment, as `pay_<uuid>` or a bare UUID. Any other format returns `400`. |
| `sort` | `disputed_at` (default), `created_at`, `updated_at`, `respond_by`, or `resolved_at`. |
| `order` | `desc` (default) or `asc`, in lowercase. |
| `page` | Page number, starting at 1 (default 1). |
| `limit` | Items per page, up to 100 (default 100). A larger value is treated as 100, and a value of 0 or less as 10. |

`page * limit` can't exceed 10000. A request past that returns `400`, and `meta.pages` never exceeds `10000 / limit`.

<Warning>
  The list can take up to about a minute to reflect a new or updated dispute, and list items never include `details`. When you need a dispute's current state—for example, right after a [dispute webhook](/webhooks/introduction/event-types#dispute-events) arrives—fetch it with `GET /disputes/{id}`, which reflects changes immediately and includes `details`.
</Warning>

`GET /disputes/{id}` returns `404` for a dispute that belongs to another organization.

## Disputes on a payment

Payments returned by `GET /payments` and `GET /payments/{id}` include a `disputes` array with a summary of each dispute linked to the payment: `id`, `external_id`, `stage`, `status`, `reason`, and `disputed_at`.

```json theme={"system"}
{
  "id": "pay_e8a1b2c3-d4f5-6789-abcd-ef0123456789",
  "payment_status": "SETTLED",
  "disputes": [
    {
      "id": "dsp_7c1a2b3c-4d5e-6f70-8a9b-0c1d2e3f4a5b",
      "external_id": "dp_1Nx2yZAbCdEfGh",
      "stage": "DISPUTE",
      "status": "NEEDS_RESPONSE",
      "reason": "FRAUDULENT",
      "disputed_at": "2026-08-01T10:15:00Z"
    }
  ]
}
```

| Endpoint | `disputes` present | `disputes` absent |
| :- | :- | :- |
| `GET /payments` | The payment has at least one dispute | The payment has no disputes, or a recent dispute isn't reflected yet |
| `GET /payments/{id}` | The payment's disputes; `[]` means none | Dispute data couldn't be loaded for this response—it doesn't mean the payment has no disputes |

Payment webhook payloads don't include `disputes`. To find payments by dispute status or stage, use the `dispute.status` and `dispute.stage` fields in [search](/api-reference/introduction/search).

## Required API key permission

`GET /disputes` and `GET /disputes/{id}` require the **Disputes: Read** permission. A scoped API key without it receives `403`. See [API keys](/guides/developers/api-keys).

<Tip>
  Many disputes can be stopped before they're filed. See [Fraud prevention](/guides/fraud-prevention/introduction) for the Visa and Mastercard programs PayNext supports.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.