Validate returns and refunds in dynamic sandbox

Use this recipe to simulate the end-to-end returns and refunds workflow in the Marketplace sandbox.

This recipe starts with a delivered test order, then walks through initiating a return, shipping and delivering the return, issuing a refund, and verifying that the refund was successfully processed.

Workflow

This workflow validates the complete returns lifecycle, from return initiation through refund verification.

Before you begin

To complete this recipe, you need Marketplace sandbox API credentials and access to the Marketplace sandbox environment. Use your sandbox credentials to generate an OAuth access token before calling the APIs in this workflow.

For more information about sandbox setup and authentication, refer to the Walmart sandbox guide.

Prerequisites

To create the required test resources for this recipe, complete Validate order fulfillment in sandbox.

Before running this recipe, you must complete the following setup:

  1. Create a test SKU.
  2. Create a test fulfillment center.
  3. Add inventory to the test SKU at the fulfillment center.
  4. Create a test order with a quantity less than or equal to the available inventory quantity.
  5. Acknowledge, ship, and deliver the test order.

Step 1: Authenticate

Generate an OAuth access token to authorize Marketplace sandbox API requests.

Endpoint

POST /v3/token

Requirements

  • You must have valid Marketplace sandbox API credentials.
  • The access token must be active when you call each API in this workflow.

Sample request

This sample request uses your Marketplace sandbox client credentials to generate an OAuth access token for subsequent API calls.

curl --location 'https://sandbox.walmartapis.com/v3/token' \ --header 'Accept: application/json' \ --header 'Authorization: Basic <base64(clientId:clientSecret)>' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'WM_MARKET: us' \ --header 'WM_QOS.CORRELATION_ID: <correlation_id>' \ --header 'WM_SVC.NAME: MP' \ --data-urlencode 'grant_type=client_credentials'
import base64
import requests client_id = "clientId"
client_secret = "clientSecret" credentials = base64.b64encode(f"{client_id}:{client_secret}".encode()).decode() url = "https://sandbox.walmartapis.com/v3/token" headers = { "Accept": "application/json", "Authorization": f"Basic {credentials}", "Content-Type": "application/x-www-form-urlencoded", "WM_MARKET": "us", "WM_QOS.CORRELATION_ID": "<correlation_id>", "WM_SVC.NAME": "MP",
} data = { "grant_type": "client_credentials"
} response = requests.post(url, headers=headers, data=data)
response.raise_for_status() print(response.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64; public class TokenRequest { public static void main(String[] args) throws Exception { String clientId = "clientId"; String clientSecret = "clientSecret"; String credentials = Base64.getEncoder().encodeToString( (clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8) ); String formBody = "grant_type=client_credentials"; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://sandbox.walmartapis.com/v3/token")) .header("Accept", "application/json") .header("Authorization", "Basic " + credentials) .header("Content-Type", "application/x-www-form-urlencoded") .header("WM_MARKET", "us") .header("WM_QOS.CORRELATION_ID", "<correlation_id>") .header("WM_SVC.NAME", "MP") .POST(HttpRequest.BodyPublishers.ofString(formBody)) .build(); HttpClient client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); }
}

What to expect

  • The API returns an access token.
  • Use the access token in subsequent API requests in this recipe.

Step 2: Initiate a return

Initiate a return for the delivered test order. The return quantity must be less than or equal to the order quantity.

Endpoint

/v3/simulations/returns

Requirements

  • The order must already be delivered.
  • The return quantity must be less than or equal to the order quantity.

Sample request

This sample request initiates a return for a specific order line by specifying the purchase order ID, line number, return quantity, and return reason.

curl --location --request POST 'https://sandbox.walmartapis.com/v3/simulations/returns' \ --header 'Accept: application/json' \ --header 'WM_SANDBOX: v2' \ --header 'WM_SEC.ACCESS_TOKEN: {{token}}' \ --header 'WM_SVC.NAME: MP' \ --header 'Content-Type: application/json' \ --data-raw '{ "purchaseOrderId": "{{purchaseOrderId}}", "lineNumber": 1, "qty": 10, "returnReason": "WRONG_ITEM" }'
import requests url = "https://sandbox.walmartapis.com/v3/simulations/returns" headers = { "Accept": "application/json", "WM_SANDBOX": "v2", "WM_SEC.ACCESS_TOKEN": "{{token}}", "WM_SVC.NAME": "MP", "Content-Type": "application/json",
} payload = { "purchaseOrderId": "{{purchaseOrderId}}", "lineNumber": 1, "qty": 10, "returnReason": "WRONG_ITEM",
} response = requests.post(url, headers=headers, json=payload)
response.raise_for_status() print(response.status_code)
print(response.text)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse; public class InitiateReturn { public static void main(String[] args) throws Exception { String body = """ { "purchaseOrderId": "{{purchaseOrderId}}", "lineNumber": 1, "qty": 10, "returnReason": "WRONG_ITEM" } """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://sandbox.walmartapis.com/v3/simulations/returns")) .header("Accept", "application/json") .header("WM_SANDBOX", "v2") .header("WM_SEC.ACCESS_TOKEN", "{{token}}") .header("WM_SVC.NAME", "MP") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(body)) .build(); HttpClient client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); }
}

What to expect

  • The return is created successfully.
  • The response includes the return identifier used in subsequent steps.

Step 3: Ship the return

Ship the return to simulate a customer shipping the return.

Endpoint

/v3/simulations/returns

Requirements

  • The return must already be initiated.

Sample request

This sample request updates the return status for a specific return order by specifying the return order ID, order line, return quantity, current status, and return event.

curl --location --request PUT 'https://sandbox.walmartapis.com/v3/simulations/returns' \ --header 'Accept: application/json' \ --header 'WM_SANDBOX: v2' \ --header 'WM_SEC.ACCESS_TOKEN: {{token}}' \ --header 'WM_SVC.NAME: MP' \ --header 'Content-Type: application/json' \ --data-raw '{ "returnOrderId": "{{returnOrderId}}", "lineNumber": 1, "qty": 10, "status": "INITIATED", "eventTag": "RETURN_IN_TRANSIT" }'
import requests url = "https://sandbox.walmartapis.com/v3/simulations/returns" headers = { "Accept": "application/json", "WM_SANDBOX": "v2", "WM_SEC.ACCESS_TOKEN": "{{token}}", "WM_SVC.NAME": "MP", "Content-Type": "application/json",
} payload = { "returnOrderId": "{{returnOrderId}}", "lineNumber": 1, "qty": 10, "status": "INITIATED", "eventTag": "RETURN_IN_TRANSIT",
} response = requests.put(url, headers=headers, json=payload)
response.raise_for_status() print(response.status_code)
print(response.text)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse; public class UpdateReturnStatus { public static void main(String[] args) throws Exception { String body = """ { "returnOrderId": "{{returnOrderId}}", "lineNumber": 1, "qty": 10, "status": "INITIATED", "eventTag": "RETURN_IN_TRANSIT" } """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://sandbox.walmartapis.com/v3/simulations/returns")) .header("Accept", "application/json") .header("WM_SANDBOX", "v2") .header("WM_SEC.ACCESS_TOKEN", "{{token}}") .header("WM_SVC.NAME", "MP") .header("Content-Type", "application/json") .PUT(HttpRequest.BodyPublishers.ofString(body)) .build(); HttpClient client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); }
}

What to expect

  • The return is updated to reflect shipment.

Step 4: Deliver the return

Mark the return as delivered to simulate the returned item being received.

Endpoint

/v3/simulations/returns

Requirements

  • The return must already be shipped.

Sample request

This sample request updates a return to the DELIVERED_AT_RETURN_CENTER event, simulating delivery of the returned item to the return center in the Marketplace sandbox.

curl --location --request PUT 'https://sandbox.walmartapis.com/v3/simulations/returns' \ --header 'Accept: application/json' \ --header 'WM_SANDBOX: v2' \ --header 'WM_SEC.ACCESS_TOKEN: {{token}}' \ --header 'WM_SVC.NAME: MP' \ --header 'Content-Type: application/json' \ --data-raw '{ "returnOrderId": "{{returnOrderId}}", "lineNumber": 1, "qty": 10, "status": "DELIVERED", "eventTag": "DELIVERED_AT_RETURN_CENTER" }'
import requests url = "https://sandbox.walmartapis.com/v3/simulations/returns" headers = { "Accept": "application/json", "WM_SANDBOX": "v2", "WM_SEC.ACCESS_TOKEN": "{{token}}", "WM_SVC.NAME": "MP", "Content-Type": "application/json",
} payload = { "returnOrderId": "{{returnOrderId}}", "lineNumber": 1, "qty": 10, "status": "DELIVERED", "eventTag": "DELIVERED_AT_RETURN_CENTER",
} response = requests.put(url, headers=headers, json=payload)
response.raise_for_status() print(response.status_code)
print(response.text)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse; public class DeliverReturn { public static void main(String[] args) throws Exception { String body = """ { "returnOrderId": "{{returnOrderId}}", "lineNumber": 1, "qty": 10, "status": "DELIVERED", "eventTag": "DELIVERED_AT_RETURN_CENTER" } """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://sandbox.walmartapis.com/v3/simulations/returns")) .header("Accept", "application/json") .header("WM_SANDBOX", "v2") .header("WM_SEC.ACCESS_TOKEN", "{{token}}") .header("WM_SVC.NAME", "MP") .header("Content-Type", "application/json") .PUT(HttpRequest.BodyPublishers.ofString(body)) .build(); HttpClient client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); }
}

What to expect

  • The return is marked as delivered.
  • The return is ready for refund processing.

Step 5: Issue a refund

Issue a refund for the delivered return.

Endpoint

/v3/returns/{returnOrderId}/refund

Requirements

  • The return must already be delivered.
  • Use the return identifier created earlier in this recipe.

Sample request

This sample request issues a refund for a returned item by specifying the return order, customer order, and refund quantity.

curl --location --request POST 'https://sandbox.walmartapis.com/v3/returns/{{returnOrderId}}/refund' \ --header 'Accept: application/json' \ --header 'WM_SANDBOX: v2' \ --header 'WM_SEC.ACCESS_TOKEN: {{token}}' \ --header 'WM_SVC.NAME: MP' \ --header 'Content-Type: application/json' \ --header 'WM_QOS.CORRELATION_ID: test-correlation-id' \ --data-raw '{ "customerOrderId": "{{customerOrderId}}", "refundLines": [ { "returnOrderLineNumber": 1, "quantity": { "unitOfMeasure": "EACH", "measurementValue": 10 } } ] }'
import requests url = "https://sandbox.walmartapis.com/v3/returns/{{returnOrderId}}/refund" headers = { "Accept": "application/json", "WM_SANDBOX": "v2", "WM_SEC.ACCESS_TOKEN": "{{token}}", "WM_SVC.NAME": "MP", "Content-Type": "application/json", "WM_QOS.CORRELATION_ID": "test-correlation-id",
} payload = { "customerOrderId": "{{customerOrderId}}", "refundLines": [ { "returnOrderLineNumber": 1, "quantity": { "unitOfMeasure": "EACH", "measurementValue": 10, }, } ],
} response = requests.post(url, headers=headers, json=payload)
response.raise_for_status() print(response.status_code)
print(response.text)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse; public class IssueRefund { public static void main(String[] args) throws Exception { String body = """ { "customerOrderId": "{{customerOrderId}}", "refundLines": [ { "returnOrderLineNumber": 1, "quantity": { "unitOfMeasure": "EACH", "measurementValue": 10 } } ] } """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://sandbox.walmartapis.com/v3/returns/{{returnOrderId}}/refund")) .header("Accept", "application/json") .header("WM_SANDBOX", "v2") .header("WM_SEC.ACCESS_TOKEN", "{{token}}") .header("WM_SVC.NAME", "MP") .header("Content-Type", "application/json") .header("WM_QOS.CORRELATION_ID", "test-correlation-id") .POST(HttpRequest.BodyPublishers.ofString(body)) .build(); HttpClient client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); }
}

What to expect

  • The refund is issued successfully.
  • Refund information is associated with the return.

Step 6: Verify the refund

Call the returns API to verify that the refund was issued.

Endpoint

/v3/returns

Requirements

  • The refund must already be issued.
  • Use the return identifier from the return created earlier in this recipe.

Sample request

This sample request retrieves return details to verify that the refund was successfully issued for the returned item.

curl --location --request GET 'https://sandbox.walmartapis.com/v3/returns' \ --header 'Accept: application/json' \ --header 'WM_SANDBOX: v2' \ --header 'WM_SVC.NAME: MP' \ --header 'WM_SEC.ACCESS_TOKEN: {{token}}' \ --header 'WM_QOS.CORRELATION_ID: test-correlation-id'
import requests url = "https://sandbox.walmartapis.com/v3/returns" headers = { "Accept": "application/json", "WM_SANDBOX": "v2", "WM_SVC.NAME": "MP", "WM_SEC.ACCESS_TOKEN": "{{token}}", "WM_QOS.CORRELATION_ID": "test-correlation-id",
} response = requests.get(url, headers=headers)
response.raise_for_status() print(response.status_code)
print(response.text)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse; public class GetReturns { public static void main(String[] args) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://sandbox.walmartapis.com/v3/returns")) .header("Accept", "application/json") .header("WM_SANDBOX", "v2") .header("WM_SVC.NAME", "MP") .header("WM_SEC.ACCESS_TOKEN", "{{token}}") .header("WM_QOS.CORRELATION_ID", "test-correlation-id") .GET() .build(); HttpClient client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); }
}

What to expect

  • The API returns the return details.
  • The response confirms that the refund was issued.

Verify the results

After completing this recipe, verify that:

  • The return was successfully initiated.
  • The return progressed through shipment and delivery.
  • A refund was issued successfully.
  • The Get Return API confirms that the refund was issued.

Next steps

Now that you have validated the returns and refunds workflow, you can continue testing additional sandbox workflows:

  • Validate order fulfillment in sandbox.
  • Validate inventory reservations, decrements, and stockouts.

Related resources




Did this page help you?