OrderReturns

API Reference

Comprehensive guide to the Omnium Returns API. Learn how to create returns, process exchanges, create replacement orders, and manage return workflows programmatically.

The Returns API enables programmatic management of the entire return lifecycle in Omnium. This includes creating returns from orders, processing exchanges, generating replacement orders, and managing return workflows.

Returns are normally created against an existing order. When the original order is not in Omnium, see Create an order-less return.

Overview

┌─────────────────────────────────────────────────────────────────┐
│                     Return API Flow                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────┐     ┌──────────────┐     ┌─────────────────────┐  │
│  │  Order  │────►│ Create Return│────►│  Return Processing  │  │
│  └─────────┘     └──────────────┘     └─────────────────────┘  │
│                         │                       │               │
│                         ▼                       ▼               │
│              ┌──────────────────┐    ┌─────────────────────┐   │
│              │ Exchange Order   │    │ Workflow Execution  │   │
│              │ (optional)       │    │ • Credit payment    │   │
│              └──────────────────┘    │ • Update inventory  │   │
│                                      │ • Notifications     │   │
│              ┌──────────────────┐    │ • Export to ERP     │   │
│              │ Replacement Order│    └─────────────────────┘   │
│              │ (optional)       │                               │
│              └──────────────────┘                               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Authentication

All Return API endpoints require authentication via API key. Include the API key in the request header:

Authorization: Bearer {your-api-key}

Endpoints are divided by permission level:

  • Read operations: Require OrderReadGroups access
  • Write operations: Require OrderAdminGroups access

Base URL

https://api.omnium.no/api/returns

For test environments:

https://apitest.omnium.no/api/returns

Create Return

Creates a return for line items from an existing order. Optionally creates an exchange order in the same transaction.

POST /api/returns/{orderId}/Return

When to Use

  • Customer wants to return purchased items for refund
  • Customer wants to exchange items for different products
  • Processing in-store returns
  • Automated return processing from external systems

Path Parameters

ParameterTypeRequiredDescription
orderIdstringYesOrder ID or order number to create return from

Request Body

{
  "returns": [
    {
      "lineItemId": "line-001",
      "returnQuantity": 2,
      "returnReason": "Wrong size",
      "returnType": "StandardReturn",
      "isStockUpdated": true,
      "creditAmount": null
    }
  ],
  "storeId": "warehouse-main",
  "comment": "Customer requested size exchange",
  "creditPayment": true,
  "creditShipment": false,
  "rmaNumber": "RMA-2024-001",
  "status": "New",
  "returnType": "StandardReturn"
}

Request Properties

PropertyTypeDescription
returnsarrayItems being returned (required)
returns[].lineItemIdstringID of the order line item to return
returns[].returnQuantitydecimalQuantity being returned
returns[].returnReasonstringFree-text reason for return
returns[].returnTypestringReturn type ID from configuration
returns[].isStockUpdatedbooleanWhether to add items back to inventory
returns[].creditAmountdecimalPer-item credit amount (null = full refund)
storeIdstringWarehouse receiving the return
commentstringReturn description/notes
creditPaymentbooleanWhether to credit the payment
creditShipmentbooleanWhether to refund shipping costs
creditShipmentAmountdecimalCustom shipping refund amount
chargeShipmentCostbooleanCharge customer for return shipping
chargeShipmentCostAmountdecimalReturn shipping cost (0 = use market default)
rmaNumberstringReturn Merchandise Authorization number
handlingTotaldecimalHandling fees to deduct from refund
statusstringInitial return status
returnTypestringOverall return type classification
propertiesarrayCustom key-value properties

Response

{
  "returnId": "ret-12345",
  "rmaNumber": "RMA-2024-001",
  "returnComment": "Customer requested size exchange",
  "returnType": "StandardReturn",
  "status": "New",
  "storeId": "warehouse-main",
  "created": "2024-01-15T10:30:00Z",
  "modified": "2024-01-15T10:30:00Z",
  "creditAmount": 149.00,
  "creditPayment": true,
  "lineItems": [
    {
      "lineItemId": "ret-line-001",
      "code": "SKU-12345",
      "displayName": "Blue T-Shirt Medium",
      "quantity": 2,
      "placedPrice": 74.50,
      "extendedPrice": 149.00
    }
  ],
  "shipments": [...],
  "subTotal": 149.00,
  "total": -149.00,
  "externalIds": [],
  "replacementOrderIds": []
}

Creating an Exchange Order

To create an exchange in the same request, include the omniumExchangeOrderOptions property:

{
  "returns": [
    {
      "lineItemId": "line-001",
      "returnQuantity": 1,
      "returnType": "Exchange",
      "isStockUpdated": true
    }
  ],
  "creditPayment": true,
  "omniumExchangeOrderOptions": {
    "exchangeOrderLines": [
      {
        "code": "SKU-54321",
        "displayName": "Blue T-Shirt Large",
        "quantity": 1,
        "placedPrice": 74.50
      }
    ],
    "orderType": "Online",
    "orderStatus": "New",
    "shippingMethodName": "Standard"
  }
}

Exchange Order Properties

PropertyTypeDescription
exchangeOrderIdstringCustom ID for exchange order (auto-generated if omitted)
exchangeOrderLinesarrayItems customer is receiving in exchange
additionalPaymentsarrayPayments if exchange costs more than return
orderTypestringOrder type for exchange order
orderStatusstringInitial status for exchange order
shippingMethodNamestringShipping method (e.g., "PickUpInStore")

Price Difference Handling

When exchange items cost more than returned items:

{
  "returns": [...],
  "omniumExchangeOrderOptions": {
    "exchangeOrderLines": [
      {
        "code": "PREMIUM-SKU",
        "quantity": 1,
        "placedPrice": 199.00
      }
    ],
    "additionalPayments": [
      {
        "paymentMethodName": "CreditCard",
        "amount": 50.00,
        "transactionId": "TXN-123456"
      }
    ]
  }
}

Create an Order-less Return

Registers a return when there is no original order in Omnium — goods brought back without a receipt, a receipt that predates the integration, or a sale made in a system that never pushed its orders.

POST /api/Orders/AddMany

Do not create an empty order first and then add a return to it as a separate call. The supported pattern — the same one Omnium's own POS integrations use — is a single order that carries the return: an order with no order lines, and a returnOrderForms entry holding the returned items and the refund.

When to Use

  • In-store returns with no matching order in Omnium
  • Returns of sales made before an integration went live
  • Goodwill returns registered at the counter

Two Calls

Registering the return and processing it are separate steps. Create the order with the return form in a placeholder status, then complete it so the return workflow runs.

1. Create the order carrying the return:

POST /api/Orders/AddMany
 
[
  {
    "id": "POSRET-001",
    "orderNumber": "POSRET-001",
    "orderType": "Pos",
    "storeId": "oslo-downtown",
    "marketId": "nor",
    "billingCurrency": "NOK",
    "returnOrderForms": [
      {
        "returnId": "8f14e45f-ceea-467a-9575-9a1f6b1c2d3e",
        "status": "New",
        "storeId": "oslo-downtown",
        "returnType": "StandardReturn",
        "creditPayment": false,
        "total": 199.00,
        "lineItems": [
          {
            "lineItemId": "1",
            "code": "yellow-tshirt-medium",
            "displayName": "Yellow T-Shirt - Medium",
            "quantity": 1,
            "returnQuantity": 1,
            "placedPrice": 199.00,
            "extendedPrice": 199.00,
            "taxRate": 25,
            "returnType": "StandardReturn",
            "returnReason": "Changed mind",
            "updateStock": true
          }
        ],
        "payments": [
          {
            "amount": 199.00,
            "paymentMethodName": "PaidInStore",
            "transactionType": "Credit",
            "status": "Processed"
          }
        ]
      }
    ]
  }
]

2. Complete the return so the workflow runs:

POST /api/Returns/POSRET-001/UpdateStatus
 
{
  "returnId": "8f14e45f-ceea-467a-9575-9a1f6b1c2d3e",
  "status": "Completed"
}

Required Properties

PropertyLevelDescription
idOrderUnique order ID
orderNumberOrderUnique order number
orderTypeOrderMust match a configured order type
storeIdOrderThe selling store
returnIdReturn formAn ID you generate, typically a GUID. This is what you reference in the UpdateStatus call
statusReturn formPlaceholder status to create the return in, before completing it
storeIdReturn formThe store receiving the goods back. Inventory is increased here
returnTypeReturn lineA return type ID from return settings
quantity and returnQuantityReturn lineSet both. The inventory adjustment is based on quantity
updateStockReturn linetrue to have Omnium add the item back to inventory

Omit rmaNumber to have one generated for you.

Missing required properties return 400 with a message identifying the problem.

orderNumber must be unique. If an order with the same number already exists, AddMany responds 200 with a "not added" message rather than an error — inspect the response body rather than relying on the status code alone.

What the Return Workflow Does

UpdateStatus runs the workflow configured for that return status under return settings. A typical configuration will:

Stock and Payment on Order-less Returns

Stock is only adjusted for return types configured to update inventory. updateStock: true on the line is necessary but not sufficient — the return type must also have UpdateInventory enabled in return settings. Use return types with UpdateInventory: false for goods that must not go back on the shelf.

There is no payment on the order to credit. The refund already happened wherever the customer was served, so set creditPayment: false on the return form and record what was refunded as a Credit payment transaction on the return form, as in the payload above. The credit step logs a warning that there is nothing to credit — this is expected and harmless.

To suppress the return notifications on a back-office registration, set "isNotificationsDisabled": true on the order.

Alternative: an Already-completed POS Order

When the POS pushes the till transaction as an order that is already completed — a mixed receipt with both sold and returned items, for example — the return can be restocked by the order workflow instead of the return workflow, using the CheckPosOrderForReturnAndIncreaseInventory step on the completed status. That step requires the order to be in a completed status and is idempotent, so re-running the workflow does not double-count.


Update Return Status

Updates the status of a return and executes the associated workflow steps.

POST /api/returns/{orderId}/UpdateStatus

When to Use

  • Moving return through processing stages
  • Triggering workflow actions (refund, inventory update, notifications)
  • Completing or cancelling returns

Request Body

{
  "status": "Completed",
  "returnId": "ret-12345",
  "userId": "user-001",
  "skipRunWorkflow": false
}

Request Properties

PropertyTypeDescription
statusstringNew status (required). Values: New, InProgress, InTransit, ReadyForPickup, Completed, OrderCanceled, PartiallyShipped
returnIdstringReturn ID to update (required)
userIdstringUser performing the update
skipRunWorkflowbooleanIf true, updates status without running workflow steps
shipmentInfoobjectShipment tracking information to update

Shipment Info Properties

{
  "status": "Completed",
  "returnId": "ret-12345",
  "shipmentInfo": {
    "shipmentId": "ship-001",
    "trackingNumber": "1Z999AA10123456784",
    "trackingUrl": "https://tracking.example.com/1Z999AA10123456784",
    "returnTrackingNumber": "1Z999AA10123456785",
    "returnTrackingLink": "https://tracking.example.com/1Z999AA10123456785"
  }
}

Response

Returns workflow execution results:

{
  "orderActionExecutionResults": [
    {
      "actionType": "UpdateInventory",
      "actionStatus": "Success",
      "translateKey": "WorkflowStep_UpdateInventory",
      "isInvisible": false
    },
    {
      "actionType": "CreditReturn",
      "actionStatus": "Success",
      "translateKey": "WorkflowStep_CreditReturn",
      "isInvisible": false
    },
    {
      "actionType": "Notification",
      "actionStatus": "Success",
      "translateKey": "WorkflowStep_Notification",
      "isInvisible": false
    }
  ],
  "isAborted": false,
  "order": {...}
}

Workflow Status Meanings

StatusTypical Workflow Actions
NewEnsureRma, Notification, UpdateOrderStatus
InProgress-
InTransitCreateReturnShipmentBooking
ReadyForPickup-
CompletedUpdateInventory, CreditReturn, ExportOrder
OrderCanceledCancelReturn

Search Returns

Search and filter return orders with pagination.

POST /api/returns/SearchReturnOrders

Request Body

{
  "orderNumber": "ORD-2024-001",
  "rmaNumber": null,
  "customerId": null,
  "email": "customer@example.com",
  "searchText": null,
  "selectedStores": ["warehouse-main"],
  "createdFrom": "2024-01-01T00:00:00Z",
  "createdTo": "2024-01-31T23:59:59Z",
  "take": 20,
  "page": 1
}

Search Properties

PropertyTypeDescription
idstringReturn ID (exact match)
orderNumberstringOriginal order number
rmaNumberstringRMA number
customerIdstringCustomer ID
projectIdstringAssociated project/claim ID
emailstringCustomer email
phonestringCustomer phone
customerNamestringCustomer name
searchTextstringFree-text search across multiple fields
selectedStoresarrayFilter by return store IDs
createdFromdatetimeReturns created after this date
createdTodatetimeReturns created before this date
modifiedFromdatetimeReturns modified after this date
modifiedTodatetimeReturns modified before this date
takeintegerResults per page (default: 20)
pageintegerPage number (default: 1)

Response

{
  "totalHits": 47,
  "result": [
    {
      "orderId": "order-12345",
      "orderNumber": "ORD-2024-001",
      "customerId": "cust-001",
      "customerName": "John Doe",
      "customerEmail": "john@example.com",
      "returnStoreName": "Main Warehouse",
      "returnStoreId": "warehouse-main",
      "returnOrderForm": {
        "returnId": "ret-12345",
        "rmaNumber": "RMA-2024-001",
        "status": "Completed",
        "created": "2024-01-15T10:30:00Z",
        "creditAmount": 149.00,
        "lineItems": [...]
      }
    }
  ],
  "facets": []
}

Patch Return

Partially update a return. Only properties included in the request are modified.

PATCH /api/returns/{orderId}/{returnId}

When to Use

  • Updating return metadata (RMA, comment, type)
  • Modifying line items on an existing return
  • Adding external IDs for integrations
  • Adjusting credit amounts

Request Body

{
  "rmaNumber": "RMA-2024-001-UPDATED",
  "returnComment": "Updated comment after inspection",
  "creditAmount": 125.00,
  "externalIds": [
    {
      "providerName": "ERP",
      "id": "ERP-RET-12345"
    }
  ]
}

Patch Properties

PropertyTypeDescription
rmaNumberstringUpdate RMA number
returnCommentstringUpdate return comment
returnTypestringUpdate return type
statusstringUpdate status
storeIdstringUpdate receiving store
creditAmountdecimalUpdate credit amount
creditPaymentbooleanUpdate credit flag
externalIdsarrayAdd/update external system IDs
lineItemsarrayUpdate line items
shipmentsarrayUpdate shipment information
shouldAddMissingLineItemsbooleanAdd items not in existing return
replaceLineItemsArraybooleanReplace all line items (not merge)

Response

{
  "totalCount": 1,
  "updatedCount": 1,
  "unchangedCount": 0,
  "notFoundCount": 0,
  "errorCount": 0,
  "isModified": true
}

Create Replacement Order

Creates a replacement order for items from an existing order. The customer receives new items without additional payment.

POST /api/returns/CreateReplacementOrder

When to Use

  • Item arrived damaged
  • Wrong item was shipped
  • Item defective/faulty
  • Lost shipment replacement

Request Body

{
  "orderId": "order-12345",
  "orderLineReplacements": [
    {
      "lineItemId": "line-001",
      "quantity": 1,
      "replacementType": "DefectiveItem",
      "replacementReason": "Product arrived damaged"
    }
  ],
  "comment": "Replacement for damaged item - approved by support"
}

Request Properties

PropertyTypeDescription
orderIdstringOriginal order ID (required)
orderLineReplacementsarrayItems to replace (required)
orderLineReplacements[].lineItemIdstringOrder line to replace
orderLineReplacements[].quantityintegerQuantity to replace
orderLineReplacements[].replacementTypestringType of replacement
orderLineReplacements[].replacementReasonstringReason for replacement
orderLineReplacements[].skuIdstringDifferent SKU to send (optional)
commentstringComment added to replacement order
amountToCreditdecimalPartial credit amount on original order

Replace with Different Product

To ship a different product:

{
  "orderId": "order-12345",
  "orderLineReplacements": [
    {
      "lineItemId": "line-001",
      "quantity": 1,
      "skuId": "NEW-SKU-456",
      "replacementReason": "Original product discontinued"
    }
  ]
}

Response

Returns a list of return order forms created:

[
  {
    "returnId": "ret-replacement-001",
    "status": "New",
    "lineItems": [...],
    "replacementOrderIds": ["replacement-order-001"]
  }
]

Get Claim Types

Retrieves available claim/project types for returns.

GET /api/returns/Claims/ClaimTypes

When to Use

  • Populating claim type dropdown in UI
  • Validating claim types before creating return with claim

Response

[
  {
    "projectTypeId": "warranty-claim",
    "projectTypeName": "Warranty Claim",
    "projectTypeDescription": "Product defect covered by warranty"
  },
  {
    "projectTypeId": "damage-claim",
    "projectTypeName": "Damage Claim",
    "projectTypeDescription": "Item damaged during shipping"
  },
  {
    "projectTypeId": "missing-item",
    "projectTypeName": "Missing Item",
    "projectTypeDescription": "Item not included in shipment"
  }
]

Common Scenarios

Scenario 1: Simple Refund Return

Customer returns items for full refund:

POST /api/returns/{orderId}/Return
 
{
  "returns": [
    {
      "lineItemId": "line-001",
      "returnQuantity": 1,
      "returnType": "StandardReturn",
      "isStockUpdated": true
    }
  ],
  "creditPayment": true,
  "creditShipment": false,
  "status": "New"
}

Then complete the return:

POST /api/returns/{orderId}/UpdateStatus
 
{
  "status": "Completed",
  "returnId": "ret-12345"
}

Scenario 2: Exchange - Same Price

Customer exchanges medium for large (same price):

POST /api/returns/{orderId}/Return
 
{
  "returns": [
    {
      "lineItemId": "line-001",
      "returnQuantity": 1,
      "returnType": "Exchange",
      "isStockUpdated": true
    }
  ],
  "creditPayment": false,
  "omniumExchangeOrderOptions": {
    "exchangeOrderLines": [
      {
        "code": "SHIRT-BLUE-L",
        "displayName": "Blue T-Shirt Large",
        "quantity": 1,
        "placedPrice": 74.50
      }
    ],
    "orderType": "Online",
    "orderStatus": "New"
  }
}

Scenario 3: Exchange with Price Difference

Customer exchanges for more expensive item:

POST /api/returns/{orderId}/Return
 
{
  "returns": [
    {
      "lineItemId": "line-001",
      "returnQuantity": 1,
      "returnType": "Exchange"
    }
  ],
  "omniumExchangeOrderOptions": {
    "exchangeOrderLines": [
      {
        "code": "PREMIUM-SHIRT",
        "quantity": 1,
        "placedPrice": 149.00
      }
    ],
    "additionalPayments": [
      {
        "paymentMethodName": "CreditCard",
        "amount": 74.50
      }
    ]
  }
}

Scenario 4: Partial Credit

Customer returns item but only receives partial credit (restocking fee):

POST /api/returns/{orderId}/Return
 
{
  "returns": [
    {
      "lineItemId": "line-001",
      "returnQuantity": 1,
      "returnType": "StandardReturn",
      "creditAmount": 60.00
    }
  ],
  "creditPayment": true,
  "handlingTotal": 14.50,
  "comment": "Restocking fee applied per policy"
}

Scenario 5: Defective Item Replacement

Item defective, send replacement without affecting inventory:

POST /api/returns/CreateReplacementOrder
 
{
  "orderId": "order-12345",
  "orderLineReplacements": [
    {
      "lineItemId": "line-001",
      "quantity": 1,
      "replacementType": "DefectiveItem",
      "replacementReason": "Manufacturing defect"
    }
  ]
}

Error Handling

HTTP Status Codes

CodeMeaning
200Success
400Bad Request - Invalid input data
404Not Found - Order or return not found
500Server Error - Processing failed

Error Response Format

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "status": 400,
  "detail": "Return quantity exceeds available quantity for line item",
  "instance": "/api/returns/order-12345/Return"
}

Common Errors

ErrorCauseSolution
"Order not found"Invalid orderIdVerify order exists and ID is correct
"Return quantity exceeds available"Trying to return more than orderedCheck remaining returnable quantity
"Return type not configured"Invalid returnTypeUse configured return type from settings
"Cannot credit - no captured payment"No payment to refundVerify order has captured payments

Integration Best Practices

1. Always Check Returnable Quantities

Before creating a return, verify the line item has sufficient quantity available for return:

  • Original quantity minus already returned quantity equals returnable quantity

2. Use Appropriate Return Types

Configure return types that match your business processes:

  • StandardReturn: Normal customer returns with restocking fee
  • DefectiveItem: Product defects (no fee, don't restock)
  • WrongItem: Warehouse error (no fee, restock)
  • Exchange: Customer wants different item

3. Handle Workflow Results

Always check the workflow execution results when updating status:

{
  "orderActionExecutionResults": [...],
  "isAborted": false
}

If isAborted is true, some workflow step failed. Check individual step results for details.

4. Use External IDs for Tracking

Add external IDs to link returns with your systems:

{
  "externalIds": [
    { "providerName": "ERP", "id": "ERP-RET-001" },
    { "providerName": "CRM", "id": "CASE-12345" }
  ]
}

5. Configure Webhooks for Real-Time Updates

Set up webhooks to receive notifications when returns change status, rather than polling the search API.