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

# Refunds

> Manage refund tickets, process full or partial refunds, and track refund status

## Overview

Waffo Pancake uses a **refund ticket** system. Buyers request refunds through the API or Customer Portal, and each request creates a ticket that moves through a defined lifecycle. Merchants review and resolve tickets from the dashboard.

***

## Business Rules

<Note>
  These rules are enforced by the API and cannot be overridden.
</Note>

* **One-time products** are eligible for refund within **14 days** of payment.
* **Subscriptions** do not use the refund ticket system. Cancellation takes effect at the end of the current billing period.
* **Partial refunds** are supported by providing a custom `amount` (as a display format string, e.g., "15.00") when creating a ticket.

***

## Refund Ticket Statuses

Every refund ticket moves through the following lifecycle:

<CardGroup cols={3}>
  <Card title="pending" icon="clock" color="#f59e0b">
    Refund requested, awaiting review.
  </Card>

  <Card title="approved" icon="check" color="#22c55e">
    Refund approved by the merchant.
  </Card>

  <Card title="rejected" icon="xmark" color="#ef4444">
    Refund request denied.
  </Card>

  <Card title="processing" icon="spinner" color="#8b5cf6">
    Refund is being processed by the payment provider.
  </Card>

  <Card title="succeeded" icon="check-double" color="#3b82f6">
    Refund completed successfully.
  </Card>

  <Card title="failed" icon="triangle-exclamation" color="#dc2626">
    Refund processing failed.
  </Card>
</CardGroup>

***

## Creating a Refund Ticket

Refund tickets are created by calling the API with API Key authentication.

### Endpoint

```
POST /v1/actions/refund-ticket/create-ticket
```

**Authentication:** API Key

### Request Body

<ParamField body="paymentId" type="string" required>
  The ID of the payment to refund (UUID v4).
</ParamField>

<ParamField body="reason" type="string" required>
  A description of why the refund is being requested.
</ParamField>

<ParamField body="amount" type="string">
  Amount to refund as a display format string (e.g., "15.00"). Omit for a full refund.
</ParamField>

### Response

<ResponseField name="ticketId" type="string">
  The unique ID of the created refund ticket.
</ResponseField>

<ResponseField name="status" type="string">
  Initial status of the ticket. Always `pending` on creation.
</ResponseField>

<ResponseField name="requestedAmount" type="string">
  The refund amount as a display format string.
</ResponseField>

### Example

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST https://api.waffo.ai/v1/actions/refund-ticket/create-ticket \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer YOUR_API_KEY_TOKEN" \
    -d '{
      "paymentId": "550e8400-e29b-41d4-a716-446655440000",
      "reason": "Product not as described",
      "amount": "15.00"
    }'
  ```

  ```typescript SDK theme={"system"}
  import { WaffoPancake } from "@waffo/pancake-ts";

  const client = new WaffoPancake({
    merchantId: process.env.WAFFO_MERCHANT_ID!,
    privateKey: process.env.WAFFO_PRIVATE_KEY!,
  });

  const { ticketId, status, requestedAmount } = await client.refunds.createTicket({
    paymentId: "550e8400-e29b-41d4-a716-446655440000",
    reason: "Product not as described",
    amount: "15.00",
  });
  ```
</CodeGroup>

***

## Querying Refund Tickets

Use GraphQL to retrieve refund ticket data.

```graphql theme={"system"}
query {
  refundTickets(storeId: "STORE_ID") {
    id
    paymentId
    storeId
    customerId
    reason
    status
    requestedAmount
    approvedAmount
    currency
    createdAt
    updatedAt
    resolvedAt
  }
}
```

| Field             | Type   | Description                                        |
| ----------------- | ------ | -------------------------------------------------- |
| `id`              | string | Refund ticket ID                                   |
| `paymentId`       | string | Associated payment ID                              |
| `storeId`         | string | Store that owns the payment                        |
| `customerId`      | string | Buyer who requested the refund                     |
| `reason`          | string | Reason provided by the buyer                       |
| `status`          | string | Current ticket status                              |
| `requestedAmount` | string | Amount the buyer requested (display format string) |
| `approvedAmount`  | string | Amount approved (may differ from requested)        |
| `currency`        | string | ISO 4217 currency code                             |
| `createdAt`       | string | ISO 8601 timestamp                                 |
| `updatedAt`       | string | ISO 8601 timestamp                                 |
| `resolvedAt`      | string | ISO 8601 timestamp (null if unresolved)            |

***

## Webhook Notifications

You can configure webhooks to receive notifications when refund ticket events occur. See the [Webhooks guide](/integrate/webhooks) for setup instructions.

***

## Reducing Refund Requests

<AccordionGroup>
  <Accordion title="Clear Product Descriptions">
    Accurate descriptions reduce "not as expected" refund requests.
  </Accordion>

  <Accordion title="Trial Periods">
    Let customers try before buying to reduce post-purchase regret.
  </Accordion>

  <Accordion title="Responsive Support">
    Address issues quickly before they become refund requests.
  </Accordion>

  <Accordion title="Recognizable Billing">
    Use a clear billing descriptor so customers recognize charges.
  </Accordion>
</AccordionGroup>
