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

# Refunds

> Initiate and track refunds

## Refund Flow

```mermaid theme={null}
sequenceDiagram
    participant Game as Game
    participant Server as Game Server
    participant API as ToffeePay

    Game->>Server: Request refund
    Server->>API: Create Refund
    API->>Server: Return refund object
    Server->>Game: Confirm refund initiated

    Note over API: Processing refund...

    API->>Server: Send refund webhook (signed)
    Server->>Server: Verify webhook signature
    Server->>Server: Process refund & revoke item
    Server->>Game: Notify refund completed
```

***

## Create a Refund

Send a server-side request to [create a refund](/api-reference/refunds/create) for a paid session.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const { refund } = await toffee.refunds.create({
      paymentId: "pay_xyz789",
      reason: "Customer request",
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = await toffee.refunds.create(CreateRefundRequest(
        payment_id="pay_xyz789",
        reason="Customer request",
    ))
    refund = resp.refund
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    resp, err := toffee.Refunds.Create(ctx, &sdk.CreateRefundRequest{
      PaymentId: "pay_xyz789",
      Reason:    "Customer request",
    })
    refund := resp.GetRefund()
    ```
  </Tab>

  <Tab title="API">
    ```http theme={null}
    POST /v1/refunds
    Authorization: Bearer <your_access_token>
    Content-Type: application/json

    {
      "payment_id": "pay_xyz789",
      "reason": "Customer request"
    }
    ```
  </Tab>
</Tabs>

**Parameters:**

* `payment_id`: The original payment ID to refund
* `reason`: Optional reason for the refund

**Response:** A Refund object.

```json theme={null}
{
  "id": "ref_xyz789",
  "payment_id": "pay_xyz789",
  "status": "pending",
  "reason": "Customer request",
  "created_at": "2023-06-01T12:00:00Z"
}
```

***

## Refund Statuses

Refunds can have the following statuses:

* `pending`: Refund created but not yet processed
* `succeeded`: Refund has been successfully processed and funds returned
* `failed`: Refund failed (e.g., insufficient funds, payment method issues)
* `cancelled`: Refund was cancelled before completion

**Status Flow:**

1. Refund starts as `pending`
2. Refund resolves to either `succeeded`, `failed`, or `cancelled`

### Timestamp Fields

Refunds include relevant timestamp fields based on their final status:

* `created_at`: When the refund was initiated
* `succeeded_at`: When the refund completed successfully (if applicable)
* `failed_at`: When the refund failed (if applicable)
* `cancelled_at`: When the refund was cancelled (if applicable)

***

## Webhook Events

ToffeePay sends webhooks for the following refund-related events:

* [`refund.created`](/api-reference/webhooks/refund.created): When a refund is created and processing begins
* [`refund.succeeded`](/api-reference/webhooks/refund.succeeded): When a refund has been processed successfully
* [`refund.failed`](/api-reference/webhooks/refund.failed): When a refund attempt fails

See the [Webhooks](/webhooks) page for implementation details and signature verification.

***

## Handle Refund Notifications

When a refund is processed, ToffeePay sends a **signed webhook** to your backend.

**Sample Payload:**

```json theme={null}
{
  "type": "refund.succeeded",
  "timestamp": "2023-06-01T12:10:00Z",
  "data": {
    // Refund object
  }
}
```

For webhook signature verification, see the [Webhooks](/webhooks#webhook-signature-verification) page.

***

## Check Refund Status

You can [check the status](/api-reference/refunds/get) of a refund at any time:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const { refund } = await toffee.refunds.get({ id: "ref_xyz789" });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = await toffee.refunds.get(GetRefundRequest(id="ref_xyz789"))
    refund = resp.refund
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    resp, err := toffee.Refunds.Get(ctx, &sdk.GetRefundRequest{Id: "ref_xyz789"})
    refund := resp.GetRefund()
    ```
  </Tab>

  <Tab title="API">
    ```http theme={null}
    GET /v1/refunds/ref_xyz789
    Authorization: Bearer <your_access_token>
    ```
  </Tab>
</Tabs>

**Response:**

```json theme={null}
{
  "id": "ref_xyz789",
  "payment_id": "pay_xyz789",
  "status": "succeeded",
  "reason": "Customer request",
  "created_at": "2023-06-01T12:00:00Z",
  "succeeded_at": "2023-06-01T12:05:00Z"
}
```

***

## List Refunds

[Retrieve historical refunds](/api-reference/refunds/list) for audit and analytics:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const { refunds } = await toffee.refunds.list({ paymentId: "pay_xyz789" });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = await toffee.refunds.list(ListRefundsRequest(payment_id="pay_xyz789"))
    refunds = resp.refunds
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    paymentId := "pay_xyz789"
    resp, err := toffee.Refunds.List(ctx, &sdk.ListRefundsRequest{
      PaymentId: &paymentId,
    })
    refunds := resp.GetRefunds()
    ```
  </Tab>

  <Tab title="API">
    ```http theme={null}
    GET /v1/refunds?payment_id=pay_xyz789&status=succeeded&limit=50&offset=0
    Authorization: Bearer <your_access_token>
    ```
  </Tab>
</Tabs>

**Response:**

```json theme={null}
[
  {
    "id": "ref_xyz789",
    "payment_id": "pay_xyz789",
    "status": "succeeded",
    "reason": "Customer request",
    "created_at": "2023-06-01T12:00:00Z",
    "succeeded_at": "2023-06-01T12:05:00Z"
  }
]
```

***

## Best Practices

1. **Idempotency**: Use [Idempotency-Key](/idempotency) header to prevent duplicate refunds
2. **Revoke Items**: When processing a refund webhook, revoke the purchased items from the user's account
3. **Webhook verification**: Always verify webhook signatures (see [Webhooks](/webhooks))
