> For the complete documentation index, see [llms.txt](https://docs.hyperswitch.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hyperswitch.io/integration-guide/payment-suite/refunds.md).

# Refunds

Create, limit, and track API refunds against captured payment amounts

A refund can return only money that has already been captured. If a payment is still authorized and waiting for capture, capture it before requesting a refund. For a partially captured payment, the captured amount is the upper bound.

Use `POST /refunds` to create a refund. Use `GET /refunds/{refund_id}` to retrieve it and track its API status.

## Create a refund

The request schema has 10 fields. These 6 cover the common full and partial refund flow:

| Field         | Required | What to send                                                                                                                                                                    |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `payment_id`  | Yes      | The payment to refund.                                                                                                                                                          |
| `amount`      | No       | The amount in the currency's lowest denomination. Send it for a partial refund.                                                                                                 |
| `refund_id`   | No       | Your unique identifier for this refund operation. Hyperswitch generates one when it is omitted.                                                                                 |
| `reason`      | No       | A reason string. Hyperswitch stores it on the refund; whether it is passed to the processor depends on the connector.                                                           |
| `metadata`    | No       | Additional structured information for your own reference.                                                                                                                       |
| `refund_type` | No       | `instant` (the default) sends the refund to the connector before responding. `scheduled` queues it instead. This decides the status in the create response, as described below. |

For a partial refund:

```json
{
  "payment_id": "<payment_id>",
  "refund_id": "<refund_id>",
  "amount": 500,
  "reason": "Customer returned the item",
  "metadata": {
    "order_reference": "test_order"
  }
}
```

The response schema has 21 fields. The 7 used in this flow are `refund_id`, `payment_id`, `amount`, `currency`, `status`, `reason`, and `metadata`.

## Full and partial refund amounts

Omit `amount` only when you intend to refund the complete captured amount and no earlier non-failed refund has consumed part of it. Hyperswitch initially substitutes `amount_captured` when `amount` is omitted, then applies the remaining-amount check.

For each refund, Hyperswitch calculates:

`remaining refundable amount = amount_captured - previous non-failed refund amounts`

The new `amount` must not exceed that remainder. Failed refund operations do not consume it. This allows multiple partial refunds, subject to the remaining captured amount and the deployment's `refund.max_attempts` limit. Hyperswitch rejects a new refund when the payment attempt already has more than `refund.max_attempts` refunds, so the default of 10 allows up to 11 refunds on one payment attempt. That off-by-one is a bug, not an intended limit; see the [tracking issue](https://github.com/juspay/hyperswitch/issues/14264). Every refund counts toward that limit, including failed ones, even though failed refunds do not consume the refundable amount. Deployments can configure a different value. Use a distinct `refund_id` for each operation.

## Refunds and captures

A payment is eligible for this refund flow when its payment status is `succeeded` or `partially_captured`. A payment waiting for capture is not eligible.

The limit is based on `amount_captured`, not the originally requested payment amount. If you captured only part of an authorization, you can refund only that captured portion.

A payment that had a void issued after capture cannot be refunded; the request fails with a precondition error.

The connector must also support refunds for the payment's method type. If the connector does not declare refund support for that payment method type, Hyperswitch rejects the request before creating a refund, with the message `Refunds are currently not supported for <payment method type> transactions via <connector>`. Call `GET /feature_matrix` to see which payment method types each connector declares refund support for.

## Refund status lifecycle

The API returns four wire values:

| Wire value  | Meaning                                                                 |
| ----------- | ----------------------------------------------------------------------- |
| `pending`   | The refund was created and does not yet have a final processor outcome. |
| `succeeded` | The refund completed.                                                   |
| `failed`    | The refund did not complete.                                            |
| `review`    | The refund requires review.                                             |

Hyperswitch records every new refund as `pending`, but that is not necessarily the status you get back from `POST /refunds`. With the default `refund_type` of `instant`, Hyperswitch sends the refund to the connector before responding, so the create response can already be `succeeded`, `failed`, or `review`, and is `pending` only when the connector has not reached a final outcome. With `refund_type: scheduled`, the refund is queued and the create response is `pending`.

Retrieve a refund with `GET /refunds/{refund_id}` when you need the current API value. For event-driven updates, use the refund events listed in [Webhooks](/integration-guide/webhooks.md).

The Control Center uses display labels for operators. See [Operations](/integration-guide/control-center/operations.md) for the dashboard workflow. Those labels and the API wire values serve different interfaces.

## Refund windows

Hyperswitch checks the time since the payment was created (not since it was captured) against the deployment's `refund.max_age` setting, in days, before creating the refund. The repository default is 365 days, but deployments can configure a different value.

This server-side eligibility window is separate from the time it takes a refund to appear on a customer statement. Statement timing is owned by the payment processor and issuer, and the Hyperswitch API does not define a fixed duration.

See the [Create a Refund](https://api-reference.hyperswitch.io/v1/refunds/refunds--create) and [Retrieve a Refund](https://api-reference.hyperswitch.io/v1/refunds/refunds--retrieve) API references for the complete schemas.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.hyperswitch.io/integration-guide/payment-suite/refunds.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
