PHPackages                             mage-os/module-rma - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. mage-os/module-rma

ActiveMagento2-module

mage-os/module-rma
==================

Return Merchandise Authorization

1.3.1(2mo ago)126—0%2[1 issues](https://github.com/mage-os-lab/module-rma/issues)MITPHPPHP &gt;=8.3

Since Feb 13Pushed 2mo agoCompare

[ Source](https://github.com/mage-os-lab/module-rma)[ Packagist](https://packagist.org/packages/mage-os/module-rma)[ RSS](/packages/mage-os-module-rma/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (1)Versions (8)Used By (0)

MageOS\_RMA
===========

[](#mageos_rma)

Return Merchandise Authorization (RMA) module for Magento / MageOS.

Installation
------------

[](#installation)

### Via Composer

[](#via-composer)

```
composer require mage-os/module-rma
```

### Enable the module

[](#enable-the-module)

```
bin/magento module:enable MageOS_RMA
bin/magento setup:upgrade
bin/magento cache:flush
```

> The `setup:upgrade` command creates the database tables and inserts default data (status, reason, resolution type, item condition) via Data Patches.

Configuration
-------------

[](#configuration)

Module settings are located at **Stores &gt; Configuration &gt; Sales &gt; RMA - Return Management**.

### General

[](#general)

FieldTypeDefaultDescriptionEnable RMAYes/NoYesEnable or disable the RMA feature (scope: website)Increment ID PrefixText`RMA-`Prefix for the return increment ID (e.g. `RMA-000001`)Return Period (Days)Numeric`30`Number of days after order placement within which a return can be requested### Policy

[](#policy)

FieldTypeDefaultDescriptionAuto-Approve ReturnsYes/NoNoWhen enabled, new return requests are automatically approvedAllowed Order StatusesMultiselect`complete`Only orders with these statuses can have a return request### Email Notifications

[](#email-notifications)

FieldTypeDefaultDescriptionEmail SenderSelect`General Contact`Sender identity for RMA emailsNew RMA Email Template (Customer)Select—Email template sent to the customer when a new return is createdStatus Change Email Template (Customer)Select—Email template sent to the customer on return status changeNew RMA Email Template (Admin)Select—Email template sent to the admin when a new return is createdAdmin Notification EmailText (email)—Email address to receive admin notifications about returns### Attachments

[](#attachments)

FieldTypeDefaultDescriptionAllowed File ExtensionsText`jpg,jpeg,png,gif,webp,mp4,mov,pdf,doc,docx,zip`Comma-separated list of allowed file extensionsMaximum File Size (MB)Numeric`10`Maximum allowed file size in megabytes per single fileMaximum Files Per UploadNumeric`5`Maximum number of files allowed per RMA creation or commentAdmin Area
----------

[](#admin-area)

### Menu

[](#menu)

Module entries are located under **Sales &gt; RMA**:

- **RMA Requests** — main grid with all return requests
- **Statuses** — manage the return lifecycle statuses
- **Reasons** — manage return reasons
- **Resolution Types** — manage resolution types (refund, replacement, etc.)
- **Item Conditions** — manage item conditions (opened, sealed, etc.)

### Creating an RMA from admin

[](#creating-an-rma-from-admin)

1. Go to **Sales &gt; RMA &gt; RMA Requests**, click **Add New RMA**
2. Search and select an order in the **Order** field (only shows orders from websites with RMA enabled)
3. Customer fields (name, email) and store are automatically filled from the order
4. Select reason and resolution type
5. In the **Items to Return** section, select the order items to include in the return, specifying quantity and condition for each
6. Save — the system automatically generates an increment ID (e.g. `RMA-000001`) and sends notification emails

### Edit RMA

[](#edit-rma)

In edit mode, the form shows order and item information as read-only. You can modify status, reason, resolution type and admin notes.

Changing the status automatically sends a notification email to the customer.

### Attachments

[](#attachments-1)

The RMA edit page displays a unified **Attachments** section above the comments timeline. This section shows all attachments associated with the RMA, regardless of whether they were uploaded at RMA creation or within a comment.

- Each attachment has a **download** link and a **delete** button
- Deleting an attachment from the unified section also removes it from the corresponding comment in the timeline (and vice versa)
- The section updates dynamically when new comments with attachments arrive via polling

### Comments / Chat

[](#comments--chat)

The RMA edit page includes a **Comments** section that enables communication between admin and customer.

- Admin can write comments visible to the customer or **internal notes** (not visible to the customer) via the "Visible to Customer" checkbox
- Internal notes display an **Internal Note** badge in the timeline
- Admin can attach files to comments via drag &amp; drop or file picker
- Comments update in real time via AJAX polling with progressive backoff (10s → 30s → 60s)
- Polling pauses when the browser tab is not visible and resumes when it becomes active again
- Messages can be sent with **Ctrl+Enter** in addition to the button

Frontend — Customer
-------------------

[](#frontend--customer)

### My Returns

[](#my-returns)

A **My Returns** link appears in the customer account sidebar. The page shows all of the customer's returns sorted by date descending, with pagination.

Table columns:

ColumnDescriptionRMA #Return increment ID (e.g. `RMA-000001`)Order #Associated order increment IDStatusCurrent return status (translated per store view)Created AtCreation dateAction**View** link to the detail pageThe **Request Return** button at the top leads to the creation form.

### RMA Detail

[](#rma-detail)

The page displays return information and the items table:

- **General information**: increment ID, order, status, reason, preferred resolution, creation and update dates
- **Items table**: product name, SKU, requested quantity, item condition
- **Attachments section**: all attachments uploaded across the RMA lifecycle (creation and comments) displayed in a unified list with download links. The section is always present and updates dynamically when new comments with attachments arrive
- All labels (status, reason, resolution, condition) are translated according to the current store view

#### Customer Comments / Chat

[](#customer-comments--chat)

Below the detail section there is a comments area that allows the customer to communicate with support:

- The customer only sees comments marked as visible (admin internal notes are not shown)
- Admin messages display a **Support** badge
- Customers can attach files to comments via drag &amp; drop or file picker
- Attachments are also shown inline within each comment for context
- Same real-time polling mechanism as the admin side (backoff 10s → 30s → 60s, pauses on hidden tab)
- Submit with **Ctrl+Enter** or the **Send** button

### Creating an RMA from the customer area

[](#creating-an-rma-from-the-customer-area)

1. From **My Returns**, click **Request Return**
2. Select an order from the dropdown (only eligible orders are shown — see Eligibility section)
3. On order change, available items are loaded via AJAX
4. For each item: check the checkbox, specify quantity and condition
5. Select reason and preferred resolution
6. Optionally attach files via drag &amp; drop or file picker (allowed extensions and size limits are configurable — see Attachments configuration)
7. Click **Submit Return Request**

If arriving from the **Request Return** button on the order detail page, the order is pre-selected and the dropdown is disabled.

### "Request Return" button on order detail

[](#request-return-button-on-order-detail)

On the customer order detail page (**Sales &gt; My Orders &gt; View Order**), a **Request Return** button appears in the action bar if the order is eligible for a return. Clicking it leads to the creation form with the order pre-selected.

Frontend — Guest
----------------

[](#frontend--guest)

Guests (orders without an account) can request a return from the guest order detail page:

1. Access the guest order detail via **Orders and Returns** (order number + email/ZIP)
2. If the order is eligible, the **Request Return** button appears
3. The form is identical to the logged-in customer form, but without the order dropdown (the order is already determined)
4. After submission, the return is created with `customer_id = null`

> Guests do not have a "My Returns" section — they can only create returns from the order detail page.

Order Eligibility for RMA
-------------------------

[](#order-eligibility-for-rma)

An order is eligible for a return request if **all** of these conditions are met:

1. **RMA enabled** — the module is enabled for the order's website (`isEnabled()`)
2. **Allowed status** — the order status is among those configured in "Allowed Order Statuses"
3. **Return period** — the order date is within the period configured in "Return Period (Days)". If the period is `0`, returns are always allowed (no time limit)
4. **Available items** — the order has at least one item with remaining returnable quantity (qty ordered − qty already requested in other RMAs &gt; 0). Virtual items, downloadable items, and parent items of configurable/bundle products are excluded

The logic is centralized in the `Service\OrderEligibility` service with the following methods:

MethodDescription`isOrderEligible(OrderInterface $order): bool`Checks all 4 conditions`getEligibleItems(OrderInterface $order): array`Returns items with available quantity`getCustomerEligibleOrders(int $customerId, int $storeId): Collection`Customer orders matching conditions 1-3Repositories and Service Contracts
----------------------------------

[](#repositories-and-service-contracts)

Each entity exposes a repository with interfaces in `Api/`:

InterfaceImplementationMethods`RMARepositoryInterface``Model\RMARepository``get`, `getByIncrementId`, `save`, `delete`, `deleteById`, `getList``StatusRepositoryInterface``Model\StatusRepository``get`, `save`, `delete`, `deleteById`, `getList``ReasonRepositoryInterface``Model\ReasonRepository``get`, `save`, `delete`, `deleteById`, `getList``ResolutionTypeRepositoryInterface``Model\ResolutionTypeRepository``get`, `save`, `delete`, `deleteById`, `getList``ItemConditionRepositoryInterface``Model\ItemConditionRepository``get`, `save`, `delete`, `deleteById`, `getList``ItemRepositoryInterface``Model\ItemRepository``get`, `save`, `delete`, `deleteById`, `getList``CommentRepositoryInterface``Model\CommentRepository``get`, `save`, `delete`, `deleteById`, `getList`All `getList` methods support `SearchCriteriaInterface` for filtering, sorting and pagination.

Business Events
---------------

[](#business-events)

The module dispatches custom events in `RMARepository::save()` to allow other modules to react to return lifecycle changes.

### How dispatching works

[](#how-dispatching-works)

1. **Creation**: when a new RMA is saved, `rma_created_after` fires
2. **Status change**: when the status changes, **two** events fire in sequence:
    - `rma_status_change_after` (generic, fires on any transition)
    - A specific semantic event based on the new status (e.g. `rma_approved_after`)

### Events table

[](#events-table)

EventWhen it firesAvailable data`rma_created_after`New RMA created`rma``rma_status_change_after`Any status change`rma`, `old_status_id`, `new_status_id``rma_approved_after`Status → Approved`rma`, `old_status_id`, `new_status_id``rma_rejected_after`Status → Rejected`rma`, `old_status_id`, `new_status_id``rma_shipped_by_customer_after`Status → Shipped by Customer`rma`, `old_status_id`, `new_status_id``rma_received_after`Status → Received by Admin`rma`, `old_status_id`, `new_status_id``rma_canceled_after`Status → Canceled by Customer`rma`, `old_status_id`, `new_status_id``rma_resolved_after`Status → Resolved`rma`, `old_status_id`, `new_status_id`### Example: Observer to book a carrier when a return is approved

[](#example-observer-to-book-a-carrier-when-a-return-is-approved)

**`etc/events.xml`** in your custom module:

```

```

**`Observer/BookCarrierPickup.php`**:

```
