Integrate with an order management system

Once an order is created, your external order management system (OMS) is the system of record and is responsible for fulfilling the order.

Communication between Oracle Commerce and the OMS is handled as follows:

  • Oracle Commerce uses webhooks to send order data to your OMS or to a gateway that transmits the data to the OMS.
  • The order management system implements the Oracle Commerce Admin REST API to update the order’s status information as the order is processed.

You need to configure your OMS or gateway to convert the data received from Oracle Commerce into the format used by the OMS, and to set up the OMS to make calls to the Oracle Commerce REST APIs to update the status of the order. Note that for certain order management systems, optional integration software is available to simplify this process.

Configure the integration points

Follow these steps to enable Oracle Commerce to communicate with your order management system:

  1. Configure the webhooks you intend to use. At a minimum, you will need to configure the Order Submit webhook. If your store includes the Agent Console, you should also configure the Return Request Update webhook.

    To configure a webhook, you supply the URL to direct POST requests to, the headers to include, and authentication information. The values to supply are determined by your OMS. See Configure Webhooks for more information.

  2. Register your OMS application with Oracle Commerce. Doing this generates an application ID and an application key that the OMS can use for authentication when it makes REST calls to Oracle Commerce. See Register applications for more information.

Order Submit webhook

When an order is submitted, the Order Submit webhook sends a POST request to the URL you have configured. (Typically this is the URL where your OMS or gateway listens for requests.) The body of the request contains the complete order data in JSON format. The order management system converts the JSON data into the system’s native format, and returns an HTTP status code indicating whether the data was received successfully. A 200-level status code indicates the POST was successful. Any other code indicates failure; if this occurs, Order Submit sends the POST request again. The webhook is executed up to five times until it succeeds or gives up.

Not all external systems you integrate with Oracle Commerce will comply with the Payment Card Industry Data Security Standard (PCI DSS). For example, while your order management system will likely comply with PCI DSS, systems that manage services like email marketing or customer loyalty programs might not be compliant. Oracle Commerce provides versions of the Order Submit webhook that exclude payment details from the order data you send to systems that do not comply with PCI DSS. See Understand webhooks and PCI DSS compliance for more information.

Order Submit request example

The following example shows the body of an Order Submit webhook POST request from Oracle Commerce. The request body is a JSON representation of the order.

{
    "site": {
        "siteURL": "http://www.example.com",
        "siteName": "Commerce Site"
    },
    "order": {
        "lastModifiedTime": 1403734373592,
        "shippingGroupCount": 1,
        "paymentGroupCount": 1,
        "shippingGroups": [
            {
                "specialInstructions": {},
                "id": "sg20005",
                "handlingInstructions": [],
                "trackingNumber": null,
                "priceInfo": {
                    "amount": 6.5,
                    "currencyCode": "USD",
                    "amountIsFinal": false,
                    "discounted": false,
                    "rawShipping": 6.5
                },
                "description": "sg20005",
                "state": 0,
                "locationId": null,
                "actualShipDate": null,
                "submittedDate": null,
                "shipOnDate": null,
                "shippingMethod": "ground",
                "shippingAddress": {
                    "middleName": "",
                    "lastName": "Smith",
                    "ownerId": null,
                    "state": "Alaska",
                    "address1": "101 TNT Dr",
                    "address2": "",
                    "address3": "",
                    "companyName": "",
                    "suffix": "",
                    "country": "United States",
                    "city": "Birmingham",
                    "id": null,
                    "postalCode": "99672",
                    "faxNumber": "",
                    "phoneNumber": "555-555-1212",
                    "county": "",
                    "email": "home@example.com",
                    "prefix": "",
                    "firstName": "Jean",
                    "jobTitle": ""
                },
                "stateDetail": null
            }
        ],
        "commerceItems": [
            {
                "id": "ci2000007",
                "productDisplayName": "Military Jacket",
                "returnedQuantity": 0,
                "priceInfo": {
                    "quantityDiscounted": 0,
                    "amount": 291,
                    "discountable": true,
                    "onSale": false,
                    "priceListId": "listPrices",
                    "currencyCode": "USD",
                    "rawTotalPrice": 291,
                    "listPrice": 145.5,
                    "amountIsFinal": false,
                    "discounted": false,
                    "currentPriceDetailsSorted": [
                        {
                            "amount": 291,
                            "itemPriceInfo": null,
                            "currencyCode": "USD",
                            "range": {
                                "lowBound": 0,
                                "class": "atg.core.util.Range",
                                "highBound": 1,
                                "size": 2
                            },
                            "tax": 0,
                            "amountIsFinal": false,
                            "discounted": false,
                            "quantity": 2,
                            "detailedUnitPrice": 145.5
                        }
                    ],
                    "salePrice": 0
                },
                "catalogId": null,
                "quantity": 2,
                "catalogKey": null,
                "catalogRefId": "sku40139",
                "productId": "prod20012"
            },
        ],
        "id": "o20005",
        "siteId": "siteUS",
        "priceInfo": {
            "total": 268.4,
            "amount": 261.9,
            "shipping": 6.5,
            "currencyCode": "USD",
            "tax": 0,
            "amountIsFinal": false,
            "discounted": true,
            "manualAdjustmentTotal": 0,
            "rawSubtotal": 291,
            "discountAmount": 29.1
        },
        "paymentGroups": [
            {
                "authorizationStatus": [
                    {
                        "errorMessage": "Request was processed successfully.",
                        "amount": 261.9,
                        "authorizationDecision": "ACCEPT",
                        "transactionId": "4037343708700178147626",
                        "reasonCode": "100",
                        "currency": "USD",
                        "transactionSuccess": true
                    }
                ],
                "currencyCode": "USD",
                "paymentId": "pg20005",
                "state": 1,
                "amountAuthorized": 261.9,
                "amount": 297.5,
                "id": "pg20005",
                "phoneNumber": "555-555-1212",
                "token": "9997000107329795",
                "expirationYear": "2021",
                "expirationMonth": "08",
                "submittedDate": {
                    "time": 1403734373000
                },
                "creditCardNumber": "1111",
                "paymentMethod": "tokenizedCreditCard"
            }
        ],
        "taxPriceInfo": {
            "amount": 0,
            "currencyCode": "USD",
            "countyTax": 0,
            "countryTax": 0,
            "amountIsFinal": false,
            "stateTax": 0,
            "discounted": false,
            "cityTax": 0,
            "districtTax": 0
        },
        "profileId": "120023",
        "creationTime": 1403734364000,
        "relationships": [
            {
                "amount": 0,
                "id": "r20003",
                "returnedQuantity": 0,
                "relationshipType": "SHIPPINGQUANTITY",
                "shippingGroupId": "sg20005",
                "quantity": 2,
                "commerceItemId": "ci2000007"
            },
            {
                "amount": 0,
                "id": "r20004",
                "returnedQuantity": 0,
                "relationshipType": "SHIPPINGQUANTITY",
                "shippingGroupId": "sg20005",
                "quantity": 1,
                "commerceItemId": "ci2000008"
            },
            {
                "id": "r20005",
                "amount": 261.9,
                "relationshipType": "ORDERAMOUNTREMAINING",
                "paymentGroupId": "pg20005",
                "orderId": "o20005"
            }
        ],
        "totalCommerceItemCount": 2
    }
}

Order Management REST APIs

Once the order data is successfully received by the order management system, any further processing of the order occurs in the OMS. For example, the status of the order changes in the OMS when payment is received and when the order is shipped.

To keep the order up to date in Oracle Commerce, the OMS can submit requests to the endpoints of the Orders resource when changes occur to the order. Typically, the update will involve changing the values of properties that store information about the state of either the order itself or components of the order, such as shipping groups. For example, when the OMS begins processing the order, it can use a PUT request to change the state property of the order object from SUBMITTED to PROCESSING:

PUT /ccadmin/v1/orders/o10406 HTTP/1.1
Authorization: Bearer <access_token>
x-ccasset-language: en
Content-Type: application/json

{"state": "PROCESSING"}

The properties of an order are described in the documentation for the /ccadmin/v1/orders/{id} endpoint. (See Learn about the APIs for information about accessing endpoint documentation.) For information about the available states for orders and order components, see Understand order states.

Keep the following in mind when writing PUT requests with the Commerce REST APIs:

  • The request typically does not need to include properties you are not updating. However, if the request includes a list or map property, that property must contain references to all the members of the list or map that should be retained. Even if you want to update only one item out of a list of 20, you must provide enough data to match the other 19 existing list members.
  • References to an existing list member must contain enough data to match the item with an existing item. If no match can be found, a new item will be created.
  • A request that includes a representation of an empty list or map removes all members of that list or map.

Return Request webhooks

An order or portion of an order is eligible for return only if it has been fulfilled and the items to be returned have not previously been returned. Even if it meets these conditions, the order may not be returnable (for example, if too much time has elapsed since the order was fulfilled), or individual items may not be returnable (for example, if a product or SKU’s Not Returnable property is set to true, or if the OMS determines an item cannot be returned).

Oracle Commerce includes two webhooks that you can use to communicate with an order management system to process returns:

  • The Return Request Validation webhook is a function webhook that queries the OMS to determine whether the order is returnable, and receives data back from the OMS indicating which items can be returned.
  • The Return Request Update webhook is an event webhook that submits a return request to the OMS when it is initiated by a shopper or agent.

These webhooks can be used together to help manage returns. For example, the Return Request Validation webhook can be used to determine which items in the order are returnable, and therefore are eligible for inclusion in the return request. The Return Request Update webhook can then be used to notify the OMS once the return request is created.

To enable these webhooks, you configure them with the URL where your OMS or gateway listens for requests. The webhooks send data to the OMS as POST requests containing JSON data. The OMS may need to be configured to convert the JSON data into the system’s native format.

Note: Oracle Commerce also provides versions of the Return Request Validation and Return Request Update webhooks that exclude payment details from the order data you send to systems that do not comply with PCI DSS. See Understand webhooks and PCI DSS compliance for more information.

Return Request Validation webhook

The Return Request Validation webhook is automatically invoked when Commerce needs to determine which items in an order are returnable. (For example, when displaying the order history, the webhook is used to determine whether to display a Return button next to an order). The webhook can also be invoked manually using the Return Requests endpoints in the Store REST API. These endpoints enable your store to accommodate a variety of different return workflows, such as shopper-initiated returns.

The webhook payload includes a context property that specifies the operation being performed. The following are the valid values for this property when validating a return request:

  • Initiate_Return -- check if the order and its items are eligible for return
  • CalculateRefund_Return -- determine refund amount
  • Submit_Return -- validate the return request prior to creating it or saving the changes
  • Custom_Return -- trigger the webhook from the Store API

The following are the valid values for this property when validating an exchange request:

  • Initiate_Exchange -- check if the order and its items are eligible for exchange
  • Submit_Exchange -- validate the exchange request prior to creating it or saving changes
  • Process_Exchange -- validate that the exchange should be fulfilled once the returned goods are received

The following example shows a portion of the webhook payload that lists the items to determine the return eligibility of:

{
  "context": "Initiate_Return",
  "returnRequests": [
    {
      "returnItemList": [
        {
          "quantityToReturn": 0,
          "commerceItemId": "ci3000416",
          "quantityAvailable": 20,
          "quantityShipped": 20,
          "productId": "Product_27Fxyzii",
          "nonreturnable": true,
          "returnReason": null,
          "shippingGroupId": "sg40414",
          "catalogRefId": "Sku_27Gxyzii",
          "nonReturnableReason": "This is a non-returnable item."
        },
        {
          "quantityToReturn": 0,
          "commerceItemId": "ci3000417",
          "quantityAvailable": 15,
          "quantityShipped": 20,
          "productId": "Product_36Exy",
          "nonreturnable": false,
          "returnReason": null,
          "shippingGroupId": "sg40414",
          "catalogRefId": "Sku_36Fxy",
          "nonReturnableReason": null
        }
      ],
. . .

The response from the OMS indicates whether the individual items are eligible for return, and whether the order as a whole is returnable. (For example, the items might be eligible for return, but the order might not be returnable if too much time has elapsed since it was fulfilled.) The response can optionally include a return authorization number, a tracking number, a URL for accessing a return shipping label, and additional data that can be displayed to the shopper. It can also override the values of the nonreturnable flag from the request.

The following is a sample response returned by the OMS:

{
  "context": "Initiate_Return",
  "returnRequests": [
    {
      "returnItemList": [
        {
          "shippingGroupId": "sg40414",
          "productId": "Product_27Fxyzii",
          "nonreturnable": true,
          "nonReturnableReason": "This is a returnable item",
          "additionalProperties": {
            "name1": "value1",
            "name2": "value2"
          },
          "quantityAvailable": 1,
          "commerceItemId": "ci3000416"
        },
        {
          "shippingGroupId": "sg40414",
          "productId": "Product_36Exy",
          "nonreturnable": false,
          "nonReturnableReason": "This is a returnable item",
          "additionalProperties": {
            "name1": "value1",
            "name2": "value2"
          },
          "quantityAvailable": 1,
          "commerceItemId": "ci3000417"
        }
      ],
      "orderId": "o30411",
      "rma": "12345",
      "trackingNumber": "1234567890",
      "returnLabel": "a5445afg5",
      "nonReturnableReason": "Order exceeded no of days",
      "nonreturnable": false,
      "additionalProperties": {
        "name1": "value1",
        "name2": "value2"
      }
    }
  ]
}

Notice that this response indicates the individual items are both eligible for return (that is, they are not nonreturnable items), and that the order as a whole can be returned.

Return Request Update webhook

When a customer service agent or a shopper creates a return request or exchange request, the Return Request Update webhook sends a request to the OMS. The body of the request contains the following data:

  • The complete order data from the original Order Submit POST request.
  • The new or updated return or exchange request.
  • For an exchange request, the new order data from the exchange.

The order management system should return an HTTP status code indicating whether the data was received successfully. A 200-level status code indicates the POST was successful. Any other code indicates failure; if this occurs, Return Request Update sends the request again. The webhook is executed up to five times until it succeeds or gives up.

Update the return request

Once the return request is received, the OMS is responsible for managing the return process. However, you may want Oracle Commerce to receive progress updates, so you can reflect the status of the return in the shopper’s order history.

To update the return request in Commerce, the OMS can submit requests to the updateReturnRequest endpoint in the Admin API. For example, after the OMS authorizes the return, it can send Commerce the tracking number and related information:

PUT /ccadmin/v1/returnRequests/200001  HTTP/1.1
Authorization: Bearer <access_token>
x-ccasset-language: en
Content-Type: application/json

{
  "shippingTaxRefund": 0,
  "agentId": "service",
  "secondaryCurrencyShippingTaxRefund": 0,
  "actualShippingRefund": 12.5,
  "actualTaxRefund": 4,
  "otherRefund": 0,
  "secondaryCurrencyActualTaxRefund": 0,
  "refundMethodList": [
    {
      "refundType": "manualRefund",
      "amount": 66.49,
      "state": "INCOMPLETE"
    }
  ],
  "returnLabel": "https://www.example.com/returnLabel/234977gege4",
  "authorizationNumber": "200001",
  "returnFee": 0,
  "requestId": "200001",
  "secondaryCurrencyActualShippingRefund": 0,
  "links": [
    {
      "rel": "self",
      "href": "http://www.example.com/ccadmin/v1/returnRequests/200001"
    }
  ],
  "state": "PENDING_CUSTOMER_ACTION",
  "additionalProperties": {
    "key1": "value1"
  },
  "originOfReturn": "contactCenter",
  "trackingNumber": "178923",
  "returnItemList": [
    {
      "secondaryCurrencyActualTaxRefundShare": 0,
      "comments": null,
      "shippingGroupId": "sg70428",
      "secondaryCurrencyActualShippingSurchargeRefundShare": 0,
      "quantityWithFractionReceived": 0,
      "commerceItemId": "ci6000446",
      "secondaryCurrencyActualShippingRefundShare": 0,
      "actualShippingSurchargeRefundShare": 0,
      "returnReason": "defective",
      "actualShippingRefundShare": 12.5,
      "state": "AWAITING_RETURN",
      "additionalProperties": {},
      "actualTaxRefundShare": 4,
      "quantityReceived": 0,
      "refundAmount": 49.99
    }
  ],
  "actualShippingSurchargeRefund": 0,
  "secondaryCurrencyActualShippingSurchargeRefund": 0
}

At later stages of the return process, the OMS can use this endpoint to provide further updates, such as notification when the returned item has been received, and notification when a refund has been issued. Typically the OMS will update the return state (which describes the return as a whole) and the return item states (which describes each return item individually) at these times.

The following are the valid return states and return item states:

  • Return states: MANUAL_REFUND, PENDING_REFUND, INCOMPLETE, COMPLETE, FULL_RETURN, PARTIAL_RETURN, PENDING_CUSTOMER_ACTION.
  • Return item states: RETURN_NOT_REQUIRED, AWAITING_RETURN, PARTIAL_RETURN, RETURNED, INITIAL.

By default, the following are the valid values for the returnReason property, which indicates why the shopper returned the item: defective, didNotLike, didNotMeetExpectations, incorrectColor, incorrectItem, incorrectSize. You can use the Reasons endpoints in the Admin REST API to add, delete, or inactivate individual return reasons. For example, to make the defective value inactive:

PUT /ccadmin/v1/reasons?type=returnReasons&id=defective
Authorization: Bearer <access_token>
x-ccasset-language: en
Content-Type: application/json

{
  "readableDescription": "Defective",
  "active": false,
  "description": "defective"
}

Note that the getReturnRequest and updateReturnRequest endpoints cannot be used in preview mode. For more information about these endpoints, including a list of the fields that can be updated, see the REST API documentation in the Oracle Help Center.

Update refund amounts

Refund amounts can be calculated and issued by either Commerce or by the OMS system. To calculate and issue refunds in Commerce, use the Agent Console or the receiveReturnRequest endpoint in the Agent API to indicate that the returned items have been received. Then start the refund process by calling the updateReturnRequest endpoint in the Agent API with the op value set to initiateRefund.

If refunds are calculated and issued by the OMS, use the Agent Console or the receiveReturnRequest endpoint in the Agent API to indicate that the returned items have been received. Then use the updateReturnRequest endpoint in the Admin API to update the refund-related fields in Commerce, and the updateOrder endpoint in the Admin API to update the amountCredited in the payment group of the original order.