How to Implement an Order Returns and Refunds Workflow in the Mall E-Commerce System
The mall e-commerce system manages order returns and refunds through a state-driven workflow with four distinct statuses (0=pending, 1=confirmed, 2=completed, 3=rejected) implemented across the mall-portal and mall-admin modules using OmsOrderReturnApply entities and the updateStatus() method.
The macrozheng/mall project provides a complete, production-ready implementation of an order returns and refunds workflow that cleanly separates customer-facing request creation from backend administrative processing. This Spring Boot-based platform tracks return applications through a strict lifecycle—from initial submission to final refund completion or rejection—using MyBatis persistence and RESTful API endpoints. The implementation spans two primary modules: mall-portal handles customer submissions, while mall-admin provides the operational interface for review and status management.
Customer Submission: Creating a Return Request
Customers initiate the returns and refunds workflow through the portal module by submitting detailed application data via a dedicated REST endpoint.
Portal Controller Endpoint
The entry point for customer requests is OmsPortalOrderReturnApplyController#create, which exposes the POST /returnApply/create endpoint. This controller receives an OmsOrderReturnApplyParam DTO and delegates persistence to the portal service layer.
// mall-portal/src/main/java/com/macro/mall/portal/controller/OmsPortalOrderReturnApplyController.java
@PostMapping("/create")
public CommonResult create(@RequestBody OmsOrderReturnApplyParam returnApply) {
int count = returnApplyService.create(returnApply);
return count > 0 ? CommonResult.success(count) : CommonResult.failed();
}
Service Persistence Logic
The OmsPortalOrderReturnApplyServiceImpl.create() method transforms the input DTO into the persistence model OmsOrderReturnApply, automatically setting the initial status = 0 (pending) and recording the submission timestamp before inserting the record via MyBatis.
// mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPortalOrderReturnApplyServiceImpl.java
OmsOrderReturnApply realApply = new OmsOrderReturnApply();
BeanUtils.copyProperties(returnApply, realApply);
realApply.setCreateTime(new Date());
realApply.setStatus(0);
returnApplyMapper.insert(realApply);
The MyBatis mapper OmsOrderReturnApplyMapper persists this data to the oms_order_return_apply table, creating a workflow instance that awaits administrative review.
Admin Processing: Managing Return Status Transitions
Administrators manage the returns and refunds workflow through the mall-admin module, which provides listing capabilities and state transition endpoints governed by the OmsOrderReturnApplyServiceImpl.updateStatus() method.
Core Status Update Logic
The updateStatus() method in OmsOrderReturnApplyServiceImpl implements the state machine logic, handling three valid transitions from the initial pending state:
// mall-admin/src/main/java/com/macro/mall/service/impl/OmsOrderReturnApplyServiceImpl.java
public int updateStatus(Long id, OmsUpdateStatusParam statusParam) {
Integer status = statusParam.getStatus();
OmsOrderReturnApply returnApply = new OmsOrderReturnApply();
if (status.equals(1)) { // Confirm return
returnApply.setId(id);
returnApply.setStatus(1);
returnApply.setReturnAmount(statusParam.getReturnAmount());
returnApply.setCompanyAddressId(statusParam.getCompanyAddressId());
returnApply.setHandleTime(new Date());
returnApply.setHandleMan(statusParam.getHandleMan());
returnApply.setHandleNote(statusParam.getHandleNote());
} else if (status.equals(2)) { // Complete return
returnApply.setId(id);
returnApply.setStatus(2);
returnApply.setReceiveTime(new Date());
returnApply.setReceiveMan(statusParam.getReceiveMan());
returnApply.setReceiveNote(statusParam.getReceiveNote());
} else if (status.equals(3)) { // Reject return
returnApply.setId(id);
returnApply.setStatus(3);
returnApply.setHandleTime(new Date());
returnApply.setHandleMan(statusParam.getHandleMan());
returnApply.setHandleNote(statusParam.getHandleNote());
} else {
return 0;
}
return returnApplyMapper.updateByPrimaryKeySelective(returnApply);
}
Status Definitions and Business Rules
Each status value triggers specific business logic and data capture requirements:
- Status 1 (Confirmed): Admin approves the return, specifies the refund amount (
returnAmount), assigns a return warehouse address (companyAddressId), and records handler identity and notes viahandleTimeandhandleMan. - Status 2 (Completed): Admin confirms physical receipt of returned goods, records
receiveTimeandreceiveMan, and triggers downstream financial and inventory systems to process the actual refund and stock release. - Status 3 (Rejected): Admin denies the request, providing rejection rationale in
handleNotewithout recording any financial transaction data.
The admin controller exposes these transitions via POST /returnApply/update/status, consuming the OmsUpdateStatusParam DTO.
Post-Completion Side Effects: Inventory and Refunds
When the returns and refunds workflow reaches status 2 (completed), the system triggers associated side effects for inventory management and payment processing.
The returnAmount field stored during the confirmation phase (status 1) serves as the authorized refund value that external payment gateways should process upon completion. While the core mall repository does not include specific payment provider integrations, the data model supports this through the persisted OmsOrderReturnApply entity.
For inventory management, completing a return (status 2) conceptually reverses the stock lock placed during order creation. The system utilizes portalOrderDao.releaseSkuStockLock()—typically invoked in order cancellation paths—to restore SKU availability when returns are finalized, ensuring accurate inventory accounting across the warehouse management system.
Practical API Examples
The following cURL commands demonstrate the complete order returns and refunds workflow from customer submission through administrative completion.
Creating a Return Request (Customer)
curl -X POST https://api.example.com/returnApply/create \
-H "Content-Type: application/json" \
-d '{
"orderId": 1024,
"productId": 215,
"orderSn": "202310150001",
"memberUsername": "john.doe",
"returnName": "John Doe",
"returnPhone": "13800138000",
"productPic": "http://img.example.com/215.jpg",
"productName": "Wireless Mouse",
"productBrand": "Logitech",
"productAttr": "颜色:黑色;尺码:标准",
"productCount": 1,
"productPrice": 99.99,
"productRealPrice": 79.99,
"reason": "商品损坏",
"description": "收到时包装已破损",
"proofPics": "http://img.example.com/claim1.jpg,http://img.example.com/claim2.jpg"
}'
This creates a record with status = 0 and returns {"code":200,"data":1,"message":"操作成功"}.
Listing Pending Returns (Admin)
curl -G https://admin.example.com/returnApply/list \
-d status=0 \
-d pageNum=1 \
-d pageSize=10
Confirming the Return (Status 1)
curl -X POST https://admin.example.com/returnApply/update/status \
-H "Content-Type: application/json" \
-d '{
"id": 5,
"status": 1,
"returnAmount": 79.99,
"companyAddressId": 3,
"handleMan": "admin1",
"handleNote": "确认退货,准备退款"
}'
Completing the Return (Status 2)
curl -X POST https://admin.example.com/returnApply/update/status \
-H "Content-Type: application/json" \
-d '{
"id": 5,
"status": 2,
"receiveMan": "finance1",
"receiveNote": "已退款,释放库存"
}'
Key Source Files and Implementation Details
The returns and refunds workflow is implemented across the following specific source files in the macrozheng/mall repository:
- Portal Controller:
mall-portal/src/main/java/com/macro/mall/portal/controller/OmsPortalOrderReturnApplyController.java— Receives customer return applications via/returnApply/create. - Portal Service:
mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPortalOrderReturnApplyServiceImpl.java— Handles DTO mapping and initial persistence withstatus = 0. - Request DTO:
mall-portal/src/main/java/com/macro/mall/portal/domain/OmsOrderReturnApplyParam.java— Defines customer submission parameters. - Admin Controller:
mall-admin/src/main/java/com/macro/mall/controller/OmsOrderReturnApplyController.java— Exposes listing and status update endpoints. - Admin Service:
mall-admin/src/main/java/com/macro/mall/service/impl/OmsOrderReturnApplyServiceImpl.java— Contains the coreupdateStatus()state machine logic. - Status Update DTO:
mall-admin/src/main/java/com/macro/mall/dto/OmsUpdateStatusParam.java— Carries transition parameters including refund amounts and handler metadata. - View Result:
mall-admin/src/main/java/com/macro/mall/dto/OmsOrderReturnApplyResult.java— Provides detailed return information for administrative queries. - MyBatis Mapper:
mall-mbg/src/main/java/com/macro/mall/mapper/OmsOrderReturnApplyMapper.java— Database CRUD operations for theoms_order_return_applytable. - Entity Model:
mall-mbg/src/main/java/com/macro/mall/model/OmsOrderReturnApply.java— Persistence entity containingstatus,returnAmount,handleTime, andreceiveTimefields.
Summary
- The mall project implements a four-state returns and refunds workflow (0=pending, 1=confirmed, 2=completed, 3=rejected) managed across separate portal and admin modules.
- Customers initiate requests via
OmsPortalOrderReturnApplyController#create, which persists data withstatus = 0throughOmsPortalOrderReturnApplyServiceImpl. - Administrators transition requests through confirmed and completed states using
OmsOrderReturnApplyServiceImpl.updateStatus(), which captures refund amounts, handler information, and receipt timestamps. - Status 2 (completed) serves as the trigger point for downstream financial refunds and inventory release operations, with the
returnAmountfield providing the authorized refund value. - All workflow data persists to the
oms_order_return_applytable via MyBatis mappers, maintaining a complete audit trail throughcreateTime,handleTime, andreceiveTimefields.
Frequently Asked Questions
What are the valid status values in the mall return workflow?
The system defines four integer status values: 0 (待处理/pending) for new customer submissions, 1 (已确认/confirmed) for admin-approved returns awaiting physical receipt, 2 (已完成/completed) for finalized returns triggering refunds and stock release, and 3 (已拒绝/rejected) for denied applications. These values are set via the updateStatus() method in mall-admin/src/main/java/com/macro/mall/service/impl/OmsOrderReturnApplyServiceImpl.java.
How does the system handle inventory when a return is completed?
When an administrator sets status = 2 (completed), the workflow signals that physical goods have been received and verified. At this stage, the system should invoke inventory release mechanisms such as portalOrderDao.releaseSkuStockLock() to restore the returned SKU quantities to available stock, reversing the original order reservation.
Where is the actual payment refund processing implemented?
The mall repository captures the authorized refund amount in the returnAmount field of the OmsOrderReturnApply entity during the confirmation phase (status 1), but it does not include specific payment gateway integrations. The status 2 completion event serves as the integration hook where external financial systems should read this amount and process the actual monetary refund to the customer.
Can customers modify or cancel a return request after submission?
According to the source code analysis, the mall-portal module only provides the create endpoint (/returnApply/create) for initial submission. There is no customer-facing update or delete operation exposed in OmsPortalOrderReturnApplyController. Customers must rely on administrative rejection (status 3) if they need to cancel a request, or contact support to modify application details before an admin confirms the return.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →