Resolving Return Request Cancellation Errors in ESHOPMAN Admin
Efficient return management is a cornerstone of excellent customer service in any e-commerce operation. For ESHOPMAN merchants, the ability to quickly and accurately process or cancel return requests directly impacts customer satisfaction and operational efficiency. However, a specific scenario has been identified within the ESHOPMAN Admin interface where canceling a return request can lead to an unexpected error message.
The Challenge: Unexpected Error During Return Cancellation
A user within the ESHOPMAN community reported an issue when attempting to cancel a return request that was in the 'requested' status. Despite no fulfillments being associated with the return itself (only the original outbound delivery fulfillment), the system returned an error preventing the cancellation.
The specific error message encountered was:
{
"type": "not_allowed",
"message": "All fulfillments must be canceled before canceling a return"
}This behavior can be confusing for merchants and administrators, as the return request is merely a pending action, not one that involves existing fulfillments that need to be undone.
Technical Deep Dive: The Admin API Interaction
Upon investigation, it was observed that when the 'Cancel' button is clicked within the order details activity timeline in the ESHOPMAN Admin, the system makes an API call to:
POST /admin/returns/return_ID/cancelThis endpoint is designed to cancel a return that has already been processed or has associated fulfillments. For a return request that is still in the 'requested' state, and has not yet been received or processed, the appropriate action should be to cancel the *request* itself. This typically corresponds to a different Admin API endpoint, such as:
DELETE /admin/returns/return_ID/requestThe discrepancy lies in the Admin UI triggering the POST /cancel endpoint, which correctly enforces the rule that any existing fulfillments related to that return must first be canceled. Since a 'requested' return has no such fulfillments, this rule becomes a blocker for what should be a straightforward cancellation of a pending request.
Impact and Community Resolution
This issue highlights a critical interaction point between the ESHOPMAN Admin UI and its underlying Node.js/TypeScript-based Admin API. While the API endpoint itself functions as designed for its intended purpose, the UI's invocation of the incorrect endpoint for a 'requested' return leads to a functional bottleneck for merchants.
The ESHOPMAN development team is aware of this behavior, and it has been noted as consistent with other reported instances within the community. Addressing this requires an update to the ESHOPMAN Admin application to ensure the correct API endpoint is called based on the return's status, allowing for seamless cancellation of pending return requests.
Underlying Platform Environment
For context, the environment where this issue was observed included:
- Node.js version: v24
- Backend Infrastructure: ESHOPMAN Cloud
- Browser: Chrome
The core ESHOPMAN platform leverages a robust Node.js/TypeScript architecture, as reflected in its dependency structure:
{
"name": "my-project",
"version": "0.0.24",
"description": "My Project",
"scripts": {
"build": "eshopman build",
"predeploy": "eshopman db:migrate",
"seed": "eshopman exec ./src/scripts/seed.ts",
"test:smtp": "eshopman exec ./src/scripts/test-smtp.ts",
"start": "eshopman start",
"dev": "eshopman develop",
"deploy:staging": "./scripts/deploy-staging.sh",
"deploy:production": "./scripts/deploy-production.sh",
"test": "yarn test:unit",
"test:ci": "COVERAGE=true TEST_TYPE=unit NODE_OPTI jest --silent --maxWorkers=50% --forceExit",
"test:integration:http": "TEST_TYPE=integration:http NODE_OPTI jest --silent=false --runInBand --forceExit",
"test:integration:modules": "TEST_TYPE=integration:modules NODE_OPTI jest --silent --runInBand --forceExit",
"test:unit": "TEST_TYPE=unit NODE_OPTI jest --silent --maxWorkers=50% --forceExit",
"test:unit:watch": "TEST_TYPE=unit NODE_OPTI jest --silent --watch --maxWorkers=25%",
"type-check": "tsc --noEmit",
"lint": "yarn quality",
"lint:fix": "biome lint --write .",
"format": "biome format --write .",
"format:check": "biome format .",
"check": "biome check .",
"check:fix": "biome check --write .",
"quality": "biome ci ."
},
"dependencies": {
"@aws-sdk/client-dynamodb": "^3.0.0",
"@eshopman/admin-sdk": "2.13.1",
"@eshopman/auth": "2.13.1",
"@eshopman/auth-emailpass": "2.13.1",
"@eshopman/auth-google": "2.13.1",
"@eshopman/cli": "2.13.1",
"@eshopman/draft-order": "2.13.1",
"@eshopman/framework": "2.13.1",
"@eshopman/index": "2.13.1",
"@eshopman/eshopman": "2.13.1",
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
"algoliasearch": "5.39.0",
"cronstrue": "^3.12.0",
"dayjs": "^1.11.18",
"fast-xml-parser": "^5.3.6",
"json-rules-engine": "^7.3.1",
"jsonwebtoken": "^9.0.2",
"nodemailer": "^7.0.11"
},
"devDependencies": {
"@biomejs/biome": "2.0.6",
"@eshopman/test-utils": "2.13.1",
"@swc/core": "1.5.7",
"@swc/jest": "0.2.39",
"@types/ajv": "^0.0.5",
"@types/jest": "30.0.0",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^22.0.0",
"@types/nodemailer": "^7.0.4",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.2.25",
"jest": "30.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"ts-node": "^10.9.2",
"typescript": "5.9.3",
"vite": "^5.4.21",
"yalc": "^1.0.0-pre.53"
},
"optionalDependencies": {
"@biomejs/cli-linux-x64-musl": "2.0.6",
"@rollup/rollup-darwin-arm64": "4.43.0",
"@rollup/rollup-darwin-x64": "4.43.0",
"@rollup/rollup-linux-arm64-gnu": "4.43.0",
"@rollup/rollup-linux-arm64-musl": "4.43.0",
"@rollup/rollup-linux-x64-musl": "4.43.0"
},
"engines": {
"node": ">=24.1.0"
},
"volta": {
"node": "24.1.0",
"yarn": "4.12.0"
},
"overrides": {
"axios": "1.13.5",
"glob": "11.1.0",
"jws": "4.0.1",
"multer": "2.0.2",
"qs": "6.14.1",
"tar": "7.5.8",
"@isaacs/brace-expansion": "5.0.1",
"fast-xml-parser": "5.3.6",
"minimatch@^10.1.1": "10.2.1"
},
"resolutions": {
"tar": "7.5.8",
"@isaacs/brace-expansion": "5.0.1",
"fast-xml-parser": "5.3.6",
"axios": "1.13.5",
"minimatch@^10.1.1": "10.2.1"
},
"packageManager": "yarn@4.12.0"
}This insight into specific API interactions is valuable for ESHOPMAN developers and merchants alike, fostering a deeper understanding of the platform's capabilities and current operational nuances.