Third party coordinated returns

Learn how notify Digital River of returns when you have a third-party fulfiller.

If you're using a third-party reverse logistics service, then you can use the Returns API to help manage the returns and refunds process.

Once a customer's request to return purchased products is approved, use this API to first notify Digital River that you authorized a return and then, after the returned goods have been received, inspected, and signed off, move them into an accepted state.

Once all the authorized goods are accepted, Digital River creates one or more refund pending events that you can listen for with a configurable webhook.

On this page, you'll find information on:

Authorizing returns

If customers request a return, and you authorize their request, your order management system should define and create a return authorization in Digital River's system.

Defining a return authorization

In a POST /returns, you're required to provide an order identifier as well as line item data. You can optionally specify a return reason and location.

Order identifier

The request must contain the orderId associated with the products that are being returned.

Items

For each items[], define itemId or skuId and the quantity of goods authorized for return.

Reason and location

You can optionally provide a return reason and location. Both of these are pass-through values, but can be useful for tracking, customer notifications, and record keeping purposes.

Creating a return authorization

To create a return authorization, send your secret API key and request payload in a POST /returns.

curl --location --request POST 'https://api.digitalriver.com/returns' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{secretKey}}' \
...
--data-raw '{
  "orderId": "215146200336",
  "reason": "Incorrect size",
  "items":
    [
      {
        "itemId": "139723170336",
        "quantity": "2"
      },
      {
        "itemId": "139723180336",
        "quantity": "2"
      }
    ]
}'

If items[].quantity exceeds the quantity that's eligible for return, you receive the following error:

409 Conflict
{
    "type": "conflict",
    "errors": [
        {
            "code": "quantity_too_large",
            "parameter": "items[0].qty",
            "message": "Return quantity is larger than order quantity"
        }
    ]
}

Return authorization

Once the request is successfully submitted, Digital River sets the state of the return and each of its items[] to created and generates an event with a type of return.created.

In items[], the quantityAccepted represents the number of products that have been received and accepted. In the 201 Created, it's always 0 but may increase, depending on the results of the return acceptance process.

Each items[] in the response contains a skuId , which you can use to make a GET/skus/{id} request and access product data.

Return
{
    "id": "ret_ea359ea9-b768-42fd-a48a-dc57f59b3d50",
    "createdTime": "2022-02-02T16:57:13Z",
    "currency": "USD",
    "items": [
        {
            "itemId": "139723170336",
            "amount": 21.62,
            "quantity": 2,
            "quantityAccepted": 0,
            "skuId": "5cd94c9b-82d7-4194-bd3f-48f33c6b7420",
            "state": "created"
        },
        {
            "itemId": "139723180336",
            "amount": 21.62,
            "quantity": 2,
            "quantityAccepted": 0,
            "skuId": "5c52b10b-4656-4234-8d0e-9e63f012bc72",
            "state": "created"
        }
    ],
    "orderId": "215146200336",
    "reason": "Incorrect size",
    "state": "created",
    "liveMode": false
}n

Accepting returns

If customers follow the instructions you provided on how to return their goods, and they arrive in the expected quantity and quality, you'll need to notify Digital River that the return is accepted so that we can issue a refund.

How you do this depends on whether the goods arrive in a single shipment or multiple shipments.

Single shipment returns

If the full quantity of goods specified in the return authorization arrives in a single shipment, and you or your third-party reverse logistics service accepts their condition, send a POST /returns/{id} with state set to accepted in the body of the request:

curl --location --request POST 'https://api.digitalriver.com/returns/ret_e4dc1cb7-f8ac-488d-99bf-e14fa1162482' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{secretKey}}' \
...
--data-raw '{
    "state": "accepted"
}'

Digital River handles your request by setting the state of the return and each of its items[] to accepted, and then creating two types of events, return.accepted and refund.pending.

If the refund is successfully processed, refund.complete is next created. If, for some reason, it's not, then you'll need to handle refund.failed.

{
    "id": "ret_e4dc1cb7-f8ac-488d-99bf-e14fa1162482",
    "createdTime": "2022-02-17T21:12:33Z",
    "currency": "USD",
    "items": [
        {
            "itemId": "142042680336",
            "amount": 21.61,
            "quantity": 2,
            "quantityAccepted": 2,
            "skuId": "2cf3d5c0-c8ef-4df7-9e6f-470b469583f9",
            "state": "accepted"
        },
        {
            "itemId": "142042690336",
            "amount": 48.61,
            "quantity": 3,
            "quantityAccepted": 3,
            "skuId": "b3bccc18-cac8-4066-8304-e7d0ea615edd",
            "state": "accepted"
        }
    ],
    "orderId": "217222390336",
    "reason": "Damaged Goods",
    "state": "accepted",
    "liveMode": false
}

Multiple shipment returns

If the goods in the return authorization don't all arrive in a single shipment, you or your third-party reverse logistics service can accept each item separately.

For example, you might have created a return authorization that contains two items[].

Return authorization
{
    "id": "ret_b4e2a7f9-82f5-4133-bbcf-4423e8fae4d1",
    "createdTime": "2022-02-21T19:06:23Z",
    "currency": "USD",
    "items": [
        {
            "itemId": "142282650336",
            "amount": 21.62,
            "quantity": 2,
            "quantityAccepted": 0,
            "skuId": "8dfbf79b-658d-4ee4-bada-9c7f476b84e4",
            "state": "created"
        },
        {
            "itemId": "142282660336",
            "amount": 64.83,
            "quantity": 3,
            "quantityAccepted": 0,
            "skuId": "66ec1069-7afe-48f6-87f2-4df8c723eef0",
            "state": "created"
        }
    ],
    "orderId": "217431410336",
    "reason": "Products don't match description",
    "state": "created",
    "liveMode": false
}

For the first items[] in this example, the full, authorized quantity might arrive in an initial shipment that doesn't contain any products from the second items[].

To handle this, in the body of an update return request, set the quantity of the first items[] to the appropriate value and it's state to accepted.

curl --location --request POST 'https://api.digitalriver.com/returns/ret_b4e2a7f9-82f5-4133-bbcf-4423e8fae4d1' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{secretKey}}' \
...
--data-raw '{
    "items": [
        {
            "itemId": "142282650336",
            "quantity": "2",
            "state":"accepted"
        }
    ]
}'

Since the second items[] is not yet accepted, the refund.pending event isn't created.

Return
{
    "id": "ret_b4e2a7f9-82f5-4133-bbcf-4423e8fae4d1",
    "createdTime": "2022-02-21T19:06:23Z",
    "currency": "USD",
    "items": [
        {
            "itemId": "142282650336",
            "amount": 21.61,
            "quantity": 2,
            "quantityAccepted": 2,
            "skuId": "8dfbf79b-658d-4ee4-bada-9c7f476b84e4",
            "state": "accepted"
        },
        {
            "itemId": "142282660336",
            "amount": 64.82,
            "quantity": 3,
            "quantityAccepted": 0,
            "skuId": "66ec1069-7afe-48f6-87f2-4df8c723eef0",
            "state": "created"
        }
    ],
    "orderId": "217431410336",
    "reason": "Products don't match description",
    "state": "created",
    "liveMode": false
}

If the remainder of products authorized for return arrive in a second shipment, then submit another update request that sets the quantity of that items[] to the appropriate value and it's state to accepted.

curl --location --request POST 'https://api.digitalriver.com/returns/ret_b4e2a7f9-82f5-4133-bbcf-4423e8fae4d1' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{secretKey}}' \
...
--data-raw '{
    "items": [
        {
            "itemId": "142282660336",
            "quantity": "3",
            "state":"accepted"
        }
    ]
}'

A successful request moves the return's state to accepted and generates return.accepted as well as one or more refund.pending events, each containing unique refunds.

{
    "id": "ret_b4e2a7f9-82f5-4133-bbcf-4423e8fae4d1",
    "createdTime": "2022-02-21T19:06:23Z",
    "currency": "USD",
    "items": [
        {
            "itemId": "142282650336",
            "amount": 21.61,
            "quantity": 2,
            "quantityAccepted": 2,
            "skuId": "8dfbf79b-658d-4ee4-bada-9c7f476b84e4",
            "state": "accepted"
        },
        {
            "itemId": "142282660336",
            "amount": 64.82,
            "quantity": 3,
            "quantityAccepted": 3,
            "skuId": "66ec1069-7afe-48f6-87f2-4df8c723eef0",
            "state": "accepted"
        }
    ],
    "orderId": "217431410336",
    "reason": "Products don't match description",
    "state": "accepted",
    "liveMode": false
}

What conditions trigger a refund

Refunds are only created when a return's state moves to accepted. For this to occur, each items[].state in that resource must also be accepted. To make that happen, the authorized quantity of each items[] must be equal to its quantityAccepted.

In other words, the Returns API is designed to handle the scenario where the full quantity of goods in a return authorization is sent back and approved and only then is the customer issued a refund.

If you'd like to provide refunds on partial returns, then your application should use the Refunds API. For details, refer to Issuing refunds.

Return
{
    "id": "ret_b4e2a7f9-82f5-4133-bbcf-4423e8fae4d1",
    "createdTime": "2022-02-21T19:06:23Z",
    "currency": "USD",
    "items": [
        {
            "itemId": "142282650336",
            "amount": 21.61,
            "quantity": 2,
            "quantityAccepted": 2,
            "skuId": "8dfbf79b-658d-4ee4-bada-9c7f476b84e4",
            "state": "accepted"
        },
        {
            "itemId": "142282660336",
            "amount": 64.82,
            "quantity": 3,
            "quantityAccepted": 3,
            "skuId": "66ec1069-7afe-48f6-87f2-4df8c723eef0",
            "state": "accepted"
        }
    ],
    "orderId": "217431410336",
    "reason": "Products don't match description",
    "state": "accepted",
    "liveMode": false
}

Last updated