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

# Create Refund

> Create a refund for a completed checkout session

# Create Refund

Creates a refund for a completed checkout session.

<Warning>
  Refunds can only be created for sessions with status `completed`. Each
  session can only be refunded once.
</Warning>

## Request

<ParamField header="Authorization" type="string" required>
  Bearer token with your API key
</ParamField>

<ParamField body="checkoutSessionId" type="string" required>
  The ID of the completed checkout session to refund
</ParamField>

<ParamField body="reason" type="string">
  Reason for the refund (for internal tracking)
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Whether the request was successful
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="id" type="string">
      Unique refund identifier (e.g., `ref_xyz789`)
    </ResponseField>

    <ResponseField name="checkoutSessionId" type="string">
      Associated checkout session ID
    </ResponseField>

    <ResponseField name="amountInCents" type="integer">
      Refund amount in cents
    </ResponseField>

    <ResponseField name="reason" type="string">
      Refund reason if provided
    </ResponseField>

    <ResponseField name="status" type="string">
      Refund status: `pending`, `processing`, `completed`, `failed`
    </ResponseField>

    <ResponseField name="requestedAt" type="string">
      ISO 8601 creation timestamp
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.swiftpay.cx/api/refunds \
    -H "Authorization: Bearer mp_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "checkoutSessionId": "sess_abc123",
      "reason": "Customer requested refund"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.swiftpay.cx/api/refunds", {
     method: "POST",
     headers: {
        Authorization: "Bearer mp_live_your_api_key",
        "Content-Type": "application/json",
     },
     body: JSON.stringify({
        checkoutSessionId: "sess_abc123",
        reason: "Customer requested refund",
     }),
  });

  const refund = await response.json();
  console.log(
     `Refund ${refund.data.id} created with status: ${refund.data.status}`
  );
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.swiftpay.cx/api/refunds',
      headers={
          'Authorization': 'Bearer mp_live_your_api_key',
          'Content-Type': 'application/json'
      },
      json={
          'checkoutSessionId': 'sess_abc123',
          'reason': 'Customer requested refund'
      }
  )

  refund = response.json()
  print(f"Refund {refund['data']['id']} created")
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "success": true,
    "data": {
      "id": "ref_xyz789",
      "checkoutSessionId": "sess_abc123",
      "amountInCents": 2999,
      "reason": "Customer requested refund",
      "status": "pending",
      "createdAt": "2024-01-15T10:30:00Z"
    }
  }
  ```

  ```json 400 theme={null}
  {
     "success": false,
     "error": {
        "type": "validation_error",
        "message": "Can only refund completed sessions",
        "requestId": "req_abc123"
     }
  }
  ```

  ```json 400 theme={null}
  {
     "success": false,
     "error": {
        "type": "validation_error",
        "message": "Insufficient balance for refund",
        "requestId": "req_abc123"
     }
  }
  ```
</ResponseExample>

## How Refunds Work

1. **Check Balance**: We verify sufficient funds (available balance + reserves)
2. **Deduct Funds**:
   * First from available balance
   * Then from oldest active reserves if needed
3. **Process Refund**: Funds returned to customer's payment method
4. **Webhook Notification**: `refund.completed` or `refund.failed` event sent

<Note>
  Refund processing typically takes 5-10 business days to appear on the
  customer's statement.
</Note>
