Overview
This document describes the open API interface of the OMS (Order Management System).
All endpoints follow RESTful conventions and use JSON for data transmission.
APIs are divided into public endpoints (no login required) and
private endpoints (Bearer Token required).
Base Information
| Item |
Description |
| API Base Path | /api |
| Data Format | application/json; charset=utf-8 |
| Character Encoding | UTF-8 |
| Timezone | Asia/Shanghai |
| Time Format | YYYY-MM-DD HH:mm:ss |
| CORS | Enabled (Access-Control-Allow-Origin: *) |
Authentication
Bearer Token Authentication
The OMS API uses Bearer Token authentication. After a successful login or registration,
you receive a token. All private endpoints require this token in the request header:
Authorization: Bearer {token}
Note: If the Token is missing, invalid, or expired, a 401 error is returned.
The default Token validity period is 7200 seconds (2 hours).
Error Codes
| Code | Description |
200 | Success |
400 | Bad request (missing or malformed parameters) |
401 | Unauthorized (not logged in, invalid or expired Token) |
403 | Forbidden (no permission to access) |
404 | Not Found (resource does not exist) |
500 | Internal Server Error |
User Authorization
Endpoints for user login, registration, Token management, and profile maintenance.
User Login
Login with username/email and password. Returns an access Token on success.
After 5 consecutive failures, the account is locked for 15 minutes.
Request Parameters (Body)
| Parameter | Type | Required | Description |
username* | string | Yes | Username or email address |
password* | string | Yes | Password |
Response Example
{
"code": 200,
"msg": "Login successful",
"data": {
"token": "a1b2c3d4e5f6...",
"expires_in": 7200,
"user": {
"id": 17,
"username": "john",
"email": "john@example.com",
"real_name": "John Doe",
"phone": "13800138000",
"avatar": "/storage/avatar/xx.jpg"
}
}
}
User Registration
After successful registration, a login Token is automatically returned.
Username, email, and phone must be unique within the same merchant account.
Request Parameters (Body)
| Parameter | Type | Required | Description |
username* | string | Yes | Username |
password* | string | Yes | Password (minimum 6 characters) |
email | string | No | Email (unique within merchant) |
phone | string | No | Phone number (unique within merchant) |
real_name | string | No | Real name |
Response: Same structure as /api/user/login.
Validate Token
Validates the locally stored Token and retrieves the latest user information.
Requires a Bearer Token in the Authorization header.
Request Headers
| Parameter | Type | Description |
Authorization | string | Bearer {token} |
Response data Fields
| Field | Type | Description |
token | string | Current Token |
user.id | int | User ID |
user.username | string | Username |
user.email | string | Email |
user.real_name | string | Real name |
user.phone | string | Phone number |
user.avatar | string | Avatar URL |
user.customer_id | string | Customer ID |
user.super_id | int | Merchant ID |
Get User Information
Response Fields
| Field | Type | Description |
id | int | User ID |
username | string | Username |
email | string | Email |
real_name | string | Real name |
phone | string | Phone number |
avatar | string | Avatar URL |
department | string | Department |
bio | string | Personal bio |
role_id | string | Role ID (e.g., User) |
customer_id | string | Customer ID |
super_id | int | Merchant ID |
consultant_id | int | Sales consultant ID |
consultant | object | Consultant info {id, username, email, real_name, phone, avatar, bio} |
Update User Information
Request Parameters (Body)
| Parameter | Type | Required | Description |
username | string | No | Username |
email | string | No | Email |
real_name | string | No | Real name |
phone | string | No | Phone number |
avatar | string | No | Avatar URL |
bio | string | No | Personal bio |
old_password | string | No | Old password (required when changing password) |
password | string | No | New password (required when changing password) |
Upload Avatar
Upload an avatar image using multipart/form-data. Automatically updates the user's avatar field.
Request Parameters (multipart/form-data)
| Parameter | Type | Required | Description |
avatar* | file | Yes | Avatar image file |
Response data
{
"avatar": "/storage/avatar/u_17_20260810.jpg"
}
User Logout
Destroys the current Token and logs out the user.
Shops
Manage e-commerce platform shops bound to the user. Supports Shopify, Amazon, eBay, Global, and more.
Data is isolated by customer_id — users can only see their own shops.
Shop List
Request Parameters (Query)
| Parameter | Type | Required | Default | Description |
page | int | No | 1 | Page number |
limit | int | No | 10 | Items per page (10/20/50) |
shop_name | string | No | - | Fuzzy search by shop name |
platform_type | string | No | all | Platform: SHOPIFY/AMAZON/EBAY/GLOBAL/all |
status | string | No | all | Status: active/inactive/all |
Response list item fields
| Field | Type | Description |
id | int | Shop ID |
shop_name | string | Shop name |
shop_id | string | Platform shop domain (e.g., xxx.myshopify.com) |
platform_type | string | Platform type: SHOPIFY/AMAZON/EBAY/GLOBAL |
platform_text | string | Platform display text |
status | string | Status: active/inactive |
status_text | string | Status display text |
shop_url | string | Shop URL |
country | string | Country |
currency | string | Currency |
created_at | string | Creation time |
Shop Detail
Request Parameters (Query)
| Parameter | Type | Required | Description |
id* | int | Yes | Shop ID |
Response: Same as list item fields, plus api_key, access_token (encrypted),
timezone, contact_email, contact_phone, remark, etc.
Shop Status Options
[
{ "value": "all", "label": "All" },
{ "value": "active", "label": "Active" },
{ "value": "inactive", "label": "Inactive" }
]
Products
Product catalog query, detail, and inventory endpoints. Products are filtered by published status
(product_status=1) by default. Prices are automatically converted to USD for display.
Product List
Request Parameters (Query)
| Parameter | Type | Required | Default | Description |
page | int | No | 1 | Page number |
limit | int | No | 12 | Items per page (12/24/48) |
product_name | string | No | - | Fuzzy search by product name |
category_name | string | No | - | Fuzzy search by category name |
min_price | float | No | - | Minimum price (original, not USD) |
max_price | float | No | - | Maximum price |
product_status | string | No | 1 | 0=unpublished, 1=published (default returns only published) |
Response list item fields
| Field | Type | Description |
product_id | string | Product ID/SKU |
product_name | string | Product name |
category_name | string | Category name |
image | string | Main image URL (normalized, local image preferred) |
price_display | string | Price display (USD, e.g., $19.99 or $10.00-29.99) |
price_range | string | Original price range |
min_price | float | Original minimum price |
max_price | float | Original maximum price |
stock_quantity | int | Stock quantity |
product_status | int | 0=unpublished, 1=published |
Product Detail
Request Parameters (Query)
| Parameter | Type | Required | Description |
product_id* | string | Yes | Product ID/SKU |
Response: In addition to list item fields, includes product_name_en,
product_description, main_image_url, main_image_url_local,
sku_count, weight, length, width, height,
source_url, supplier_name, tags, images array, etc.
Inventory Query
Single product inventory query for external systems like WooCommerce plugins.
At least one of product_id or sku must be provided.
Request Parameters (Query)
| Parameter | Type | Required | Description |
product_id | string | One of two | Product ID (exact match) |
sku | string | One of two | SKU number (fuzzy match) |
shop_id | string | No | Shop ID filter |
Response Fields
| Field | Type | Description |
product_id | string | Product ID |
product_name | string | Product name |
sku | string | SKU number (same as product_id) |
stock_quantity | int | Total stock |
available_quantity | int | Available stock (total - reserved, min 0) |
min_price | float | Original minimum price |
max_price | float | Original maximum price |
currency | string | Currency (fixed USD) |
last_updated | string | Last update time (prefers last_sync_time) |
Batch Inventory Query
Request Parameters (Body, JSON)
| Parameter | Type | Required | Description |
product_ids | array | One of two | Product ID array, e.g., ["SKU001","SKU002"] |
skus | array | One of two | SKU array |
shop_id | string | No | Shop ID filter |
Response Example
{
"code": 200,
"data": {
"list": [
{
"product_id": "SKU001",
"product_name": "Product A",
"sku": "SKU001",
"stock_quantity": 100,
"available_quantity": 95,
"min_price": 10.5,
"max_price": 25.0,
"currency": "USD",
"last_updated": "2026-08-10 15:30:00"
}
],
"total": 2
}
}
Orders
Order list, detail, and status enum endpoints. Data is isolated by customer_id —
users can only see their own orders.
Order List
Request Parameters (Query)
| Parameter | Type | Required | Default | Description |
page | int | No | 1 | Page number |
limit | int | No | 10 | Items per page (10/20/50) |
order_no | string | No | - | Fuzzy search by order number |
status | string | No | all | Order status (see status options) |
start_time | string | No | - | Order start date (YYYY-MM-DD) |
end_time | string | No | - | Order end date (YYYY-MM-DD) |
Response list item fields
| Field | Type | Description |
id | int | Internal order ID |
order_no | string | Order number |
order_status | string | Order status enum string |
status_text | string | Status display text |
total_amount | float | Total order amount (raw value) |
total_amount_formatted | string | Formatted amount (e.g., $199.00) |
currency | string | Currency |
shipping_name | string | Recipient name |
shipping_country | string | Shipping country |
tracking_number | string | Tracking number |
created_at | string | Creation time |
Order Detail
Request Parameters (Query)
| Parameter | Type | Required | Description |
id* | int | Yes | Internal order ID |
Additional Response Fields
| Field | Type | Description |
items | array | Order items: {order_id, order_no, product_id, product_name, sku, image, price, quantity, subtotal, created_at} |
logistics | object | Latest logistics record (last entry in order_logistics table) |
Order Status Options
[
{ "value": "all", "label": "All" },
{ "value": "pending", "label": "Pending" },
{ "value": "processing", "label": "Processing" },
{ "value": "shipped", "label": "Shipped" },
{ "value": "completed", "label": "Completed" },
{ "value": "cancelled", "label": "Cancelled" },
{ "value": "refunded", "label": "Refunded" }
]
Tickets
Customer ticket system supporting ticket creation, viewing, and replies.
Data is isolated by customer_id.
Ticket List
Request Parameters (Query)
| Parameter | Type | Required | Default | Description |
page | int | No | 1 | Page number |
limit | int | No | 10 | Items per page (10/20/50) |
status | string | No | all | Ticket status (see status options) |
type | string | No | all | Ticket type (see type options) |
start_time | string | No | - | Start date (YYYY-MM-DD) |
end_time | string | No | - | End date (YYYY-MM-DD) |
Additional list item fields
| Field | Type | Description |
status_text | string | Status display text |
type_text | string | Type display text |
Ticket Detail
Request Parameters (Query)
| Parameter | Type | Required | Description |
id* | int | Yes | Ticket ID |
Additional Response Fields
| Field | Type | Description |
replies | array | Reply list (ascending by creation time): {ticket_id, user_id, user_type (customer/admin), content, created_at} |
Create Ticket
Request Parameters (Body, JSON)
| Parameter | Type | Required | Description |
type* | string | Yes | Ticket type: question/complaint/suggestion/bug/other |
title* | string | Yes | Ticket title (trimmed) |
content* | string | Yes | Ticket content (trimmed) |
Response data: { "id": 123 }. New ticket status is automatically set to pending.
Reply to Ticket
Request Parameters (Body, JSON)
| Parameter | Type | Required | Description |
ticket_id* | int | Yes | Ticket ID (must belong to current user) |
content* | string | Yes | Reply content |
After a successful reply, the ticket status is automatically updated to replied.
The replier's user_type is fixed as customer.
Response data: { "id": 456 } (ID of the new reply record).
Ticket Status Options
[
{ "value": "all", "label": "All" },
{ "value": "pending", "label": "Pending" },
{ "value": "processing", "label": "Processing" },
{ "value": "replied", "label": "Replied" },
{ "value": "resolved", "label": "Resolved" },
{ "value": "closed", "label": "Closed" }
]
Ticket Type Options
[
{ "value": "all", "label": "All" },
{ "value": "question", "label": "Question" },
{ "value": "complaint", "label": "Complaint" },
{ "value": "suggestion", "label": "Suggestion" },
{ "value": "bug", "label": "Bug Report" },
{ "value": "other", "label": "Other" }
]
Sourcing
Customers submit sourcing requests, view quotes, and communicate with consultants via messages.
Data is isolated by user_id + super_id.
Submit Sourcing Request
Request Parameters (Body, JSON)
| Parameter | Type | Required | Description |
product_image | string | One of two | Product image URL (product_image or product_url must be non-empty) |
product_url | string | One of two | Product link URL |
product_name | string | No | Product name |
product_no | string | No | Product number |
quote_price | float | No | Reference quote (default 0.00, USD) |
country_id | int | No | Target country ID (default 0) |
accept_similar_products | bool | No | Accept similar products (default false, stored as 1 when true) |
additional_info | string | No | Additional information |
communication_info | string | No | Contact notes |
Response Example
{
"code": 200,
"msg": "Submit successful",
"data": {
"id": 123,
"status": 1,
"status_text": "Pending Quote",
"created_at": "2026-08-10 10:00:00"
}
}
Sourcing List
Request Parameters (Query)
| Parameter | Type | Required | Default | Description |
page | int | No | 1 | Page number |
limit | int | No | 20 | Items per page (10/20/50) |
status | int | No | - | Numeric status filter 1~5 (no filter if empty/non-numeric) |
product_name | string | No | - | Fuzzy match by product name |
product_no | string | No | - | Exact match by product number |
start_time | string | No | - | Creation start time (YYYY-MM-DD or YYYY-MM-DDTHH:mm) |
end_time | string | No | - | Creation end time |
Response list item fields
| Field | Type | Description |
id | int | Sourcing record ID |
product_name | string | Product name |
product_no | string | Product number |
product_image | string | Product image |
status | int | Status number (1-5) |
status_text | string | Status display text |
quote_price | float | Quote price |
accept_similar_products | int | Accept similar products 0/1 |
accept_similar_text | string | Yes/No text |
linked_product | object|null | Matched product {sku, product_name, image, price_range}, null if not matched |
Sourcing Detail
Request Parameters (Query)
| Parameter | Type | Required | Description |
id* | int | Yes | Sourcing record ID |
Additional Response Fields
| Field | Type | Description |
quotes | array | Quote records (descending by create_time) |
communications | array | Communication records (descending by create_time) |
Sourcing History
Returns only completed records: status 4 (quote failed) or 5 (quote successful).
Pagination and search parameters are the same as the list endpoint. Sorted by update_time descending.
Sourcing Statistics
{
"code": 200,
"data": {
"total": 100,
"pending_quote": 20,
"quoting": 15,
"pending_confirmation": 10,
"quotation_failure": 25,
"quote_success": 30
}
}
My Sourcing (Simplified)
Simplified sourcing list endpoint. Uses pagination structure (not last_page).
Request Parameters (Query)
| Parameter | Type | Required | Default | Description |
page | int | No | 1 | Page number |
pageSize | int | No | 20 | Items per page (note: parameter name is pageSize, not limit) |
status | string | No | - | Empty = all; otherwise converted to int for filtering |
Additional list item fields: product_images (JSON array),
currency, update_time.
My Sourcing Detail (with messages)
Request Parameters (Query)
| Parameter | Type | Required | Description |
id* | int | Yes | Sourcing record ID |
Additional Response Fields (vs list)
| Field | Type | Description |
product_sku | string | Matched product SKU |
product_images | array | Product images array (JSON decoded) |
messages | array | Message list (ascending by create_time): {id, sender_type (user/admin), sender_id, content, image_urls, msg_type (text/image), create_time} |
Send Text Message
Request Parameters (Body, JSON)
| Parameter | Type | Required | Description |
sourcing_id* | int | Yes | Sourcing record ID (must belong to current user) |
content* | string | Yes | Message text content |
Sender sender_type is fixed as user, sender_id is the current logged-in user ID,
msg_type is fixed as text.
Response data
{
"id": 789,
"sourcing_id": 123,
"content": "Message text content",
"create_time": "2026-08-10 15:30:00"
}
Upload Sourcing Image
Two upload modes are available:
Mode 1: Upload product image only (multipart/form-data)
| Path | Field | Description | Response |
/api/sourcing/uploadImage | image (file) | Upload image only, no message sent | { image_url: "/storage/sourcing/..." } |
Mode 2: Upload image and auto-send as message (multipart/form-data)
| Path | Field | Description |
/api/sourcing/uploadMessageImage | sourcing_id + image (file) | Uploads image and automatically creates a msg_type=image message record with content [Image] |
Response fields: message_id, image_url, create_time.
Sourcing Status Options
[
{ "value": 1, "label": "Pending Quote" },
{ "value": 2, "label": "Quoting" },
{ "value": 3, "label": "Pending Confirmation" },
{ "value": 4, "label": "Quote Failed" },
{ "value": 5, "label": "Quote Successful" }
]