order-management
v0.0.28
Published
A starter for Medusa plugins.
Maintainers
Readme
Compatibility
This starter is compatible with versions >= 2.4.0 of @medusajs/medusa.
Features
- Order Management: Cancel and reorder functionality for orders
- Guest Order Portal: Complete look-up system for guest users (OTP-based)
- Order Confirmation Emails: Automatically sends email notifications when orders are placed (with "Claim Order" support for registered users)
- Return Orders Admin Panel: Complete return orders management section in the Medusa Admin Panel with list view, filtering, search, detail pages, and status management
- Guest Returns & Invoices: Secure endpoints for guest users to initiate returns and download invoices
- Customer-Initiated Swaps: Complete swap/exchange functionality allowing customers to request item swaps directly from the storefront with full status lifecycle management
Configuration
The plugin can be configured in your medusa-config.js file:
import { defineConfig } from "@medusajs/framework/utils"
module.exports = defineConfig({
// ...
plugins: [
{
resolve: "order-management",
options: {
// Required options
storefrontUrl: process.env.STOREFRONT_URL || "http://localhost:8000",
jwtSecret: process.env.JWT_SECRET || "medusa-secret-guest-access",
// Email template options
email: {
orderConfirmTemplate: "src/templates/emails/order-confirmation.html", // Path to HTML template file
otpTemplate: "src/templates/emails/otp-verification.html", // Path to HTML template file (required)
},
// Optional SMTP configuration (for email delivery)
smtp: {
enabled: process.env.FORCE_SMTP_REDELIVER === "true",
host: process.env.SMTP_HOST,
port: process.env.SMTP_PORT ? Number(process.env.SMTP_PORT) : undefined,
secure: process.env.SMTP_SECURE === "true",
auth: {
user: process.env.SMTP_AUTH_USER,
pass: process.env.SMTP_AUTH_PASS,
},
from: process.env.SMTP_FROM || process.env.SMTP_AUTH_USER,
},
},
},
],
})Configuration Options
Required Options:
storefrontUrl- Your storefront URL (required)jwtSecret- JWT secret for guest order tokens (required)
Email Template Options:
email.orderConfirmTemplate- Path to HTML template file for order confirmation emails (optional)email.otpTemplate- Path to HTML template file for OTP verification emails (required for guest OTP functionality)
Optional SMTP Options:
smtp.enabled- Enable SMTP email delivery (default:false)smtp.host- SMTP server host (required if enabled)smtp.port- SMTP server port (required if enabled)smtp.secure- Use secure connection (default:true)smtp.auth.user- SMTP username (required if enabled)smtp.auth.pass- SMTP password (required if enabled)smtp.from- From email address (optional, defaults tosmtp.auth.user)
Notes:
storefrontUrlandjwtSecretare required. All other options are optional.- Order confirmation emails are only sent if a template path is provided. If no template is configured, emails will not be sent.
- OTP template is mandatory for guest OTP functionality. The guest OTP request API will return an error if
email.otpTemplateis not configured. - OTP templates should include
{{otp}}placeholder for the verification code. - SMTP configuration is optional. If not enabled, emails will use Medusa's default email provider.
Return Orders Admin Panel
The plugin includes a dedicated section in the Medusa Admin Panel for managing customer return orders. This feature provides administrators with comprehensive tools to view, search, filter, and manage all return orders.
Features
- List View: View all return orders in a table format with key information
- Search: Search returns by return ID, order ID, or customer email
- Filtering: Filter returns by status (requested, received, requires_action, completed, canceled)
- Detail Pages: View detailed information for each return order including:
- Return information (ID, status, refund amount, reason, note)
- Related order information (order ID, customer, totals)
- Return items with quantities
- Status history timeline
- Metadata
- Status Management: Update return status with validation and status history tracking
- Pagination: Load more returns with pagination support
Accessing Return Orders
Once the plugin is installed and configured, you can access the Return Orders section from the Admin Panel sidebar. The section appears as "Return Orders" with a return icon.
API Endpoints
The plugin provides the following admin API endpoints for return orders management:
GET /admin/returns- List all return orders with filtering, search, and paginationGET /admin/returns/:id- Get detailed information for a specific return orderPOST /admin/returns/:id/status- Update the status of a return order
Return Statuses
The plugin supports the following return statuses:
requested- Return has been requested by the customerreceived- Return items have been receivedrequires_action- Return requires manual interventioncompleted- Return has been completedcanceled- Return has been canceled
Status updates are tracked in the return's metadata with timestamps and admin user IDs.
Guest Order Portal
The Guest Order Portal allows users who placed orders without an account to view their order status, initiate returns, and download invoices securely via an OTP (One-Time Password) system.
Security Features
- Strict Separation: Guest orders are strictly filtered by unique guest customer IDs. Registered account orders will never be exposed in the guest portal.
- Access Control: The portal uses short-lived JWT tokens issued upon successful OTP verification.
- Account Protection: Emails belonging to registered accounts are blocked from the guest OTP flow to prevent unauthorized access and encourage secure logins.
Store API Endpoints
The plugin provides the following store API endpoints for the Guest Order Portal:
POST /store/otp/request- Request an OTP for an email or phone number.POST /store/otp/verify- Verify the OTP and receive a guest JWT token.GET /store/guest-orders- List summary of orders for the verified guest identifier.GET /store/guest-orders/:id- Get full details for a specific guest order (includes items, shipping status, etc.).POST /store/guest-orders/:id/returns- Initiate a return request for a guest order.GET /store/guest-orders/:id/invoice- Download a PDF invoice for the guest order.
Note: All GET and POST requests to guest order endpoints require the JWT token in the Authorization: Bearer <token> header.
Email Templates
The plugin supports custom HTML templates for order confirmation emails. Templates use variable replacement with {{variable_name}} syntax.
Creating Templates
Create HTML template files for email notifications. Place them in your project, for example:
your-project/
src/
templates/
emails/
order-confirmation.htmlExample Email Template (src/templates/emails/order-confirmation.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background-color: #4CAF50; color: white; padding: 20px; text-align: center; }
.content { padding: 20px; background-color: #ffffff; }
.order-info { background-color: #f5f5f5; padding: 15px; margin: 15px 0; border-radius: 5px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Order Confirmation</h1>
</div>
<div class="content">
<div class="order-info">
<p><strong>Order ID:</strong> {{order_id}}</p>
<p><strong>Status:</strong> {{order_status}}</p>
<p><strong>Total:</strong> {{order_total}}</p>
<p><strong>Email:</strong> {{order_email}}</p>
<p><strong>Date:</strong> {{order_date}}</p>
</div>
<p>Thank you for your order!</p>
</div>
</div>
</body>
</html>Template Variables
The following variables are available in order confirmation email templates:
| Variable | Description | Example |
|----------|-------------|---------|
| {{order_id}} | Order ID | order_123 |
| {{order_status}} | Order status | pending |
| {{order_total}} | Order total amount | 99.99 |
| {{order_email}} | Customer email address | [email protected] |
| {{order_date}} | Order creation date | 2024-01-15T10:30:00Z |
| {{order_items}} | Order items array (JSON stringified) | [{"title":"Product","quantity":1}] |
| {{shipping_address}} | Shipping address object (JSON stringified) | {"first_name":"John",...} |
| {{billing_address}} | Billing address object (JSON stringified) | {"first_name":"John",...} |
| {{is_registered}} | Whether the customer email has a registered account | true |
| {{claim_link}} | Link for registered users to claim their guest order | http://.../claim?order_id=... |
Customer-Initiated Swaps
The plugin includes a complete swap/exchange feature that allows customers to request item swaps directly from the storefront. This extends Medusa v2's native OrderExchange functionality with customer-facing APIs and admin management tools.
Features
- Customer-Initiated Swaps: Customers can request swaps for their orders directly from the storefront
- Complete Status Lifecycle: Full status tracking from
requested→approved→return_started→return_shipped→return_received→new_items_shipped→completed - Admin Management: Complete admin panel for viewing, approving, rejecting, and managing swaps
- Price Difference Calculation: Automatic calculation of price differences between returned and new items
- Status History: Complete audit trail of all status changes
Swap Status Flow
requested → approved → return_started → return_shipped → return_received → new_items_shipped → completed
↘ rejected
↘ cancelled (from any status except completed)Storefront Implementation Guide
For detailed implementation instructions on integrating exchange functionality into your storefront, see the Storefront Exchange Implementation Guide. This guide includes:
- Complete API documentation with request/response examples
- React/TypeScript implementation examples
- Error handling best practices
- Status flow diagrams
- Integration checklist
Storefront API Endpoints
Create Swap Request
POST /store/swaps
Authorization: Bearer <customer_token>
Content-Type: application/json
{
"order_id": "order_123",
"return_items": [
{
"id": "item_123",
"quantity": 1,
"reason": "Wrong size"
}
],
"new_items": [
{
"variant_id": "variant_456",
"quantity": 1
}
],
"reason": "Size exchange",
"note": "Please send size M instead"
}List Customer Swaps
GET /store/swaps
Authorization: Bearer <customer_token>Get Swap Details
GET /store/swaps/{swap_id}
Authorization: Bearer <customer_token>List Swaps for Order
GET /store/orders/{order_id}/swaps
Authorization: Bearer <customer_token>Create Swap for Order
POST /store/orders/{order_id}/swaps
Authorization: Bearer <customer_token>
Content-Type: application/json
{
"return_items": [
{
"id": "item_123",
"quantity": 1
}
],
"new_items": [
{
"variant_id": "variant_456",
"quantity": 1
}
],
"reason": "Size exchange"
}Cancel Swap
POST /store/swaps/{swap_id}/cancel
Authorization: Bearer <customer_token>Admin API Endpoints
List All Swaps
GET /admin/swaps?status=requested&order_id=order_123&limit=50&offset=0Get Swap Details
GET /admin/swaps/{swap_id}Approve Swap
POST /admin/swaps/{swap_id}/approveReject Swap
POST /admin/swaps/{swap_id}/reject
Content-Type: application/json
{
"reason": "Item out of stock"
}Update Swap Status
POST /admin/swaps/{swap_id}/status
Content-Type: application/json
{
"status": "return_started",
"metadata": {
"return_label_id": "label_123"
}
}Admin UI
The plugin includes a complete admin UI for managing swaps:
- Swaps List Page: View all swaps with filtering by status, search by order ID, and pagination
- Swap Detail Page: View complete swap information including:
- Swap details (ID, status, dates, price difference)
- Original order information
- Return items list
- New items list
- Status history timeline
- Action buttons (approve/reject/update status)
Access the Swaps section from the Admin Panel sidebar.
Storefront Helpers
The plugin provides helper methods for easy integration:
import { createSwapRequest, getSwaps, getSwap, cancelSwap } from "order-management/helpers"
// Create a swap request
const swap = await createSwapRequest({
orderId: "order_123",
returnItems: [
{ id: "item_123", quantity: 1, reason: "Wrong size" }
],
newItems: [
{ variant_id: "variant_456", quantity: 1 }
],
reason: "Size exchange",
note: "Please send size M"
}, container)
// Get swaps for an order
const swaps = await getSwaps("order_123", container)
// Get a specific swap
const swapDetails = await getSwap("swap_123", container)
// Cancel a swap
const cancelledSwap = await cancelSwap("swap_123", container)Status Transitions
The swap status flow enforces valid transitions:
- requested →
approved,rejected,cancelled - approved →
return_started,cancelled - return_started →
return_shipped,cancelled - return_shipped →
return_received,cancelled - return_received →
new_items_shipped,cancelled - new_items_shipped →
completed,cancelled - rejected → (terminal state)
- completed → (terminal state)
- cancelled → (terminal state)
Invalid status transitions will be rejected with a descriptive error message.
Getting Started
Visit the Quickstart Guide to set up a server.
Visit the Plugins documentation to learn more about plugins and how to create them.
Visit the Docs to learn more about our system requirements.
What is Medusa
Medusa is a set of commerce modules and tools that allow you to build rich, reliable, and performant commerce applications without reinventing core commerce logic. The modules can be customized and used to build advanced ecommerce stores, marketplaces, or any product that needs foundational commerce primitives. All modules are open-source and freely available on npm.
Learn more about Medusa’s architecture and commerce modules in the Docs.
Community & Contributions
The community and core team are available in GitHub Discussions, where you can ask for support, discuss roadmap, and share ideas.
Join our Discord server to meet other community members.
