> For the complete documentation index, see [llms.txt](https://docs.commercelayer.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.commercelayer.io/core-api-reference/2026-05/payment_refunds.md).

# Payment refunds

The payment refund object and the allowed CRUD operations on the related resource endpoint

A payment refund returns funds from a [payment capture](/core-api-reference/2026-05/payment_captures.md) back to the customer. The transaction is processed asynchronously. Refunds can be full or partial:

* A **partial refund** creates a new refund transaction and leaves the session in `partially_refunded` status.
* A **full refund** happens when the total refunded amount equals the total captured amount and transitions the session to `refunded` status.

{% hint style="info" %}
Creating a payment refund is what triggers the fund return via the associated [payment session](/core-api-reference/2026-05/payment_sessions.md), which in turn interacts with the related [payment setting](/core-api-reference/2026-05/payment_settings.md).
{% endhint %}

## Refund amount

A refund must reference a payment capture at creation time. The `amount_cents` defaults to the full remaining `refund_balance_cents` on the capture if not specified. The refund amount cannot exceed the capture amount.

## Event-driven creation

Gateway webhook events can create a payment refund automatically if one does not already exist for the capture. This means a transaction does not need to be explicitly created via the API first — Commerce Layer will create it in response to the event, ensuring the session status and order payment status are always kept in sync regardless of whether the flow was API-initiated or event-driven.

Incoming events are matched to an existing refund by the gateway's own reference for that operation. A reference already seen updates the refund it belongs to, while a reference not seen before creates a new one.

{% hint style="info" %}
Gateways don't guarantee delivery order and may send the same event more than once. An event arriving for a refund that has already reached a final status is ignored, so a redelivery can't overwrite a settled outcome — receiving the same refund notification twice still only records the refund once.
{% endhint %}

If a refund event arrives and its corresponding payment authorization and/or payment capture are missing, behavior depends on the gateway:

* [Adyen](/core-api-reference/2026-05/payment_setting_adyens.md) — the missing authorization and capture are synthesized from the event itself. The authorization reuses the `originalReference` Adyen supplies, but its refund notification carries no field identifying the capture's own reference, so the synthesized capture reuses the refund event's own reference as its token and the refund amount as its `amount_cents` (an approximation, not the original captured amount).
* [Stripe](/core-api-reference/2026-05/payment_setting_stripes.md) — the `charge.refunded` event includes the full charge object, so the missing authorization and capture are synthesized using the real Stripe charge ID and its actual authorized/captured amounts — no approximation needed.
* [Checkout.com](/core-api-reference/2026-05/payment_setting_checkout_coms.md) — like Adyen, both the missing authorization and capture are synthesized from the event itself, reusing the event's real payment ID — stable across the whole payment lifecycle — as their token. Unlike Adyen, though, the refund event carries no field for either the original authorization or capture amount, so both synthesized records reuse the refund's own amount as an approximation.
* [External](/core-api-reference/2026-05/payment_setting_externals.md) (custom gateways) — the webhook payload must explicitly include `authorization_token` and `reference_transaction_token` alongside the refund's own `transaction_token`. If any is missing, the event is rejected outright with a `422 Unprocessable Entity` response rather than Commerce Layer guessing at a missing reference.
* [Braintree](/core-api-reference/2026-05/payment_setting_braintrees.md) — refund events do **not** cascade. A refund is only created if a `succeeded` payment capture already exists for the session. Otherwise, the event is silently dropped (no refund is created, no error is raised).
* [PayPal](/core-api-reference/2026-05/payment_setting_paypals.md) — refund events do **not** cascade. A refund is only created if a payment capture already exists for the session. Otherwise, the event is silently dropped.

{% hint style="warning" %}
Because of the Adyen and Checkout.com limitations above, a synthesized capture — and, for Checkout.com, the synthesized authorization too — created this way may not accurately reflect the original amount or reference. It exists primarily to satisfy the data model and keep the session status in sync, not as an authoritative record of the original transaction.
{% endhint %}

## Return-initiated refunds

A payment refund can be linked to a [return](/core-api-reference/2026-05/returns.md). When a return-associated refund succeeds, the return status is updated automatically to reflect the completed refund.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.commercelayer.io/core-api-reference/2026-05/payment_refunds.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
