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:
- Create a test SKU.
- Create a test fulfillment center.
- Add inventory to the test SKU at the fulfillment center.
- Create a test order with a quantity less than or equal to the available inventory quantity.
- Acknowledge, ship, and deliver the test order.
Step 1: Authenticate
Generate an OAuth access token to authorize Marketplace sandbox API requests.
Endpoint
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
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
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
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
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
Updated 13 days ago

