# Returns

{% hint style="info" %}
This article focuses on the returns process for developers. For information on the returns in the store operations process, see the [returns-app](https://docs.fulfillmenttools.com/documentation/apps/returns-app "mention") section.
{% endhint %}

A return is when a customer sends a purchased product back, seeking a refund, exchange, or store credit. The return process typically involves the customer physically bringing the items to the store or the customer initiating an online return.

There are two types of return:

* Announced returns (the customer notifies the retailer in advance about the return)
* Unannounced returns (the customer returns an item without prior notification)

## ItemReturnJob

An `ItemReturnJob` serves as a container for all potential `ItemReturns` associated with a placed order. It encompasses all items eligible for return (and not eligible for return) and tracks actual returned items. During interactions with the `ItemReturnJob`, validations ensure that only items that were handed over in the given order can be returned in the handed over quantities.

An `ItemReturnJob` is automatically generated through the designated workflow after the [handover](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/handover) process. The system then sends a notification with the `ITEM_RETURN_JOB_CREATED` event. If the handover feature is not utilized, the `ItemReturnJob` can be created via [item return jobs REST API](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#post-/api/itemreturnjobs).

The initial status of the `ItemReturnJob` is `OPEN`. The `returnableLineItems` list contains all items from the handover that are eligible for return. The `ItemReturnJob` includes all items from all handovers related to the original order, even if the order was split into multiple pick jobs.

## ItemReturn

An `ItemReturn` represents all items actually returned within the associated `ItemReturnJob`. It is imperative to have a valid `ItemReturnJob` before creating an `ItemReturn`.

While adding or updating an `ItemReturn` within an existing `ItemReturnJob`, item validations ensure that the returned quantity does not exceed the delivered and previously returned amounts.

Line items are returned by creating a new `ItemReturn` entity within an existing `ItemReturnJob`. This is done using the following API call:

```http
POST https://{projectId}.api.fulfillmenttools.com/api/itemreturnjobs/{itemReturnJobId}/itemreturns
```

```json
{
  "itemReturnForCreation": {
    "status": "ANNOUNCED",
    "returnFacilityRef": "string",
    "tenantOrderId": "string",
    "returnedLineItems": [
      {
        "itemConditionComment": "Upper corner damaged",
        "tenantArticleId": "4711-1",
        "status": "OPEN"
      }
    ]
  },
  "itemReturnJobVersion": 1
}
```

This call creates a pre-announced `ItemReturn` with an initial status `OPEN`, which can be updated later as required. Each returned item must be part of the `returnableLineItems` array of the parent `ItemReturnJob`. The request must also include the current `itemReturnJobVersion` to prevent concurrent modifications.

Note that the `status` of an `ItemReturnJob` does not automatically change to `FINISHED`, even if all of its `returnedLineItems` are `ACCEPTED`. The `ItemReturnJob` status must be updated explicitly via an API call. This action triggers an `ITEM_RETURN_JOB_UPDATED` event.

### Triggering a refund

A refund is triggered by updating the `refund` and `status` fields of a specific `returnedLineItem`. This is accomplished using the following PATCH request, which requires the current `itemReturnJobVersion`. For more details, refer to the [update returned line item endpoint documentation](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#patch-/api/itemreturnjobs/-itemReturnJobId-/itemreturns/-itemReturnId-/returnedlineitems/-returnedLineItemId-).

```http
PATCH https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/itemreturnjobs/{itemReturnJobId}/itemreturns/{itemReturnId}/returnedlineitems/{returnedLineItemId}
```

```json
{
  "status": "OPEN",
  "refund": {
    "status": "OPEN",
    "price": {
      "value": 19.95,
      "currency": "EUR"
    }
  },
  "itemReturnJobVersion": 2
}
```

## Returnable and not returnable items

As some items can't be returned for different reasons (customized item, special offer, and so on), an `ItemReturnJob` has two arrays of items: `returnableItems` and `notReturnableItems`. These items represent the items that are, returnable and not returnable.

In the case of an `ItemReturnJob` being created automatically in the designated workflow, both arrays are filled automatically as well.\
An item will be placed in the `notReturnableItems` array if the item was part of a related Service Job that had the flag `itemsReturnable` set to `false` otherwise it will be placed in the `returnableItems` array.

If in the [handover](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/handover) process items have been marked as handed over by setting the `handedOverQuantity` value to at least 1, then those items will populate one of those arrays. The `handedOverQuantity` sets the `returnable` field.\
If there is no [handover job](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/handover) or none of the items of the handover job have a `handedOverQuantity` set to at least 1, the arrays will be populated with the items of the related [pick job](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/picking). In this case, the `returnable` attribute is set by the `picked` quantity of the items in the pick job.

You can move items from one array to another by using the corresponding [actions](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#post-/api/itemreturnjobs/-itemReturnJobId-/actions).\
Line items can only be moved if the `itemReturns` array of the corresponding `ItemReturnJob` is empty and if the `returned` item's value to move is 0.

## Return reasons

Return reasons help customers to specify why certain items have been returned by the customer while creating an `ItemReturn`. In order to get predefined return reasons, these reasons can be added to the given return configuration via [return configuration REST API](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#put-/api/configurations/return).

The reasons can be passed while creating an `ItemReturn` through the API. Having default reasons is optional and not mandatory for passing reasons into an `ItemReturn`.

### Default values for return reasons in the back end

Default values for return reasons in the backend are not provided. However, it is possible to manage returns reasons on the client side. For example, in the [returns app](https://docs.fulfillmenttools.com/documentation/apps/returns-app), the default value for return reasons is set to "no reason". If no additional reasons are specified in the back end, the return reasons will not be displayed.

API users can use the predefined return reasons or provide their own ones when creating or updating the `ItemReturnLineItem` of an `ItemReturn`.

## Returned item conditions

Upon receiving the returned item, the item's condition is assessed, eligibility is checked based on the return policy, and a suitable resolution is provided (e.g., refund or store credit). This requires the ability to create a return manually.

When accepting returned items, the condition of the items can be defined. In the [Returns App](https://docs.fulfillmenttools.com/documentation/apps/returns-app), the default value for conditions is set to "not damaged". However, there is no default value defined in the back end.

Localized `itemConditions` can be added to the `returnConfiguration` via [return configuration REST API](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#put-/api/configurations/return).\
The translation depends on the locale of the user using this endpoint and the `tenantLocaleConfiguration`.

## Announced returns

Announced returns are return requests that a `customer` has registered before the physical package arrives at the `facility`. Announced returns include the items and details provided by the customer, such as return reason and item condition.

The return announcement is transferred from the shop and an `ItemReturn` is created in the associated `ItemReturnJob` with the status `ANNOUNCED`. This job can be updated until it is confirmed.&#x20;

These details are made available in [Backoffice](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/broken-reference) and the [Returns app](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/broken-reference), where announced returns can be searched for, optionally using a barcode from the return label if provided. Furthermore, the user is able to check and, if necessary, edit those details and confirm the return.

When confirming the return, the status changes from `ANNOUNCED` to `COMPLETED`, and no further changes are possible after confirmation.

## Create an announced return and complete it

{% hint style="info" %}
This is an example of an order that only contains returnable items.
{% endhint %}

1. **Obtain the `itemReturnJobId` for the order**
   1. Query [GET `/api/itemreturnjobs`](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#get-/api/itemreturnjobs) using the `tenantOrderId` (for example, via `searchTerm`) and, if needed, additional filters such as `facilityId`
   2. From the result, select the entry matching the `tenantOrderId` and take its ID as `itemReturnJobId`
2. **Create the announced return**
   1. Create an announced return using [POST `/api/itemreturnjobs/{itemReturnJobId}/itemreturns`](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#post-/api/itemreturnjobs/-itemReturnJobId-/itemreturns)
   2. Set status to `ANNOUNCED`
   3. Provide `returnFacilityRef` and at least one entry in `returnedLineItems`
   4. Each returned line item must include `tenantArticleId` and a line-item status (for example, `OPEN`)
   5. `itemConditionLocalized` and reasons are optional
   6. Include the current `itemReturnJobVersion`
3. **Locate announced returns**
   1. Filter by status `ANNOUNCED` in Backoffice
   2. Search by order information
4. **Edit prior to confirmation (optional)**
   1. Edits can be performed in the mobile application:
      1. Adjust quantities
      2. Replace or correct items within the same order
      3. Update reasons or conditions (if applicable)
      4. Add missing items from the same order if necessary
5. **Confirm the return using the returns app**
   1. Review the summary of items and details
   2. Confirm the return
   3. When confirming the return, the status changes from `ANNOUNCED` to `COMPLETED` and no further changes are possible after confirmation.

## Find an item return job by order

Use the following endpoint to obtain the `item return job` ID for a given `order`. This applies to an `order` that contains only returnable items.

```
GET https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/itemreturnjobs?searchTerm={TENANT_ORDER_ID}&facilityId={FACILITY_ID}
```

{% code title="Response example (excerpt):" %}

```json
[
  {
    "id": "job_98765",
    "status": "OPEN",
    "tenantOrderId": "ORDER_456",
    "returnableLineItems": [
      {
        "article": {
          "tenantArticleId": "4711",
          "title": "Cologne Water"
        },
        "delivered": 1,
        "returned": 0,
        "returnable": 1
      }
    ],
    "notReturnableLineItems": [],
    "itemReturns": []
  }
]
```

{% endcode %}

## Create an announced return

To create an `item return` with the status `ANNOUNCED` within an existing `item return job`, make the following API call:

```http
POST https://{projectId}.api.fulfillmenttools.com/api/itemreturnjobs/{ITEM_RETURN_JOB_ID}/itemreturns
```

```json
{
  "itemReturnForCreation": {
    "status": "ANNOUNCED",
    "returnFacilityRef": "FACILITY_123",
    "tenantOrderId": "ORDER_456",
    "scannableCodes": ["RETURN_LABEL_789"],
    "returnedLineItems": [
      {
        "tenantArticleId": "a69006ba-7100-4b4d-a610-1ca28016a4eb",
        "status": "OPEN",
        "scannedCodes": ["CODE_123"],
        "itemConditionLocalized": {
          "de_DE": "Wert",
          "en_US": "Value",
          "ru_RU": "значение"
        },
        "itemConditionComment": "Upper corner damaged",
        "reasons": [
          {
            "reason": "SIZE_TOO_SMALL",
            "reasonLocalized": {
              "de_DE": "Zu klein",
              "en_US": "Too small",
              "ru_RU": "Слишком маленький"
            },
            "comment": "Upper corner damaged"
          }
        ],
        "customAttributes": {},
        "recordableAttributes": [
          {
            "group": "general",
            "keyLocalized": {
              "de_DE": "Land",
              "en_US": "Country",
              "ru_RU": "Страна"
            },
            "recordingRule": "MANDATORY",
            "value": "Germany"
          }
        ]
      }
    ]
  },
  "itemReturnJobVersion": 0
}
```

#### Example 201 Created response

```json
{
  "id": "ret_12345",
  "created": "2025-08-11T08:30:00.000Z",
  "status": "ANNOUNCED",
  "returnFacilityRef": "FACILITY_123",
  "tenantOrderId": "ORDER_456",
  "returnedLineItems": [
    {
      "tenantArticleId": "a69006ba-7100-4b4d-a610-1ca28016a4eb",
      "status": "OPEN",
      "itemConditionLocalized": {
        "de_DE": "Wert",
        "en_US": "Value",
        "ru_RU": "значение"
      },
      "reasons": [
        {
          "reason": "SIZE_TOO_SMALL",
          "reasonLocalized": {
            "de_DE": "Zu klein",
            "en_US": "Too small",
            "ru_RU": "Слишком маленький"
          },
          "comment": "Upper corner damaged"
        }
      ],
      "recordableAttributes": [
        {
          "group": "general",
          "keyLocalized": {
            "de_DE": "Land",
            "en_US": "Country",
            "ru_RU": "Страна"
          },
          "recordingRule": "MANDATORY",
          "value": "Germany"
        }
      ]
    }
  ],
  "itemReturnJobId": "job_98765"
}
```
