> For the complete documentation index, see [llms.txt](https://developers.coincircuit.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.coincircuit.io/promp-library/refund-and-dispute-handling.md).

# Refund and dispute handling

Estimate, create, and track refunds for sessions and invoices.

Use this prompt to add refund estimation, refund creation, and refund status tracking to your support workflow.

`Refunds` `Webhooks` `Support`

### What this prompt covers

* Estimate refund outcomes before sending funds
* Create refunds for sessions and invoices
* Track refund progress with webhook events

{% code title="refund-dispute-handling.prompt.md" expandable="true" collapsedlinecount="20" %}

````markdown
You are helping me add refund handling to my existing CoinCircuit payment integration. I have the CoinCircuit MCP server connected.

**If you have access to the CoinCircuit MCP server, call these tools for the most accurate and detailed schema outputs:**
- Call `search_api` with feature `Refunds` in the CoinCircuit MCP to see all available refund endpoints (estimate, create session refund, create invoice refund, list, get by ID).
- Call `get_endpoint` with method `post` and path `/api/v1/refunds/session/{sessionReference}` for the session refund request/response schema.
- Call `get_endpoint` with method `post` and path `/api/v1/refunds/invoice/{invoiceReference}` for the invoice refund schema.
- Call `get_endpoint` with method `get` and path `/api/v1/refunds/estimate/{reference}` for the refund estimation schema.
- Call `get_schema` with name `RefundCreatedWebhookDto` for the refund.created webhook payload.
- Call `get_schema` with name `RefundSuccessWebhookDto` for the refund.success webhook payload.
- Call `get_schema` with name `RefundFailedWebhookDto` for the refund.failed webhook payload.
- Call `get_schema` with name `RefundResponseDto` for the full refund object shape used in both API responses and webhooks.

Use the live MCP data as your source of truth. The details below are a guide, but if the MCP returns something different, trust the MCP.

## API Basics

- **Base URL:** `https://api.coincircuit.io`
- **Auth:** `x-api-key` header on every request.

## Project Context

I have an application using CoinCircuit for payments and I need to handle customer refund requests for both checkout session payments and invoice payments. CoinCircuit sends crypto refunds to a wallet address you specify.

## What I Need You to Implement

### 1. Estimate refund before processing

Before issuing a refund, show the customer what they'll receive after fees.

**Endpoint:** `GET /api/v1/refunds/estimate/{reference}?entity={type}`
*(Call `get_endpoint` with method `get`, path `/api/v1/refunds/estimate/{reference}` in the CoinCircuit MCP for the full parameter and response details.)*

**Path params:**
- `reference` (string) - the session reference (e.g. `CS_1234567890`) or invoice reference (e.g. `INV_1234567890`)

**Query params:**
- `entity` (required) - `"session"` or `"invoice"`
- `feePaidBy` (optional) - `"merchant"` or `"customer"`

Use this to display a confirmation screen: "Refund amount: X USDT, Network fee: Y USDT, Customer receives: Z USDT".

### 2. Refund a checkout session

**Endpoint:** `POST /api/v1/refunds/session/{sessionReference}`
*(Call `get_endpoint` with method `post`, path `/api/v1/refunds/session/{sessionReference}`, section `request` in the CoinCircuit MCP for the exact request body.)*

**Path params:**
- `sessionReference` (string) - the session reference from the original payment

**Request body:**
- `refundAddress` (string, **required**) - the customer's wallet address to receive the refund
- `reason` (string, optional) - e.g. "Customer requested refund", "Product not delivered"
- `feePaidBy` (string, optional) - `"merchant"` or `"customer"`. Defaults to your dashboard settings. Controls who absorbs the blockchain gas fee.

**Example:**
```json
{
  "refundAddress": "TF6yMCJqFcT6wFFutxVmRocKgJFD5imKUT",
  "reason": "Customer requested refund - product not as described",
  "feePaidBy": "merchant"
}
```

**Response (201):** Returns the refund object:
- `data.id` - refund UUID
- `data.entity` - `"session"`
- `data.reference` - the session reference
- `data.status` - `"pending"`, `"processing"`, `"completed"`, or `"failed"`
- `data.chain` - blockchain used for the refund (matches original payment)
- `data.asset` - crypto asset (e.g. `"USDT"`)
- `data.amount` - crypto amount the customer receives (e.g. `"49.50000000"`)
- `data.fee` - network fee in crypto (e.g. `"0.50000000"`)
- `data.feePaidBy` - `"merchant"` or `"customer"`
- `data.balanceSource` - `"merchantBalance"` or `"pendingBalance"`
- `data.merchantDebitAmount` - fiat amount debited from your balance
- `data.fiatAmount` / `data.fiatCurrency` - fiat value of the refund
- `data.refundAddress` - customer's wallet
- `data.txHash` - blockchain tx hash (populated on completion)
- `data.explorerUrl` - block explorer link (populated on completion)

*(Call `get_schema` with name `RefundResponseDto` in the CoinCircuit MCP for every field in the refund object, including which are required vs optional.)*

### 3. Refund an invoice

**Endpoint:** `POST /api/v1/refunds/invoice/{invoiceReference}`
*(Call `get_endpoint` with method `post`, path `/api/v1/refunds/invoice/{invoiceReference}` in the CoinCircuit MCP for the full schema.)*

Same request body as session refunds: `refundAddress` (required), `reason` (optional), `feePaidBy` (optional). Same response shape.

### 4. Track refund status via webhooks

*(Call `get_schema` with name `RefundSuccessWebhookDto` in the CoinCircuit MCP for the full refund.success webhook payload. Call `get_schema` with name `RefundFailedWebhookDto` for the failure payload.)*

**Refund events** (envelope: `{ event: string, data: { refund: RefundObject } }`):

- `refund.created` - refund initiated, blockchain transaction pending. `data.refund.status` is `"pending"`. *(Call `get_schema` with name `RefundCreatedWebhookDto` for the full payload.)*
- `refund.success` - crypto sent to customer's wallet. `data.refund.txHash` and `data.refund.explorerUrl` are populated. `data.refund.completedAt` has the timestamp.
- `refund.failed` - refund failed (insufficient hot wallet balance, invalid address, etc.). `data.refund.status` is `"failed"`.

**Refund object fields in webhook:**
- `data.refund.id` - refund UUID
- `data.refund.entity` - `"session"` or `"invoice"`
- `data.refund.reference` - original session/invoice reference
- `data.refund.status` - `"pending"`, `"processing"`, `"completed"`, `"failed"`
- `data.refund.amount` - crypto amount customer receives
- `data.refund.fee` - network fee
- `data.refund.feePaidBy` - who paid the fee
- `data.refund.refundAddress` - customer's wallet
- `data.refund.txHash` - blockchain tx hash (on success)
- `data.refund.explorerUrl` - block explorer URL (on success)
- `data.refund.merchantDebitAmount` - fiat amount debited from merchant
- `data.refund.fiatAmount` / `data.refund.fiatCurrency` - fiat value

### 5. Query refund history

*(Call `search_api` with feature `Refunds` in the CoinCircuit MCP to see all listing and detail endpoints.)*

**List all refunds:** `GET /api/v1/refunds` (returns paginated list)
*(Call `get_endpoint` with method `get`, path `/api/v1/refunds` in the CoinCircuit MCP for pagination params and response schema.)*

**Get single refund:** `GET /api/v1/refunds/{id}`
*(Call `get_endpoint` with method `get`, path `/api/v1/refunds/{id}` in the CoinCircuit MCP for the full response.)*

Use these to build a support dashboard showing all refunds with their status, amounts, and transaction details.

### 6. Customer communication flow

Build email/notification triggers based on webhook events:
- On `refund.created`: "Your refund has been initiated. We're sending {amount} {asset} to your wallet."
- On `refund.success`: "Your refund of {amount} {asset} has been sent to {refundAddress}. Track it here: {explorerUrl}"
- On `refund.failed`: "We encountered an issue processing your refund. Our team is looking into it. Reference: {reference}"

## Constraints

- `refundAddress` is **required**. CoinCircuit needs to know where to send the crypto.
- Refunds are async. The API returns immediately with `"pending"` status. Use webhooks for final status.
- A session or invoice can only be refunded **once**.
- You cannot refund more than the original payment amount.
- The refund is sent in crypto (on the same chain/asset as the original payment) regardless of the original fiat denomination.
- Network fees (gas) may be deducted from the refund amount (if `feePaidBy: "customer"`) or from your merchant balance (if `feePaidBy: "merchant"`).
- Use the estimate endpoint first to show the customer what they'll receive.
- Refund statuses: `"pending"` -> `"processing"` -> `"completed"` or `"failed"`.
````

{% endcode %}


---

# 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://developers.coincircuit.io/promp-library/refund-and-dispute-handling.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.
