# How to Implement an Order Returns and Refunds Workflow in the Mall E-Commerce System

> Learn how to implement order returns and refunds workflow in the Mall e-commerce system. Discover the state-driven process using four statuses and OmsOrderReturnApply entities.

- Repository: [macro/mall](https://github.com/macrozheng/mall)
- Tags: how-to-guide
- Published: 2026-02-28

---

**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.

```java
// 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.

```java
// 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:

```java
// 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 via `handleTime` and `handleMan`.
- **Status 2 (Completed):** Admin confirms physical receipt of returned goods, records `receiveTime` and `receiveMan`, 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 `handleNote` without 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)

```bash
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)

```bash
curl -G https://admin.example.com/returnApply/list \
  -d status=0 \
  -d pageNum=1 \
  -d pageSize=10

```

### Confirming the Return (Status 1)

```bash
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)

```bash
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`](https://github.com/macrozheng/mall/blob/main/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`](https://github.com/macrozheng/mall/blob/main/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPortalOrderReturnApplyServiceImpl.java) — Handles DTO mapping and initial persistence with `status = 0`.
- **Request DTO:** [`mall-portal/src/main/java/com/macro/mall/portal/domain/OmsOrderReturnApplyParam.java`](https://github.com/macrozheng/mall/blob/main/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`](https://github.com/macrozheng/mall/blob/main/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`](https://github.com/macrozheng/mall/blob/main/mall-admin/src/main/java/com/macro/mall/service/impl/OmsOrderReturnApplyServiceImpl.java) — Contains the core `updateStatus()` state machine logic.
- **Status Update DTO:** [`mall-admin/src/main/java/com/macro/mall/dto/OmsUpdateStatusParam.java`](https://github.com/macrozheng/mall/blob/main/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`](https://github.com/macrozheng/mall/blob/main/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`](https://github.com/macrozheng/mall/blob/main/mall-mbg/src/main/java/com/macro/mall/mapper/OmsOrderReturnApplyMapper.java) — Database CRUD operations for the `oms_order_return_apply` table.
- **Entity Model:** [`mall-mbg/src/main/java/com/macro/mall/model/OmsOrderReturnApply.java`](https://github.com/macrozheng/mall/blob/main/mall-mbg/src/main/java/com/macro/mall/model/OmsOrderReturnApply.java) — Persistence entity containing `status`, `returnAmount`, `handleTime`, and `receiveTime` fields.

## 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 with `status = 0` through `OmsPortalOrderReturnApplyServiceImpl`.
- **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 `returnAmount` field providing the authorized refund value.
- All workflow data persists to the `oms_order_return_apply` table via MyBatis mappers, maintaining a complete audit trail through `createTime`, `handleTime`, and `receiveTime` fields.

## 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`](https://github.com/macrozheng/mall/blob/main/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.