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

# Refunds

# Lifecycle

To help getting started with the Refunds API, this illustration shows off how refunds are handled by HUB2 API.

<Frame>
  <img src="https://mermaid.ink/img/pako:eNq9k11P2zAUhv_K0bklLWm6LIkvkFBatkrQVQRuUG5McvKhpXbxB4xV_e9zGiImJOBi0nxl-X39vPY59h4LWRIy1PRgSRS0aHmt-DYX4MYVqaLhwkzOzk6-2_uAweZHdgOniiorSj2Y1tIQqLZuDMgKBltmuLGaQXq9PL9ZLgZjL00cajJiGSgyVgkYeLB6YzzZKPnYlqQckJz-YlP9UbX5PH2zXC9W629voK_pT3TfSPkTdg7eivrd8JRrgpnjya5zPtBH_v-wj67JawdG-zXpnRRu_tSaZizN33s_qkx2m6bLLLu4vYRTuDhfXY49ei-wb_2LBNqVSwMXsNqs_yHqg4ZoWxSkdWU7t6fibUclerglteVt6R7rvifkaBraUo7MTUuquO1Mjrk4OCu3RmbPokBmlCUP7a7kZnzb4-KOC2R7_IVslsTTOI6S4GsYJL4fRl88fHbLfjhN5lE4D2M_nCWBHx08_C2lI_jTOAo9VNLWDbKKd3oA3h3VgU9la6S6Gv7X8Zt5WKv-AoOuXB1JpdIKgyyYh4c_gC4ftA" />
</Frame>

# API Reference

The *Refunds API* allows merchants to initiate refunds for previously successful transfers.

* [Refunds](#refunds)
  * [Creating a refund](#creating-a-refund)
    * [Restrictions](#restrictions)
  * [Retrieving refund details](#retrieving-refund-details)
  * [List refunds](#list-refunds)
    * [Pagination](#pagination)

***

## Creating a refund

[HUB2 API reference - Create a refund](/api-reference/refunds/create-refund)

Creating a refund requires one call to the dedicated endpoint with the transfer ID that you want to refund.

Sample request :

<CodeGroup>
  ```bash Curl theme={null}
  curl --location --request POST 'https://api.hub2.io/refunds' \
  --header 'ApiKey: [REDACTED]' \
  --header 'MerchantId: [REDACTED]' \
  --header 'Environment: sandbox' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "id": "tr_000000000000000000011",
    "zendeskTicketId": "zd_123456"
  }'
  ```

  ```typescript Typescript theme={null}
  import fetch from 'node-fetch';

  async function createRefund() {
      const response = await fetch('https://api.hub2.io/refunds', {
          method: 'POST',
          headers: {
              'ApiKey': '[REDACTED]',
              'MerchantId': '[REDACTED]',
              'Environment': 'sandbox',
              'Content-Type': 'application/json'
          },
          body: JSON.stringify({
              "id": "tr_000000000000000000011",
              "zendeskTicketId": "zd_123456"
          })
      });

      if (response.ok) {
          const result = await response.json();
          console.log(result);
      } else {
          console.log(`HTTP Status: ${response.status}`);
      }
  }

  createRefund();
  ```

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

  headers = {
      'ApiKey': '[REDACTED]',
      'MerchantId': '[REDACTED]',
      'Environment': 'sandbox',
      'Content-Type': 'application/json',
  }

  data = {
      "id": "tr_000000000000000000011",
      "zendeskTicketId": "zd_123456"
  }

  response = requests.post(
      'https://api.hub2.io/refunds',
      headers=headers,
      data=json.dumps(data)
  )

  if response.status_code == 200:
      print(response.json())
  else:
      print(f'HTTP Status: {response.status_code}')
  ```
</CodeGroup>

This request will initiate a refund for the specified transfer. The refund will be processed asynchronously and you will receive webhooks notifications about the status changes.

<Note>
  For any ticket to HUB2 support team concerning a refund, the refund ID will be asked, not the transfer ID.
</Note>

### Restrictions

* Only successful transfers can be refunded
* A transfer can only be refunded once
* The refund amount will be the full amount of the original transfer

***

## Retrieving refund details

[HUB2 API reference - Get refund details](/api-reference/refunds/retrieve-a-refund)

To retrieve a refund, perform a call to the dedicated endpoint. *Note : This endpoint requires a refund ID, obtained when creating a refund ([see previous step](#creating-a-refund)).*

This endpoint was designed to get the full details of a refund, including its current status and processing information.
***This endpoint***, like every endpoint on HUB2 API, ***is rate limited***. That means that if this endpoint is called too many times by a merchant ID, the HUB2 API will respond with `HTTP 429 Too Many Requests` to that merchant ID.

<Note>
  Documentation about rate limits [can be found here](/documentation/en/limits).
</Note>

Sample request :

<CodeGroup>
  ```bash Curl theme={null}
  curl --location --request GET 'https://api.hub2.io/refunds/123' \
  --header 'ApiKey: [REDACTED]' \
  --header 'MerchantId: [REDACTED]' \
  --header 'Environment: sandbox' \
  --header 'Content-Type: application/json' \
  ```

  ```typescript Typescript theme={null}
  import fetch from 'node-fetch';

  async function getRefund() {
      const response = await fetch('https://api.hub2.io/refunds/123', {
          method: 'GET',
          headers: {
              'ApiKey': '[REDACTED]',
              'MerchantId': '[REDACTED]',
              'Environment': 'sandbox',
              'Content-Type': 'application/json'
          }
      });

      if (response.ok) {
          const refund = await response.json();
          console.log(refund);
      } else {
          console.log(`HTTP Status: ${response.status}`);
      }
  }

  getRefund();
  ```

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

  headers = {
      'ApiKey': '[REDACTED]',
      'MerchantId': '[REDACTED]',
      'Environment': 'sandbox',
      'Content-Type': 'application/json',
  }

  response = requests.get(
      'https://api.hub2.io/refunds/123',
      headers=headers
  )

  if response.status_code == 200:
      print(response.json())
  else:
      print(f'HTTP Status: {response.status_code}')
  ```
</CodeGroup>

Once a Refund has been created and webhooks have been configured to receive notifications about the Refund's lifecycle, HUB2 will send webhooks for each event associated with configured webhooks.

**This is the recommended method for taking into account changes in the status of a Refund.** Some Refunds are processed quickly, while others less so, for a variety of unforeseeable reasons. There is no point in retrieving the details of a Refund to retrieve the status of a Refund if no change has taken place. This is why setting up webhooks is recommended.

<Note>
  Documentation about webhooks [can be found here](/integration/en/webhooks/webhooks_overview).
</Note>

***

## List refunds

[HUB2 API reference - List refunds](/api-reference/refunds/retrieve-refunds-collection)

To fetch a list of refunds, use the dedicated endpoint. Several query parameters (see below) can be applied to filter our results.

Sample request :

<CodeGroup>
  ```bash Curl theme={null}
  curl --location --request GET 'https://api.hub2.io/refunds?fromDate=2023-01-01T00:00:00.000&toDate=2023-01-01T12:00:00.000&page=1&perPage=100' \
  --header 'ApiKey: [REDACTED]' \
  --header 'MerchantId: [REDACTED]' \
  --header 'Environment: sandbox' \
  --header 'Content-Type: application/json' \
  ```

  ```typescript Typescript theme={null}
  import fetch from 'node-fetch';

  async function getRefunds() {
      const response = await fetch('https://api.hub2.io/refunds?fromDate=2023-01-01T00:00:00.000&toDate=2023-01-01T12:00:00.000&page=1&perPage=100', {
          method: 'GET',
          headers: {
              'ApiKey': '[REDACTED]',
              'MerchantId': '[REDACTED]',
              'Environment': 'sandbox',
              'Content-Type': 'application/json'
          }
      });

      if (response.ok) {
          const refunds = await response.json();
          console.log(refunds);
      } else {
          console.log(`HTTP Status: ${response.status}`);
      }
  }

  getRefunds();
  ```

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

  headers = {
      'ApiKey': '[REDACTED]',
      'MerchantId': '[REDACTED]',
      'Environment': 'sandbox',
      'Content-Type': 'application/json',
  }

  response = requests.get(
      'https://api.hub2.io/refunds?fromDate=2023-01-01T00:00:00.000&toDate=2023-01-01T12:00:00.000&page=1&perPage=100',
      headers=headers
  )

  if response.status_code == 200:
      print(response.json())
  else:
      print(f'HTTP Status: {response.status_code}')
  ```
</CodeGroup>

Please note the following parameters:

* **Parameter `fromDate` :** identifies the starting date of the refunds retrieval range, the value here is `2023-01-01T00:00:00.000Z`
* **Parameter `toDate` :** identifies the ending date of the refunds retrieval range, the value here is `2023-01-01T12:00:00.000Z`
* **Parameters `page` and `perPage` :** To control navigation through the result pages.

<Note>
  By default, when no filter is defined, **the 100 last refunds are returned** by this endpoint, ordered by `created_at`, descending.
</Note>

<Warning>
  **For a big number of refunds, paginated requests will be mandatory to retrieve all refunds from the HUB2 API.**
</Warning>

### Pagination

Pagination is available on that endpoint.

The response headers provide the `Content-Range` header to inform of the total number of results, and the header value is in the format `0-99/2453`.

In this particular case, this header indicates that the API returned the first 100 results out of a total of 2453 - so there are 25 pages of 100 results to fetch to retrieve all refunds corresponding to the initial filter.

A good advice is to set date filters in the initial request, so the number of results remains the same while pagination is running (except when `toDate` is set to a date in the future).
